diff --git a/src/lumino/api_key.py b/src/lumino/api_key.py index 39cbd4f..fe97796 100644 --- a/src/lumino/api_key.py +++ b/src/lumino/api_key.py @@ -1,12 +1,5 @@ -""" -API key management endpoints for the Lumino SDK. - -This module contains the ApiKeyEndpoint class, which provides methods -for interacting with API key-related endpoints. -""" - import logging -from typing import Any, List +from typing import Any from lumino.models import ( ApiKeyCreate, diff --git a/src/lumino/dataset.py b/src/lumino/dataset.py index 3cced18..33e6f9a 100644 --- a/src/lumino/dataset.py +++ b/src/lumino/dataset.py @@ -1,12 +1,5 @@ -""" -Dataset operation endpoints for the Lumino SDK. - -This module contains the DatasetEndpoint class, which provides methods -for interacting with dataset-related API endpoints. -""" - import logging -from typing import Any, List +from typing import Any import aiohttp @@ -139,28 +132,3 @@ async def delete_dataset(self, dataset_name: str) -> None: """ self.logger.info("Deleting dataset: %s", dataset_name) await self._sdk._request("DELETE", f"/datasets/{dataset_name}") - - async def download_dataset(self, dataset_name: str, output_path: str) -> None: - """ - Download a dataset. - - Args: - dataset_name (str): The name of the dataset to download. - output_path (str): The path where the downloaded dataset will be saved. - - Raises: - LuminoAPIError: If the API request fails. - IOError: If there's an error writing the file. - """ - self.logger.info("Downloading dataset: %s", dataset_name) - response = await self._sdk._request("GET", f"/datasets/{dataset_name}/download", stream=True) - - try: - with open(output_path, 'wb') as f: - async for chunk in response.content.iter_chunked(8192): - f.write(chunk) - except IOError as e: - self.logger.error("Error writing dataset to file: %s", str(e)) - raise - - self.logger.info("Dataset downloaded successfully to: %s", output_path) diff --git a/src/lumino/exceptions.py b/src/lumino/exceptions.py index 56c8716..69d8a8e 100644 --- a/src/lumino/exceptions.py +++ b/src/lumino/exceptions.py @@ -1,28 +1,14 @@ -""" -Custom exception classes for the Lumino SDK. - -This module defines exception classes specific to the Lumino SDK, -allowing for more precise error handling in client applications. -""" - from typing import Any, Optional -class LuminoError(Exception): - """Base exception class for all Lumino SDK errors.""" +class LuminoValueError(Exception): + """ + Exception raised when attempting to send an invalid value to the Lumino API. + """ + pass - def __init__(self, message: str): - """ - Initialize the LuminoError. - Args: - message (str): The error message. - """ - self.message = message - super().__init__(self.message) - - -class LuminoAPIError(LuminoError): +class LuminoAPIError(Exception): """Exception raised for errors returned by the Lumino API.""" def __init__(self, status: int, message: str, details: Optional[Any] = None): @@ -37,34 +23,3 @@ def __init__(self, status: int, message: str, details: Optional[Any] = None): self.status = status self.details = details super().__init__(f"Lumino API Error (Status {status}): {message}") - - -class LuminoConfigurationError(LuminoError): - """Exception raised for configuration errors in the Lumino SDK.""" - - def __init__(self, message: str): - """ - Initialize the LuminoConfigurationError. - - Args: - message (str): The error message describing the configuration issue. - """ - super().__init__(f"Lumino SDK Configuration Error: {message}") - - -class LuminoValidationError(LuminoError): - """Exception raised for validation errors in the Lumino SDK.""" - - def __init__(self, message: str, field: Optional[str] = None): - """ - Initialize the LuminoValidationError. - - Args: - message (str): The error message describing the validation issue. - field (Optional[str]): The name of the field that failed validation, if applicable. - """ - self.field = field - error_message = f"Validation Error: {message}" - if field: - error_message = f"{error_message} (Field: {field})" - super().__init__(error_message) diff --git a/src/lumino/fine_tuning.py b/src/lumino/fine_tuning.py index 2b11ab8..8fcf8ae 100644 --- a/src/lumino/fine_tuning.py +++ b/src/lumino/fine_tuning.py @@ -1,12 +1,5 @@ -""" -Fine-tuning job management endpoints for the Lumino SDK. - -This module contains the FineTuningEndpoint class, which provides methods -for interacting with fine-tuning job-related API endpoints. -""" - import logging -from typing import Any, List, Optional +from typing import Any, Optional from lumino.models import ( FineTuningJobCreate, @@ -109,58 +102,3 @@ async def cancel_fine_tuning_job(self, job_name: str) -> FineTuningJobDetailResp self.logger.info("Cancelling fine-tuning job: %s", job_name) data = await self._sdk._request("POST", f"/fine-tuning/{job_name}/cancel") return FineTuningJobDetailResponse(**data) - - async def delete_fine_tuning_job(self, job_name: str) -> None: - """ - Delete a fine-tuning job. - - Args: - job_name (str): The name of the fine-tuning job to delete. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Deleting fine-tuning job: %s", job_name) - await self._sdk._request("DELETE", f"/fine-tuning/{job_name}") - - async def get_fine_tuning_job_metrics(self, job_name: str) -> dict: - """ - Get metrics for a specific fine-tuning job. - - Args: - job_name (str): The name of the fine-tuning job. - - Returns: - dict: A dictionary containing metrics for the fine-tuning job. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Getting metrics for fine-tuning job: %s", job_name) - data = await self._sdk._request("GET", f"/fine-tuning/{job_name}/metrics") - return data - - async def get_fine_tuning_job_logs(self, job_name: str, start_time: Optional[str] = None, - end_time: Optional[str] = None) -> List[str]: - """ - Get logs for a specific fine-tuning job. - - Args: - job_name (str): The name of the fine-tuning job. - start_time (Optional[str]): The start time for log retrieval (ISO format). - end_time (Optional[str]): The end time for log retrieval (ISO format). - - Returns: - List[str]: A list of log entries for the fine-tuning job. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Getting logs for fine-tuning job: %s", job_name) - params = {} - if start_time: - params["start_time"] = start_time - if end_time: - params["end_time"] = end_time - data = await self._sdk._request("GET", f"/fine-tuning/{job_name}/logs", params=params) - return data["logs"] diff --git a/src/lumino/model.py b/src/lumino/model.py index 31ede3f..31959c8 100644 --- a/src/lumino/model.py +++ b/src/lumino/model.py @@ -1,12 +1,5 @@ -""" -Model information retrieval endpoints for the Lumino SDK. - -This module contains the ModelEndpoint class, which provides methods -for interacting with model-related API endpoints. -""" - import logging -from typing import Any, Optional +from typing import Any from lumino.models import ( BaseModelResponse, @@ -108,50 +101,3 @@ async def get_fine_tuned_model(self, model_name: str) -> FineTunedModelResponse: self.logger.info("Getting fine-tuned model: %s", model_name) data = await self._sdk._request("GET", f"/models/fine-tuned/{model_name}") return FineTunedModelResponse(**data) - - async def delete_fine_tuned_model(self, model_name: str) -> None: - """ - Delete a fine-tuned model. - - Args: - model_name (str): The name of the fine-tuned model to delete. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Deleting fine-tuned model: %s", model_name) - await self._sdk._request("DELETE", f"/models/fine-tuned/{model_name}") - - async def get_model_performance(self, model_name: str) -> dict: - """ - Get performance metrics for a specific model. - - Args: - model_name (str): The name of the model (base or fine-tuned). - - Returns: - dict: A dictionary containing performance metrics for the model. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Getting performance metrics for model: %s", model_name) - data = await self._sdk._request("GET", f"/models/{model_name}/performance") - return data - - async def compare_models(self, model_names: list[str]) -> dict: - """ - Compare performance metrics for multiple models. - - Args: - model_names (list[str]): A list of model names to compare. - - Returns: - dict: A dictionary containing comparative performance metrics for the specified models. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Comparing models: %s", ", ".join(model_names)) - data = await self._sdk._request("POST", "/models/compare", json={"models": model_names}) - return data diff --git a/src/lumino/models.py b/src/lumino/models.py index bdb1ce6..c878dd3 100644 --- a/src/lumino/models.py +++ b/src/lumino/models.py @@ -1,55 +1,82 @@ -import json -from datetime import datetime +from datetime import datetime, timezone, date from enum import Enum -from typing import List, Optional, Dict, Any +from functools import partial +from typing import List, Dict, Any, Annotated +from uuid import UUID -from pydantic import BaseModel as _BaseModel, Field, EmailStr +from pydantic import BaseModel as _BaseModel, Field, EmailStr, PlainSerializer, ConfigDict, field_validator + +from lumino.exceptions import LuminoValueError class UserStatus(str, Enum): """Enumeration of possible user statuses.""" - ACTIVE = "ACTIVE" - INACTIVE = "INACTIVE" + ACTIVE = "ACTIVE" # User account is active and can be used + INACTIVE = "INACTIVE" # User account is deactivated and cannot be used class ApiKeyStatus(str, Enum): """Enumeration of possible API key statuses.""" - ACTIVE = "ACTIVE" - EXPIRED = "EXPIRED" - REVOKED = "REVOKED" + ACTIVE = "ACTIVE" # API key is active and can be used for authentication + EXPIRED = "EXPIRED" # API key has expired and is no longer valid + REVOKED = "REVOKED" # API key has been manually revoked by the user or admin class DatasetStatus(str, Enum): """Enumeration of possible dataset statuses.""" - UPLOADED = "UPLOADED" - VALIDATED = "VALIDATED" - ERROR = "ERROR" - DELETED = "DELETED" + UPLOADED = "UPLOADED" # Dataset has been uploaded but not yet validated + VALIDATED = "VALIDATED" # Dataset has been validated and is ready for use + ERROR = "ERROR" # There was an error processing or validating the dataset + DELETED = "DELETED" # Dataset has been marked as deleted class FineTuningJobStatus(str, Enum): """Enumeration of possible fine-tuning job statuses.""" - NEW = "NEW" - QUEUED = "QUEUED" - RUNNING = "RUNNING" - COMPLETED = "COMPLETED" - FAILED = "FAILED" - STOPPING = "STOPPING" - STOPPED = "STOPPED" + NEW = "NEW" # Job has been created but not yet started + QUEUED = "QUEUED" # Job is queued and waiting to start + RUNNING = "RUNNING" # Job is currently running + STOPPING = "STOPPING" # Job is in the process of being stopped + STOPPED = "STOPPED" # Job has been stopped by the user or system + COMPLETED = "COMPLETED" # Job has completed successfully + FAILED = "FAILED" # Job has failed to complete class FineTuningJobType(str, Enum): """Enumeration of possible fine-tuning job types.""" - FULL = "FULL" - LORA = "LORA" - QLORA = "QLORA" + FULL = "FULL" # Full fine-tuning job + LORA = "LORA" # Low-resource fine-tuning job + QLORA = "QLORA" # Quantized low-resource fine-tuning job class BaseModelStatus(str, Enum): """Enumeration of possible base model statuses.""" - ACTIVE = "ACTIVE" - INACTIVE = "INACTIVE" - DEPRECATED = "DEPRECATED" + ACTIVE = "ACTIVE" # Base model is available for use + INACTIVE = "INACTIVE" # Base model is deactivated and cannot be used + DEPRECATED = "DEPRECATED" # Base model is no longer supported or recommended for use + + +class UsageUnit(str, Enum): + """ + Enum for the unit of the available usage units. + """ + TOKEN = "TOKEN" + + +class ServiceName(str, Enum): + """ + Enum for the name of the available services. + """ + FINE_TUNING_JOB = "FINE_TUNING_JOB" + + +class BillingTransactionType(str, Enum): + """ + Enum for the type of billing transaction. + """ + MANUAL_ADJUSTMENT = "MANUAL_ADJUSTMENT" + NEW_USER_CREDIT = "NEW_USER_CREDIT" + FINE_TUNING_JOB = "FINE_TUNING_JOB" + STRIPE_CHECKOUT = "STRIPE_CHECKOUT" class BaseModel(_BaseModel): @@ -60,6 +87,22 @@ def __str__(self): return self.model_dump_json(indent=2) +NameField = partial(Field, + min_length=1, max_length=255, + pattern="^[a-z0-9-]+$") + +DateTime = Annotated[ + datetime, + PlainSerializer(lambda _datetime: _datetime.strftime("%Y-%m-%dT%H:%M:%SZ"), return_type=str), +] + + +def _expiration_must_be_future(v: datetime) -> datetime: + if v.astimezone(timezone.utc) <= datetime.utcnow().astimezone(timezone.utc): + raise LuminoValueError('Expiration date must be in the future') + return v + + class Pagination(BaseModel): """Model for pagination information.""" total_pages: int @@ -67,79 +110,109 @@ class Pagination(BaseModel): items_per_page: int +class ListResponse(BaseModel): + """Model for list response data.""" + data: List[Any] + pagination: Pagination + + class UserUpdate(BaseModel): - """Model for updating user information.""" - name: Optional[str] = Field(None, min_length=1, max_length=255) - email: Optional[EmailStr] = None + """ + Schema for updating user information. + """ + name: str | None = Field(None, min_length=1, max_length=255, description="The updated name of the user") class UserResponse(BaseModel): - """Model for user response data.""" - id: str - created_at: datetime - updated_at: datetime - status: UserStatus - name: str - email: EmailStr - credits_balance: float + """ + Schema for user response data. + """ + id: UUID = Field(..., description="The unique identifier for the user") + created_at: DateTime = Field(..., description="The timestamp when the user was created") + updated_at: DateTime = Field(..., description="The timestamp when the user was last updated") + status: UserStatus = Field(..., description="The current status of the user") + name: str = Field(..., description="The name of the user") + email: EmailStr = Field(..., description="The email address of the user") + credits_balance: float = Field(..., description="The current credit balance of the user") + model_config = ConfigDict(from_attributes=True) class ApiKeyCreate(BaseModel): - """Model for creating a new API key.""" - name: str = Field(..., min_length=1, max_length=255) - expires_at: datetime + """ + Schema for creating a new API key. + """ + name: str = NameField(..., description="The name of the API key") + expires_at: DateTime = Field(..., description="The expiration date and time of the API key") - class Config: - json_encoders = { - datetime: lambda v: v.isoformat() - } + @field_validator('expires_at') + def expiration_must_be_future(cls, v: datetime) -> datetime: + return _expiration_must_be_future(v) class ApiKeyUpdate(BaseModel): - """Model for updating an API key.""" - name: Optional[str] = Field(None, min_length=1, max_length=255) - expires_at: Optional[datetime] = None + """ + Schema for updating an existing API key. + """ + name: str | None = NameField(None, description="The new name for the API key") + expires_at: datetime | None = Field(None, description="The new expiration date and time for the API key") + + @field_validator('expires_at') + def expiration_must_be_future(cls, v: datetime) -> datetime: + return _expiration_must_be_future(v) class ApiKeyResponse(BaseModel): - """Model for API key response data.""" - id: str - created_at: datetime - last_used_at: Optional[datetime] - expires_at: datetime - status: ApiKeyStatus - name: str - prefix: str + """ + Schema for API key response data. + """ + id: UUID = Field(..., description="The unique identifier of the API key") + created_at: DateTime = Field(..., description="The creation date and time of the API key") + last_used_at: datetime | None = Field(None, description="The last usage date and time of the API key") + expires_at: DateTime = Field(..., description="The expiration date and time of the API key") + status: ApiKeyStatus = Field(..., description="The current status of the API key") + name: str = Field(..., description="The name of the API key") + prefix: str = Field(..., description="The prefix of the API key (first few characters)") + model_config = ConfigDict(from_attributes=True) class ApiKeyWithSecretResponse(ApiKeyResponse): - """Model for API key response data including the secret.""" - secret: str + """ + Schema for API key response data including the secret key. + """ + secret: str = Field(..., description="The full API key secret") + model_config = ConfigDict(from_attributes=True) class DatasetCreate(BaseModel): - """Model for creating a new dataset.""" - name: str = Field(..., min_length=1, max_length=255) - description: Optional[str] = Field(None, max_length=1000) + """ + Schema for creating a new dataset. + """ + name: str = NameField(..., description="The name of the dataset") + description: str | None = Field(None, max_length=1000, description="A description of the dataset") class DatasetUpdate(BaseModel): - """Model for updating a dataset.""" - name: Optional[str] = Field(None, min_length=1, max_length=255) - description: Optional[str] = Field(None, max_length=1000) + """ + Schema for updating an existing dataset. + """ + name: str | None = NameField(None, description="The new name for the dataset") + description: str | None = Field(None, max_length=1000, description="The new description for the dataset") class DatasetResponse(BaseModel): - """Model for dataset response data.""" - id: str - created_at: datetime - updated_at: datetime - status: DatasetStatus - name: str - description: Optional[str] - file_name: str - file_size: int - errors: Optional[Dict[str, Any]] + """ + Schema for dataset response data. + """ + id: UUID = Field(..., description="The unique identifier of the dataset") + created_at: DateTime = Field(..., description="The timestamp when the dataset was created") + updated_at: DateTime = Field(..., description="The timestamp when the dataset was last updated") + status: DatasetStatus = Field(..., description="The current status of the dataset") + name: str = Field(..., description="The name of the dataset") + description: str | None = Field(None, description="The description of the dataset, if any") + file_name: str = Field(..., description="The name of the stored dataset file") + file_size: int = Field(..., description="The size of the dataset file in bytes") + errors: dict | None = Field(None, description="Any errors encountered during dataset processing, if any") + model_config = ConfigDict(from_attributes=True) class FineTuningJobParameters(BaseModel): @@ -148,86 +221,106 @@ class FineTuningJobParameters(BaseModel): shuffle: bool = Field(default=True) num_epochs: int = Field(default=1, gt=0, le=10) lr: float = Field(default=3e-4, gt=0, le=1) - seed: Optional[int] = Field(None, ge=0) + seed: int | None = Field(default=None, ge=0) class FineTuningJobCreate(BaseModel): - """Model for creating a new fine-tuning job.""" - base_model_name: str - dataset_name: str - name: str = Field(..., min_length=1, max_length=255) - type: FineTuningJobType = Field(FineTuningJobType.LORA, description="The type of fine-tuning job") - parameters: FineTuningJobParameters + """ + Schema for creating a new fine-tuning job. + """ + base_model_name: str = Field(..., description="The name of the base model to use for fine-tuning") + dataset_name: str = Field(..., description="The name of the dataset to use for fine-tuning") + name: str = NameField(..., description="The name of the fine-tuning job") + type: FineTuningJobType = Field(..., description="The type of fine-tuning job to run") + parameters: FineTuningJobParameters = Field(..., description="The parameters for the fine-tuning job") class FineTuningJobResponse(BaseModel): - """Model for fine-tuning job response data.""" - id: str - created_at: datetime - updated_at: datetime - base_model_name: str - dataset_name: str - status: FineTuningJobStatus - name: str - type: FineTuningJobType - current_step: Optional[int] - total_steps: Optional[int] - current_epoch: Optional[int] - total_epochs: Optional[int] - num_tokens: Optional[int] + """ + Schema for fine-tuning job response data. + """ + id: UUID = Field(..., description="The unique identifier of the fine-tuning job") + created_at: DateTime = Field(..., description="The creation date and time of the fine-tuning job") + updated_at: DateTime = Field(..., description="The last update date and time of the fine-tuning job") + base_model_name: str = Field(..., description="The name of the base model used for fine-tuning") + dataset_name: str = Field(..., description="The name of the dataset used for fine-tuning") + status: FineTuningJobStatus = Field(..., description="The current status of the fine-tuning job") + name: str = Field(..., description="The name of the fine-tuning job") + type: FineTuningJobType = Field(..., description="The type of fine-tuning job") + current_step: int | None = Field(None, description="The current step of the fine-tuning process") + total_steps: int | None = Field(None, description="The total number of steps in the fine-tuning process") + current_epoch: int | None = Field(None, description="The current epoch of the fine-tuning process") + total_epochs: int | None = Field(None, description="The total number of epochs in the fine-tuning process") + num_tokens: int | None = Field(None, description="The number of tokens processed in the fine-tuning job") + model_config = ConfigDict(from_attributes=True) class FineTuningJobDetailResponse(FineTuningJobResponse): - """Model for detailed fine-tuning job response data.""" - parameters: Dict[str, Any] - metrics: Optional[Dict[str, Any]] + """ + Schema for detailed fine-tuning job response data, including parameters and metrics. + """ + parameters: Dict[str, Any] = Field(..., description="The parameters used for the fine-tuning job") + metrics: Dict[str, Any] | None = Field(None, description="The metrics collected during the fine-tuning process") + timestamps: Dict[str, Any] | None = Field(None, description="The timestamps recorded during the fine-tuning process") + model_config = ConfigDict(from_attributes=True) class BaseModelResponse(BaseModel): - """Model for base model response data.""" - id: str - description: Optional[str] - hf_url: str - status: BaseModelStatus - name: str - meta: Optional[Dict[str, Any]] + """ + Schema for base model response data. + """ + id: UUID = Field(..., description="The unique identifier of the base model") + description: str | None = Field(None, description="A description of the base model") + hf_url: str = Field(..., description="The Hugging Face URL for the model") + status: BaseModelStatus = Field(..., description="The current status of the base model") + name: str = Field(..., description="The name of the base model") + meta: Dict[str, Any] | None = Field(None, description="Additional metadata about the base model") + model_config = ConfigDict(from_attributes=True) class FineTunedModelResponse(BaseModel): - """Model for fine-tuned model response data.""" - id: str - created_at: datetime - fine_tuning_job_name: str - name: str - artifacts: Optional[Dict[str, Any]] + """ + Schema for fine-tuned model response data. + """ + id: UUID = Field(..., description="The unique identifier of the fine-tuned model") + created_at: DateTime = Field(..., description="The timestamp when the fine-tuned model was created") + fine_tuning_job_name: str = Field(..., description="The name of the associated fine-tuning job") + name: str = Field(..., description="The name of the fine-tuned model") + artifacts: Dict[str, Any] | None = Field(None, description="Additional artifacts associated with the fine-tuned model") + model_config = ConfigDict(from_attributes=True) class UsageRecordResponse(BaseModel): - """Model for usage record response data.""" - id: str - created_at: datetime - service_name: str - usage_amount: float - usage_unit: str - cost: float - fine_tuning_job_name: str + """ + Schema for usage record response data. + """ + id: UUID = Field(..., description="The unique identifier of the usage record") + created_at: DateTime = Field(..., description="The timestamp when the usage record was created") + service_name: ServiceName = Field(..., description="The name of the service used") + usage_amount: float = Field(..., description="The amount of usage for the service") + usage_unit: UsageUnit = Field(..., description="The unit of usage for the service") + cost: float = Field(..., description="The cost associated with the usage") + fine_tuning_job_name: str = Field(..., description="The name of the associated fine-tuning job") + model_config = ConfigDict(from_attributes=True) class TotalCostResponse(BaseModel): - """Model for total cost response data.""" - start_date: datetime - end_date: datetime - total_cost: float + """ + Schema for total cost response data. + """ + start_date: date = Field(..., description="The start date of the period for which the cost is calculated") + end_date: date = Field(..., description="The end date of the period for which the cost is calculated") + total_cost: float = Field(..., description="The total cost for the specified period") + model_config = ConfigDict(from_attributes=True) class CreditHistoryResponse(BaseModel): - """Model for credit history response data.""" - id: str - created_at: datetime - credits: float - - -class ListResponse(BaseModel): - """Model for list response data.""" - data: List[Any] - pagination: Pagination + """ + Schema for credit history response data. + """ + id: UUID = Field(..., description="The unique identifier for the credit record") + created_at: DateTime = Field(..., description="The timestamp when the credit record was created") + credits: float = Field(..., description="The amount of credits added or deducted") + transaction_id: str = Field(..., description="The transaction ID") + transaction_type: BillingTransactionType = Field(..., description="The type of transaction") + model_config = ConfigDict(from_attributes=True) diff --git a/src/lumino/sdk.py b/src/lumino/sdk.py index 5bfb1ad..8ab746c 100644 --- a/src/lumino/sdk.py +++ b/src/lumino/sdk.py @@ -1,24 +1,19 @@ -""" -Core module for the Lumino SDK. - -This module contains the main LuminoSDK class and common utilities used across the SDK. -""" - import json import logging -from typing import Dict, Any from datetime import datetime +from typing import Dict, Any import aiohttp -from lumino.billing import BillingEndpoint -from lumino.exceptions import LuminoAPIError -from lumino.user import UserEndpoint from lumino.api_key import ApiKeyEndpoint +from lumino.billing import BillingEndpoint from lumino.dataset import DatasetEndpoint +from lumino.exceptions import LuminoAPIError from lumino.fine_tuning import FineTuningEndpoint from lumino.model import ModelEndpoint from lumino.usage import UsageEndpoint +from lumino.user import UserEndpoint + class DateTimeEncoder(json.JSONEncoder): """Custom JSON encoder for datetime objects.""" diff --git a/src/lumino/usage.py b/src/lumino/usage.py index f10fb4a..e172d8a 100644 --- a/src/lumino/usage.py +++ b/src/lumino/usage.py @@ -1,13 +1,6 @@ -""" -Usage tracking endpoints for the Lumino SDK. - -This module contains the UsageEndpoint class, which provides methods -for interacting with usage-related API endpoints. -""" - import logging +from datetime import date from typing import Any, Optional -from datetime import datetime, date from lumino.models import ( UsageRecordResponse, diff --git a/src/lumino/user.py b/src/lumino/user.py index c7c3e19..6ffcb5f 100644 --- a/src/lumino/user.py +++ b/src/lumino/user.py @@ -1,12 +1,5 @@ -""" -User management endpoints for the Lumino SDK. - -This module contains the UserEndpoint class, which provides methods -for interacting with user-related API endpoints. -""" - import logging -from typing import Any, Dict +from typing import Any from lumino.models import UserUpdate, UserResponse @@ -61,46 +54,3 @@ async def update_current_user(self, user_update: UserUpdate) -> UserResponse: json=user_update.dict(exclude_unset=True) ) return UserResponse(**data) - - async def delete_account(self) -> Dict[str, Any]: - """ - Delete the current user's account. - - Returns: - Dict[str, Any]: The API response confirming account deletion. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.warning("Deleting user account") - return await self._sdk._request("DELETE", "/users/me") - - async def get_account_settings(self) -> Dict[str, Any]: - """ - Get the current user's account settings. - - Returns: - Dict[str, Any]: The user's account settings. - - Raises: - LuminoAPIError: If the API request fails. - """ - self.logger.info("Getting user account settings") - return await self._sdk._request("GET", "/users/me/settings") - - async def update_account_settings(self, settings: Dict[str, Any]) -> Dict[str, Any]: - """ - Update the current user's account settings. - - Args: - settings (Dict[str, Any]): The updated account settings. - - Returns: - Dict[str, Any]: The updated account settings. - - Raises: - LuminoAPIError: If the API request fails. - LuminoValidationError: If the provided settings are invalid. - """ - self.logger.info("Updating user account settings") - return await self._sdk._request("PATCH", "/users/me/settings", json=settings) diff --git a/tests/e2e_test.py b/tests/e2e_test.py index 1066203..1063f8f 100644 --- a/tests/e2e_test.py +++ b/tests/e2e_test.py @@ -7,7 +7,7 @@ from lumino.models import ( UserUpdate, ApiKeyCreate, DatasetCreate, FineTuningJobCreate, - ApiKeyUpdate, DatasetUpdate, FineTuningJobParameters + ApiKeyUpdate, DatasetUpdate, FineTuningJobParameters, FineTuningJobType ) from lumino.sdk import LuminoSDK @@ -101,12 +101,11 @@ async def run_e2e_test(): base_model_name=selected_base_model, dataset_name=dataset.name, name=add_suffix("test-fine-tuning-job"), + type=FineTuningJobType.LORA, parameters=FineTuningJobParameters( batch_size=2, shuffle=True, num_epochs=1, - use_lora=True, - use_qlora=False ) )) logger.info(f"Created fine-tuning job: {job.name} (ID: {job.id})")