From 597a565b9552d9f9765faffdb0f5bc537a026be5 Mon Sep 17 00:00:00 2001 From: cdrappier Date: Wed, 10 Jun 2026 18:37:34 +0000 Subject: [PATCH 1/3] feat: add Application resource support - Regenerate controlplane client from cdrappier/application-runtime-pr2-api branch spec - Add Application models (Application, ApplicationSpec, ApplicationList) and API functions (CRUD + list revisions) - Create ApplicationInstance (async) and SyncApplicationInstance (sync) helper classes - Support create, get, list, delete, update, and create_if_not_exists operations - Export from blaxel.core.application and re-export from blaxel.core Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- src/blaxel/core/__init__.py | 10 + src/blaxel/core/application/__init__.py | 13 + src/blaxel/core/application/application.py | 592 ++++++++++++++++++ .../core/client/api/agents/list_agents.py | 165 ++++- .../core/client/api/applications/__init__.py | 0 .../api/applications/create_application.py | 199 ++++++ .../api/applications/delete_application.py | 179 ++++++ .../api/applications/get_application.py | 179 ++++++ .../list_application_revisions.py | 153 +++++ .../api/applications/list_applications.py | 261 ++++++++ .../api/applications/update_application.py | 212 +++++++ .../api/compute/create_sandbox_preview.py | 24 +- .../core/client/api/compute/list_sandboxes.py | 182 +++++- .../core/client/api/drives/list_drives.py | 159 ++++- .../client/api/functions/list_functions.py | 163 ++++- .../api/jobs/list_job_execution_tasks.py | 259 ++++++++ .../client/api/jobs/list_job_executions.py | 99 ++- src/blaxel/core/client/api/jobs/list_jobs.py | 165 ++++- .../core/client/api/models/list_models.py | 165 ++++- .../client/api/policies/get_policy_usages.py | 158 +++++ .../core/client/api/policies/list_policies.py | 165 ++++- .../core/client/api/volumes/list_volumes.py | 165 ++++- .../api/vpcs/get_egress_gateway_usage.py | 134 ++++ .../client/api/workspaces/get_workspace.py | 23 +- src/blaxel/core/client/models/__init__.py | 108 ++++ src/blaxel/core/client/models/agent.py | 1 - src/blaxel/core/client/models/agent_list.py | 102 +++ .../core/client/models/agent_runtime.py | 1 - src/blaxel/core/client/models/agent_spec.py | 1 - src/blaxel/core/client/models/app_revision.py | 137 ++++ .../models/app_revision_configuration.py | 97 +++ src/blaxel/core/client/models/app_url.py | 76 +++ src/blaxel/core/client/models/application.py | 125 ++++ .../core/client/models/application_list.py | 102 +++ .../core/client/models/application_spec.py | 154 +++++ .../core/client/models/configuration.py | 11 +- .../models/create_job_execution_output.py | 1 - .../models/create_job_execution_request.py | 1 - .../core/client/models/custom_domain.py | 1 - .../client/models/custom_domain_metadata.py | 1 - .../core/client/models/custom_domain_spec.py | 36 +- .../client/models/custom_domain_subdomain.py | 97 +++ ...te_volume_template_version_response_200.py | 1 - src/blaxel/core/client/models/drive.py | 1 - src/blaxel/core/client/models/drive_list.py | 102 +++ .../core/client/models/egress_config.py | 1 - .../core/client/models/egress_gateway.py | 1 - .../client/models/egress_gateway_usage.py | 56 ++ src/blaxel/core/client/models/egress_ip.py | 1 - src/blaxel/core/client/models/entrypoint.py | 1 - .../core/client/models/firewall_config.py | 66 ++ src/blaxel/core/client/models/form.py | 1 - src/blaxel/core/client/models/function.py | 1 - .../core/client/models/function_list.py | 102 +++ .../core/client/models/function_runtime.py | 1 - .../core/client/models/function_spec.py | 1 - .../models/get_drive_jwks_response_200.py | 1 - .../get_workspace_features_response_200.py | 1 - src/blaxel/core/client/models/image.py | 1 - .../core/client/models/image_metadata.py | 1 - src/blaxel/core/client/models/image_spec.py | 1 - src/blaxel/core/client/models/integration.py | 1 - .../client/models/integration_connection.py | 1 - .../models/integration_connection_spec.py | 1 - .../client/models/integration_endpoint.py | 1 - .../client/models/integration_endpoints.py | 2 - src/blaxel/core/client/models/job.py | 1 - .../core/client/models/job_execution.py | 1 - .../core/client/models/job_execution_list.py | 102 +++ .../core/client/models/job_execution_spec.py | 1 - .../core/client/models/job_execution_task.py | 1 - .../client/models/job_execution_task_list.py | 102 +++ src/blaxel/core/client/models/job_list.py | 102 +++ src/blaxel/core/client/models/job_runtime.py | 1 - src/blaxel/core/client/models/job_spec.py | 1 - .../core/client/models/list_agents_anchor.py | 17 + .../core/client/models/list_agents_sort.py | 20 + .../client/models/list_applications_anchor.py | 17 + .../client/models/list_applications_sort.py | 20 + .../core/client/models/list_drives_anchor.py | 17 + .../core/client/models/list_drives_sort.py | 20 + .../client/models/list_functions_anchor.py | 17 + .../core/client/models/list_functions_sort.py | 20 + .../models/list_job_execution_tasks_sort.py | 20 + .../client/models/list_job_executions_sort.py | 20 + .../core/client/models/list_jobs_anchor.py | 17 + .../core/client/models/list_jobs_sort.py | 20 + .../core/client/models/list_models_anchor.py | 17 + .../core/client/models/list_models_sort.py | 20 + .../client/models/list_policies_anchor.py | 17 + .../core/client/models/list_policies_sort.py | 20 + .../client/models/list_sandboxes_anchor.py | 17 + .../core/client/models/list_sandboxes_sort.py | 20 + .../core/client/models/list_volumes_anchor.py | 17 + .../core/client/models/list_volumes_sort.py | 20 + src/blaxel/core/client/models/lite_volume.py | 138 ++++ .../client/models/lite_volume_metadata.py | 88 +++ .../core/client/models/lite_volume_spec.py | 70 +++ .../core/client/models/location_response.py | 1 - .../core/client/models/mcp_definition.py | 1 - src/blaxel/core/client/models/metadata.py | 1 - src/blaxel/core/client/models/model.py | 1 - src/blaxel/core/client/models/model_list.py | 102 +++ src/blaxel/core/client/models/model_spec.py | 1 - src/blaxel/core/client/models/o_auth.py | 1 - .../core/client/models/pagination_meta.py | 83 +++ .../models/pending_invitation_accept.py | 1 - .../models/pending_invitation_render.py | 1 - .../pending_invitation_workspace_details.py | 1 - src/blaxel/core/client/models/policy.py | 27 +- src/blaxel/core/client/models/policy_list.py | 102 +++ .../client/models/policy_resource_type.py | 1 + src/blaxel/core/client/models/policy_spec.py | 1 - .../core/client/models/policy_usage_counts.py | 98 +++ .../core/client/models/policy_usages.py | 179 ++++++ .../models/policy_usages_agents_item.py | 45 ++ .../models/policy_usages_functions_item.py | 45 ++ .../client/models/policy_usages_jobs_item.py | 45 ++ .../models/policy_usages_models_item.py | 45 ++ .../models/policy_usages_sandboxes_item.py | 45 ++ src/blaxel/core/client/models/preview.py | 1 - src/blaxel/core/client/models/preview_spec.py | 1 - .../core/client/models/preview_token.py | 1 - src/blaxel/core/client/models/proxy_config.py | 27 + src/blaxel/core/client/models/proxy_target.py | 1 - src/blaxel/core/client/models/public_ips.py | 1 - src/blaxel/core/client/models/region.py | 1 - src/blaxel/core/client/models/sandbox.py | 1 - .../core/client/models/sandbox_definition.py | 1 - .../core/client/models/sandbox_error.py | 1 - .../core/client/models/sandbox_lifecycle.py | 1 - src/blaxel/core/client/models/sandbox_list.py | 103 +++ .../core/client/models/sandbox_network.py | 63 +- .../core/client/models/sandbox_runtime.py | 6 +- src/blaxel/core/client/models/sandbox_spec.py | 14 +- src/blaxel/core/client/models/sso_domain.py | 1 - src/blaxel/core/client/models/template.py | 1 - .../models/test_feature_flag_response_200.py | 1 - src/blaxel/core/client/models/trigger.py | 4 +- .../client/models/trigger_configuration.py | 1 - src/blaxel/core/client/models/volume.py | 1 - src/blaxel/core/client/models/volume_list.py | 102 +++ .../core/client/models/volume_template.py | 1 - src/blaxel/core/client/models/vpc.py | 1 - src/blaxel/core/client/models/workspace.py | 27 +- .../client/models/workspace_hipaa_info.py | 89 +++ .../client/models/workspace_hipaa_unsafe.py | 80 +++ .../models/workspace_resource_counts.py | 49 ++ .../core/client/models/workspace_runtime.py | 31 +- .../models/workspace_sandbox_settings.py | 65 ++ 150 files changed, 7351 insertions(+), 357 deletions(-) create mode 100644 src/blaxel/core/application/__init__.py create mode 100644 src/blaxel/core/application/application.py create mode 100644 src/blaxel/core/client/api/applications/__init__.py create mode 100644 src/blaxel/core/client/api/applications/create_application.py create mode 100644 src/blaxel/core/client/api/applications/delete_application.py create mode 100644 src/blaxel/core/client/api/applications/get_application.py create mode 100644 src/blaxel/core/client/api/applications/list_application_revisions.py create mode 100644 src/blaxel/core/client/api/applications/list_applications.py create mode 100644 src/blaxel/core/client/api/applications/update_application.py create mode 100644 src/blaxel/core/client/api/jobs/list_job_execution_tasks.py create mode 100644 src/blaxel/core/client/api/policies/get_policy_usages.py create mode 100644 src/blaxel/core/client/api/vpcs/get_egress_gateway_usage.py create mode 100644 src/blaxel/core/client/models/agent_list.py create mode 100644 src/blaxel/core/client/models/app_revision.py create mode 100644 src/blaxel/core/client/models/app_revision_configuration.py create mode 100644 src/blaxel/core/client/models/app_url.py create mode 100644 src/blaxel/core/client/models/application.py create mode 100644 src/blaxel/core/client/models/application_list.py create mode 100644 src/blaxel/core/client/models/application_spec.py create mode 100644 src/blaxel/core/client/models/custom_domain_subdomain.py create mode 100644 src/blaxel/core/client/models/drive_list.py create mode 100644 src/blaxel/core/client/models/egress_gateway_usage.py create mode 100644 src/blaxel/core/client/models/firewall_config.py create mode 100644 src/blaxel/core/client/models/function_list.py create mode 100644 src/blaxel/core/client/models/job_execution_list.py create mode 100644 src/blaxel/core/client/models/job_execution_task_list.py create mode 100644 src/blaxel/core/client/models/job_list.py create mode 100644 src/blaxel/core/client/models/list_agents_anchor.py create mode 100644 src/blaxel/core/client/models/list_agents_sort.py create mode 100644 src/blaxel/core/client/models/list_applications_anchor.py create mode 100644 src/blaxel/core/client/models/list_applications_sort.py create mode 100644 src/blaxel/core/client/models/list_drives_anchor.py create mode 100644 src/blaxel/core/client/models/list_drives_sort.py create mode 100644 src/blaxel/core/client/models/list_functions_anchor.py create mode 100644 src/blaxel/core/client/models/list_functions_sort.py create mode 100644 src/blaxel/core/client/models/list_job_execution_tasks_sort.py create mode 100644 src/blaxel/core/client/models/list_job_executions_sort.py create mode 100644 src/blaxel/core/client/models/list_jobs_anchor.py create mode 100644 src/blaxel/core/client/models/list_jobs_sort.py create mode 100644 src/blaxel/core/client/models/list_models_anchor.py create mode 100644 src/blaxel/core/client/models/list_models_sort.py create mode 100644 src/blaxel/core/client/models/list_policies_anchor.py create mode 100644 src/blaxel/core/client/models/list_policies_sort.py create mode 100644 src/blaxel/core/client/models/list_sandboxes_anchor.py create mode 100644 src/blaxel/core/client/models/list_sandboxes_sort.py create mode 100644 src/blaxel/core/client/models/list_volumes_anchor.py create mode 100644 src/blaxel/core/client/models/list_volumes_sort.py create mode 100644 src/blaxel/core/client/models/lite_volume.py create mode 100644 src/blaxel/core/client/models/lite_volume_metadata.py create mode 100644 src/blaxel/core/client/models/lite_volume_spec.py create mode 100644 src/blaxel/core/client/models/model_list.py create mode 100644 src/blaxel/core/client/models/pagination_meta.py create mode 100644 src/blaxel/core/client/models/policy_list.py create mode 100644 src/blaxel/core/client/models/policy_usage_counts.py create mode 100644 src/blaxel/core/client/models/policy_usages.py create mode 100644 src/blaxel/core/client/models/policy_usages_agents_item.py create mode 100644 src/blaxel/core/client/models/policy_usages_functions_item.py create mode 100644 src/blaxel/core/client/models/policy_usages_jobs_item.py create mode 100644 src/blaxel/core/client/models/policy_usages_models_item.py create mode 100644 src/blaxel/core/client/models/policy_usages_sandboxes_item.py create mode 100644 src/blaxel/core/client/models/sandbox_list.py create mode 100644 src/blaxel/core/client/models/volume_list.py create mode 100644 src/blaxel/core/client/models/workspace_hipaa_info.py create mode 100644 src/blaxel/core/client/models/workspace_hipaa_unsafe.py create mode 100644 src/blaxel/core/client/models/workspace_resource_counts.py create mode 100644 src/blaxel/core/client/models/workspace_sandbox_settings.py diff --git a/src/blaxel/core/__init__.py b/src/blaxel/core/__init__.py index 219d1b23..b4be1a95 100644 --- a/src/blaxel/core/__init__.py +++ b/src/blaxel/core/__init__.py @@ -1,6 +1,12 @@ """Blaxel core module.""" from .agents import BlAgent, bl_agent +from .application import ( + ApplicationAPIError, + ApplicationCreateConfiguration, + ApplicationInstance, + SyncApplicationInstance, +) from .authentication import BlaxelAuth, auth, get_credentials from .cache import find_from_cache from .client.client import client @@ -73,6 +79,10 @@ "SyncDriveInstance", "DriveCreateConfiguration", "DriveAPIError", + "ApplicationInstance", + "SyncApplicationInstance", + "ApplicationCreateConfiguration", + "ApplicationAPIError", "verify_webhook_signature", "verify_webhook_from_request", "ImageInstance", diff --git a/src/blaxel/core/application/__init__.py b/src/blaxel/core/application/__init__.py new file mode 100644 index 00000000..4db46208 --- /dev/null +++ b/src/blaxel/core/application/__init__.py @@ -0,0 +1,13 @@ +from .application import ( + ApplicationAPIError, + ApplicationCreateConfiguration, + ApplicationInstance, + SyncApplicationInstance, +) + +__all__ = [ + "ApplicationAPIError", + "ApplicationCreateConfiguration", + "ApplicationInstance", + "SyncApplicationInstance", +] diff --git a/src/blaxel/core/application/application.py b/src/blaxel/core/application/application.py new file mode 100644 index 00000000..d69c8fb9 --- /dev/null +++ b/src/blaxel/core/application/application.py @@ -0,0 +1,592 @@ +import asyncio +import time +import uuid +import warnings +from typing import Callable, Dict, List, Union + +from ..client.api.applications.create_application import asyncio as create_application +from ..client.api.applications.create_application import sync as create_application_sync +from ..client.api.applications.delete_application import asyncio as delete_application +from ..client.api.applications.delete_application import sync as delete_application_sync +from ..client.api.applications.get_application import asyncio as get_application +from ..client.api.applications.get_application import sync as get_application_sync +from ..client.api.applications.list_applications import asyncio as list_applications +from ..client.api.applications.list_applications import sync as list_applications_sync +from ..client.api.applications.update_application import asyncio as update_application +from ..client.api.applications.update_application import sync as update_application_sync +from ..client.client import client +from ..client.errors import UnexpectedStatus +from ..client.models import Application, ApplicationSpec, Metadata +from ..client.models.error import Error +from ..client.types import UNSET +from ..common.settings import settings + + +class ApplicationAPIError(Exception): + """Exception raised when application API returns an error.""" + + def __init__(self, message: str, status_code: int | None = None, code: str | None = None): + super().__init__(message) + self.status_code = status_code + self.code = code + + +class _AsyncDeleteDescriptor: + """Descriptor that provides both class-level and instance-level delete functionality.""" + + def __init__(self, delete_func: Callable): + self._delete_func = delete_func + + def __get__(self, instance, owner): + if instance is None: + return self._delete_func + else: + + async def instance_delete() -> Application: + return await self._delete_func(instance.metadata.name or "") + + return instance_delete + + +class _SyncDeleteDescriptor: + """Descriptor that provides both class-level and instance-level delete functionality (sync).""" + + def __init__(self, delete_func: Callable): + self._delete_func = delete_func + + def __get__(self, instance, owner): + if instance is None: + return self._delete_func + else: + + def instance_delete() -> Application: + return self._delete_func(instance.metadata.name or "") + + return instance_delete + + +class _AsyncUpdateDescriptor: + """Descriptor that provides both class-level and instance-level update functionality.""" + + def __init__(self, update_func: Callable): + self._update_func = update_func + + def __get__(self, instance, owner): + if instance is None: + return self._update_func + else: + + async def instance_update( + updates: Union["ApplicationCreateConfiguration", Application, Dict[str, any]], + ) -> "ApplicationInstance": + return await self._update_func(instance.metadata.name or "", updates) + + return instance_update + + +class _SyncUpdateDescriptor: + """Descriptor that provides both class-level and instance-level update functionality (sync).""" + + def __init__(self, update_func: Callable): + self._update_func = update_func + + def __get__(self, instance, owner): + if instance is None: + return self._update_func + else: + + def instance_update( + updates: Union["ApplicationCreateConfiguration", Application, Dict[str, any]], + ) -> "SyncApplicationInstance": + return self._update_func(instance.metadata.name or "", updates) + + return instance_update + + +class ApplicationCreateConfiguration: + """Simplified configuration for creating applications with default values.""" + + def __init__( + self, + name: str | None = None, + display_name: str | None = None, + labels: Dict[str, str] | None = None, + image: str | None = None, + region: str | None = None, + enabled: bool | None = None, + ): + self.name = name + self.display_name = display_name + self.labels = labels + self.image = image + self.region = region + self.enabled = enabled + + @classmethod + def from_dict(cls, data: Dict[str, any]) -> "ApplicationCreateConfiguration": + return cls( + name=data.get("name"), + display_name=data.get("display_name"), + labels=data.get("labels"), + image=data.get("image"), + region=data.get("region"), + enabled=data.get("enabled"), + ) + + +class ApplicationInstance: + delete: "_AsyncDeleteDescriptor" + + def __init__(self, application: Application): + self.application = application + + @property + def metadata(self): + return self.application.metadata + + @property + def spec(self): + return self.application.spec + + @property + def status(self): + return self.application.status + + @property + def events(self): + return self.application.events + + @property + def name(self): + return self.application.metadata.name if self.application.metadata else None + + @property + def display_name(self): + return self.application.metadata.display_name if self.application.metadata else None + + @classmethod + async def create( + cls, config: Union[ApplicationCreateConfiguration, Application, Dict[str, any]] + ) -> "ApplicationInstance": + default_name = f"app-{uuid.uuid4().hex[:8]}" + + if isinstance(config, Application): + application = config + elif isinstance(config, ApplicationCreateConfiguration): + application = Application( + metadata=Metadata( + name=config.name or default_name, + display_name=config.display_name or config.name or default_name, + labels=config.labels, + ), + spec=ApplicationSpec( + region=config.region or settings.region or UNSET, + enabled=config.enabled if config.enabled is not None else True, + ), + ) + elif isinstance(config, dict): + app_config = ApplicationCreateConfiguration.from_dict(config) + application = Application( + metadata=Metadata( + name=app_config.name or default_name, + display_name=app_config.display_name or app_config.name or default_name, + labels=app_config.labels, + ), + spec=ApplicationSpec( + region=app_config.region or settings.region or UNSET, + enabled=app_config.enabled if app_config.enabled is not None else True, + ), + ) + else: + raise ValueError( + f"Invalid config type: {type(config)}. Expected ApplicationCreateConfiguration, Application, or dict." + ) + + if not application.metadata: + application.metadata = Metadata(name=default_name) + if not application.metadata.name: + application.metadata.name = default_name + if not application.spec: + application.spec = ApplicationSpec() + + if not application.spec.region or application.spec.region is UNSET: + warnings.warn( + "ApplicationInstance.create: 'region' is not set. In a future version, 'region' will be a required parameter. " + "Please specify a region (e.g. 'us-pdx-1', 'eu-lon-1', 'us-was-1') in the application configuration or set the BL_REGION environment variable.", + FutureWarning, + stacklevel=2, + ) + + response = await create_application(client=client, body=application) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + return cls(response) + + @classmethod + async def get(cls, application_name: str) -> "ApplicationInstance": + response = await get_application(application_name=application_name, client=client) + if response is None: + raise ApplicationAPIError( + f"Application '{application_name}' not found", status_code=404, code="NOT_FOUND" + ) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + return cls(response) + + @classmethod + async def list(cls) -> list["ApplicationInstance"]: + response = await list_applications(client=client) + if isinstance(response, Error): + return [] + if response is None: + return [] + data = response.data if not isinstance(response.data, type(UNSET)) else [] + return [cls(app) for app in data or []] + + @classmethod + async def create_if_not_exists( + cls, config: Union[ApplicationCreateConfiguration, Application, Dict[str, any]] + ) -> "ApplicationInstance": + """Create an application if it doesn't exist, otherwise return existing.""" + try: + return await cls.create(config) + except (ApplicationAPIError, UnexpectedStatus) as e: + is_conflict = False + if isinstance(e, ApplicationAPIError): + is_conflict = e.status_code == 409 or e.code in [ + "409", + "APPLICATION_ALREADY_EXISTS", + ] + elif isinstance(e, UnexpectedStatus): + is_conflict = e.status_code == 409 + + if is_conflict: + if isinstance(config, ApplicationCreateConfiguration): + name = config.name + elif isinstance(config, dict): + name = config.get("name") + elif isinstance(config, Application): + name = config.metadata.name if config.metadata else None + else: + name = None + + if not name: + raise ValueError("Application name is required") + + return await cls.get(name) + raise + + +class SyncApplicationInstance: + delete: "_SyncDeleteDescriptor" + + """Synchronous application instance for managing application deployments.""" + + def __init__(self, application: Application): + self.application = application + + @property + def metadata(self): + return self.application.metadata + + @property + def spec(self): + return self.application.spec + + @property + def status(self): + return self.application.status + + @property + def events(self): + return self.application.events + + @property + def name(self): + return self.application.metadata.name if self.application.metadata else None + + @property + def display_name(self): + return self.application.metadata.display_name if self.application.metadata else None + + @classmethod + def create( + cls, config: Union[ApplicationCreateConfiguration, Application, Dict[str, any]] + ) -> "SyncApplicationInstance": + """Create a new application synchronously.""" + default_name = f"app-{uuid.uuid4().hex[:8]}" + + if isinstance(config, Application): + application = config + elif isinstance(config, ApplicationCreateConfiguration): + application = Application( + metadata=Metadata( + name=config.name or default_name, + display_name=config.display_name or config.name or default_name, + labels=config.labels, + ), + spec=ApplicationSpec( + region=config.region or settings.region or UNSET, + enabled=config.enabled if config.enabled is not None else True, + ), + ) + elif isinstance(config, dict): + app_config = ApplicationCreateConfiguration.from_dict(config) + application = Application( + metadata=Metadata( + name=app_config.name or default_name, + display_name=app_config.display_name or app_config.name or default_name, + labels=app_config.labels, + ), + spec=ApplicationSpec( + region=app_config.region or settings.region or UNSET, + enabled=app_config.enabled if app_config.enabled is not None else True, + ), + ) + else: + raise ValueError( + f"Invalid config type: {type(config)}. Expected ApplicationCreateConfiguration, Application, or dict." + ) + + if not application.metadata: + application.metadata = Metadata(name=default_name) + if not application.metadata.name: + application.metadata.name = default_name + if not application.spec: + application.spec = ApplicationSpec() + + if not application.spec.region or application.spec.region is UNSET: + warnings.warn( + "SyncApplicationInstance.create: 'region' is not set. In a future version, 'region' will be a required parameter. " + "Please specify a region (e.g. 'us-pdx-1', 'eu-lon-1', 'us-was-1') in the application configuration or set the BL_REGION environment variable.", + FutureWarning, + stacklevel=2, + ) + + response = create_application_sync(client=client, body=application) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + return cls(response) + + @classmethod + def get(cls, application_name: str) -> "SyncApplicationInstance": + """Get an application by name synchronously.""" + response = get_application_sync(application_name=application_name, client=client) + if response is None: + raise ApplicationAPIError( + f"Application '{application_name}' not found", status_code=404, code="NOT_FOUND" + ) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + return cls(response) + + @classmethod + def list(cls) -> List["SyncApplicationInstance"]: + """List all applications synchronously.""" + response = list_applications_sync(client=client) + if isinstance(response, Error): + return [] + if response is None: + return [] + data = response.data if not isinstance(response.data, type(UNSET)) else [] + return [cls(app) for app in data or []] + + @classmethod + def create_if_not_exists( + cls, config: Union[ApplicationCreateConfiguration, Application, Dict[str, any]] + ) -> "SyncApplicationInstance": + """Create an application if it doesn't exist, otherwise return existing.""" + try: + return cls.create(config) + except (ApplicationAPIError, UnexpectedStatus) as e: + is_conflict = False + if isinstance(e, ApplicationAPIError): + is_conflict = e.status_code == 409 or e.code in [ + "409", + "APPLICATION_ALREADY_EXISTS", + ] + elif isinstance(e, UnexpectedStatus): + is_conflict = e.status_code == 409 + + if is_conflict: + if isinstance(config, ApplicationCreateConfiguration): + name = config.name + elif isinstance(config, dict): + name = config.get("name") + elif isinstance(config, Application): + name = config.metadata.name if config.metadata else None + else: + name = None + + if not name: + raise ValueError("Application name is required") + + return cls.get(name) + raise + + +async def _delete_application_by_name(application_name: str) -> Application: + """Delete an application by name (async).""" + response = await delete_application(application_name=application_name, client=client) + return response + + +def _delete_application_by_name_sync(application_name: str) -> Application: + """Delete an application by name (sync).""" + response = delete_application_sync(application_name=application_name, client=client) + return response + + +async def _update_application_by_name( + application_name: str, + updates: Union[ApplicationCreateConfiguration, Application, Dict[str, any]], +) -> "ApplicationInstance": + """Update an application by name (async).""" + app_instance = await ApplicationInstance.get(application_name) + current_app = app_instance.application + + if isinstance(updates, Application): + new_metadata = updates.metadata + new_spec = updates.spec + elif isinstance(updates, ApplicationCreateConfiguration): + new_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=updates.display_name, + labels=updates.labels, + ) + new_spec = ApplicationSpec( + region=updates.region, + enabled=updates.enabled, + ) + elif isinstance(updates, dict): + config = ApplicationCreateConfiguration.from_dict(updates) + new_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=config.display_name, + labels=config.labels, + ) + new_spec = ApplicationSpec( + region=config.region, + enabled=config.enabled, + ) + else: + raise ValueError( + f"Invalid updates type: {type(updates)}. Expected ApplicationCreateConfiguration, Application, or dict." + ) + + merged_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=new_metadata.display_name + if new_metadata and new_metadata.display_name + else (current_app.metadata.display_name if current_app.metadata else None), + labels=new_metadata.labels + if new_metadata and new_metadata.labels + else (current_app.metadata.labels if current_app.metadata else None), + ) + + merged_spec = ApplicationSpec( + region=new_spec.region + if new_spec and new_spec.region + else (current_app.spec.region if current_app.spec else None), + enabled=new_spec.enabled + if new_spec and new_spec.enabled is not None + else (current_app.spec.enabled if current_app.spec else True), + ) + + body = Application( + metadata=merged_metadata, + spec=merged_spec, + ) + + response = await update_application(application_name=application_name, client=client, body=body) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + await asyncio.sleep(0.5) + return ApplicationInstance(response) + + +def _update_application_by_name_sync( + application_name: str, + updates: Union[ApplicationCreateConfiguration, Application, Dict[str, any]], +) -> "SyncApplicationInstance": + """Update an application by name (sync).""" + app_instance = SyncApplicationInstance.get(application_name) + current_app = app_instance.application + + if isinstance(updates, Application): + new_metadata = updates.metadata + new_spec = updates.spec + elif isinstance(updates, ApplicationCreateConfiguration): + new_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=updates.display_name, + labels=updates.labels, + ) + new_spec = ApplicationSpec( + region=updates.region, + enabled=updates.enabled, + ) + elif isinstance(updates, dict): + config = ApplicationCreateConfiguration.from_dict(updates) + new_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=config.display_name, + labels=config.labels, + ) + new_spec = ApplicationSpec( + region=config.region, + enabled=config.enabled, + ) + else: + raise ValueError( + f"Invalid updates type: {type(updates)}. Expected ApplicationCreateConfiguration, Application, or dict." + ) + + merged_metadata = Metadata( + name=current_app.metadata.name if current_app.metadata else application_name, + display_name=new_metadata.display_name + if new_metadata and new_metadata.display_name + else (current_app.metadata.display_name if current_app.metadata else None), + labels=new_metadata.labels + if new_metadata and new_metadata.labels + else (current_app.metadata.labels if current_app.metadata else None), + ) + + merged_spec = ApplicationSpec( + region=new_spec.region + if new_spec and new_spec.region + else (current_app.spec.region if current_app.spec else None), + enabled=new_spec.enabled + if new_spec and new_spec.enabled is not None + else (current_app.spec.enabled if current_app.spec else True), + ) + + body = Application( + metadata=merged_metadata, + spec=merged_spec, + ) + + response = update_application_sync(application_name=application_name, client=client, body=body) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) + time.sleep(0.5) + return SyncApplicationInstance(response) + + +ApplicationInstance.delete = _AsyncDeleteDescriptor(_delete_application_by_name) +SyncApplicationInstance.delete = _SyncDeleteDescriptor(_delete_application_by_name_sync) + +ApplicationInstance.update = _AsyncUpdateDescriptor(_update_application_by_name) +SyncApplicationInstance.update = _SyncUpdateDescriptor(_update_application_by_name_sync) diff --git a/src/blaxel/core/client/api/agents/list_agents.py b/src/blaxel/core/client/api/agents/list_agents.py index 487c47a2..7cfb1f5f 100644 --- a/src/blaxel/core/client/api/agents/list_agents.py +++ b/src/blaxel/core/client/api/agents/list_agents.py @@ -5,30 +5,55 @@ from ... import errors from ...client import Client -from ...models.agent import Agent +from ...models.agent_list import AgentList from ...models.error import Error -from ...types import Response +from ...models.list_agents_anchor import ListAgentsAnchor +from ...models.list_agents_sort import ListAgentsSort +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListAgentsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListAgentsAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/agents", + "params": params, } return _kwargs -def _parse_response( - *, client: Client, response: httpx.Response -) -> Union[Error, list["Agent"]] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> Union[AgentList, Error] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Agent.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = AgentList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -51,7 +76,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Error, list["Agent"]]]: +) -> Response[Union[AgentList, Error]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -63,21 +88,41 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Error, list["Agent"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListAgentsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListAgentsAnchor] = UNSET, +) -> Response[Union[AgentList, Error]]: """List all agents - Returns all AI agents deployed in the workspace. Each agent includes its deployment status, runtime - configuration, and global inference endpoint URL. + Returns AI agents deployed in the workspace. Each agent includes its deployment status, runtime + configuration, and global inference endpoint URL. Starting with API version 2026-04-28 the response + is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all agents. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListAgentsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListAgentsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Agent']]] + Response[Union[AgentList, Error]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -89,43 +134,82 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Error, list["Agent"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListAgentsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListAgentsAnchor] = UNSET, +) -> Union[AgentList, Error] | None: """List all agents - Returns all AI agents deployed in the workspace. Each agent includes its deployment status, runtime - configuration, and global inference endpoint URL. + Returns AI agents deployed in the workspace. Each agent includes its deployment status, runtime + configuration, and global inference endpoint URL. Starting with API version 2026-04-28 the response + is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all agents. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListAgentsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListAgentsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Agent']] + Union[AgentList, Error] """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Error, list["Agent"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListAgentsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListAgentsAnchor] = UNSET, +) -> Response[Union[AgentList, Error]]: """List all agents - Returns all AI agents deployed in the workspace. Each agent includes its deployment status, runtime - configuration, and global inference endpoint URL. + Returns AI agents deployed in the workspace. Each agent includes its deployment status, runtime + configuration, and global inference endpoint URL. Starting with API version 2026-04-28 the response + is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all agents. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListAgentsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListAgentsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Agent']]] + Response[Union[AgentList, Error]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -135,22 +219,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Error, list["Agent"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListAgentsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListAgentsAnchor] = UNSET, +) -> Union[AgentList, Error] | None: """List all agents - Returns all AI agents deployed in the workspace. Each agent includes its deployment status, runtime - configuration, and global inference endpoint URL. + Returns AI agents deployed in the workspace. Each agent includes its deployment status, runtime + configuration, and global inference endpoint URL. Starting with API version 2026-04-28 the response + is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all agents. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListAgentsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListAgentsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Agent']] + Union[AgentList, Error] """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/applications/__init__.py b/src/blaxel/core/client/api/applications/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/blaxel/core/client/api/applications/create_application.py b/src/blaxel/core/client/api/applications/create_application.py new file mode 100644 index 00000000..765d4441 --- /dev/null +++ b/src/blaxel/core/client/api/applications/create_application.py @@ -0,0 +1,199 @@ +from http import HTTPStatus +from typing import Any, Union + +import httpx + +from ... import errors +from ...client import Client +from ...models.application import Application +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + *, + body: Application, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/applications", + } + + if type(body) is dict: + _body = body + else: + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[Application, Error] | None: + if response.status_code == 200: + response_200 = Application.from_dict(response.json()) + + return response_200 + if response.status_code == 400: + response_400 = Error.from_dict(response.json()) + + return response_400 + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + if response.status_code == 409: + response_409 = Error.from_dict(response.json()) + + return response_409 + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[Application, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Client, + body: Application, +) -> Response[Union[Application, Error]]: + """Create application + + Creates a new application deployment. Applications are long-running workloads that default to public + access and mk3 generation. + + Args: + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Client, + body: Application, +) -> Union[Application, Error] | None: + """Create application + + Creates a new application deployment. Applications are long-running workloads that default to public + access and mk3 generation. + + Args: + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: Client, + body: Application, +) -> Response[Union[Application, Error]]: + """Create application + + Creates a new application deployment. Applications are long-running workloads that default to public + access and mk3 generation. + + Args: + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Client, + body: Application, +) -> Union[Application, Error] | None: + """Create application + + Creates a new application deployment. Applications are long-running workloads that default to public + access and mk3 generation. + + Args: + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/src/blaxel/core/client/api/applications/delete_application.py b/src/blaxel/core/client/api/applications/delete_application.py new file mode 100644 index 00000000..c21164cf --- /dev/null +++ b/src/blaxel/core/client/api/applications/delete_application.py @@ -0,0 +1,179 @@ +from http import HTTPStatus +from typing import Any, Union + +import httpx + +from ... import errors +from ...client import Client +from ...models.application import Application +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + application_name: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "delete", + "url": f"/applications/{application_name}", + } + + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[Application, Error] | None: + if response.status_code == 200: + response_200 = Application.from_dict(response.json()) + + return response_200 + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[Application, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + application_name: str, + *, + client: Client, +) -> Response[Union[Application, Error]]: + """Delete application + + Permanently deletes an application and all its deployment history. The application endpoint will + immediately stop responding. This action cannot be undone. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + application_name: str, + *, + client: Client, +) -> Union[Application, Error] | None: + """Delete application + + Permanently deletes an application and all its deployment history. The application endpoint will + immediately stop responding. This action cannot be undone. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return sync_detailed( + application_name=application_name, + client=client, + ).parsed + + +async def asyncio_detailed( + application_name: str, + *, + client: Client, +) -> Response[Union[Application, Error]]: + """Delete application + + Permanently deletes an application and all its deployment history. The application endpoint will + immediately stop responding. This action cannot be undone. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + application_name: str, + *, + client: Client, +) -> Union[Application, Error] | None: + """Delete application + + Permanently deletes an application and all its deployment history. The application endpoint will + immediately stop responding. This action cannot be undone. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return ( + await asyncio_detailed( + application_name=application_name, + client=client, + ) + ).parsed diff --git a/src/blaxel/core/client/api/applications/get_application.py b/src/blaxel/core/client/api/applications/get_application.py new file mode 100644 index 00000000..ada84c8d --- /dev/null +++ b/src/blaxel/core/client/api/applications/get_application.py @@ -0,0 +1,179 @@ +from http import HTTPStatus +from typing import Any, Union + +import httpx + +from ... import errors +from ...client import Client +from ...models.application import Application +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + application_name: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/applications/{application_name}", + } + + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[Application, Error] | None: + if response.status_code == 200: + response_200 = Application.from_dict(response.json()) + + return response_200 + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[Application, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + application_name: str, + *, + client: Client, +) -> Response[Union[Application, Error]]: + """Get application + + Returns detailed information about an application including its current deployment status, + configuration, events history, and endpoint URL. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + application_name: str, + *, + client: Client, +) -> Union[Application, Error] | None: + """Get application + + Returns detailed information about an application including its current deployment status, + configuration, events history, and endpoint URL. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return sync_detailed( + application_name=application_name, + client=client, + ).parsed + + +async def asyncio_detailed( + application_name: str, + *, + client: Client, +) -> Response[Union[Application, Error]]: + """Get application + + Returns detailed information about an application including its current deployment status, + configuration, events history, and endpoint URL. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + application_name: str, + *, + client: Client, +) -> Union[Application, Error] | None: + """Get application + + Returns detailed information about an application including its current deployment status, + configuration, events history, and endpoint URL. + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return ( + await asyncio_detailed( + application_name=application_name, + client=client, + ) + ).parsed diff --git a/src/blaxel/core/client/api/applications/list_application_revisions.py b/src/blaxel/core/client/api/applications/list_application_revisions.py new file mode 100644 index 00000000..0bc6c201 --- /dev/null +++ b/src/blaxel/core/client/api/applications/list_application_revisions.py @@ -0,0 +1,153 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import Client +from ...models.revision_metadata import RevisionMetadata +from ...types import Response + + +def _get_kwargs( + application_name: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/applications/{application_name}/revisions", + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> list["RevisionMetadata"] | None: + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = RevisionMetadata.from_dict(response_200_item_data) + + response_200.append(response_200_item) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[list["RevisionMetadata"]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + application_name: str, + *, + client: Client, +) -> Response[list["RevisionMetadata"]]: + """List all application revisions + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[list['RevisionMetadata']] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + application_name: str, + *, + client: Client, +) -> list["RevisionMetadata"] | None: + """List all application revisions + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + list['RevisionMetadata'] + """ + + return sync_detailed( + application_name=application_name, + client=client, + ).parsed + + +async def asyncio_detailed( + application_name: str, + *, + client: Client, +) -> Response[list["RevisionMetadata"]]: + """List all application revisions + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[list['RevisionMetadata']] + """ + + kwargs = _get_kwargs( + application_name=application_name, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + application_name: str, + *, + client: Client, +) -> list["RevisionMetadata"] | None: + """List all application revisions + + Args: + application_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + list['RevisionMetadata'] + """ + + return ( + await asyncio_detailed( + application_name=application_name, + client=client, + ) + ).parsed diff --git a/src/blaxel/core/client/api/applications/list_applications.py b/src/blaxel/core/client/api/applications/list_applications.py new file mode 100644 index 00000000..66195847 --- /dev/null +++ b/src/blaxel/core/client/api/applications/list_applications.py @@ -0,0 +1,261 @@ +from http import HTTPStatus +from typing import Any, Union + +import httpx + +from ... import errors +from ...client import Client +from ...models.application_list import ApplicationList +from ...models.error import Error +from ...models.list_applications_anchor import ListApplicationsAnchor +from ...models.list_applications_sort import ListApplicationsSort +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListApplicationsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListApplicationsAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/applications", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[ApplicationList, Error] | None: + if response.status_code == 200: + response_200 = ApplicationList.from_dict(response.json()) + + return response_200 + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[ApplicationList, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListApplicationsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListApplicationsAnchor] = UNSET, +) -> Response[Union[ApplicationList, Error]]: + """List all applications + + Returns applications deployed in the workspace. Each application includes its deployment status, + runtime configuration, and endpoint URL. Starting with API version 2026-04-28 the response is + wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all applications. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListApplicationsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListApplicationsAnchor]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[ApplicationList, Error]] + """ + + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListApplicationsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListApplicationsAnchor] = UNSET, +) -> Union[ApplicationList, Error] | None: + """List all applications + + Returns applications deployed in the workspace. Each application includes its deployment status, + runtime configuration, and endpoint URL. Starting with API version 2026-04-28 the response is + wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all applications. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListApplicationsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListApplicationsAnchor]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[ApplicationList, Error] + """ + + return sync_detailed( + client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ).parsed + + +async def asyncio_detailed( + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListApplicationsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListApplicationsAnchor] = UNSET, +) -> Response[Union[ApplicationList, Error]]: + """List all applications + + Returns applications deployed in the workspace. Each application includes its deployment status, + runtime configuration, and endpoint URL. Starting with API version 2026-04-28 the response is + wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all applications. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListApplicationsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListApplicationsAnchor]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[ApplicationList, Error]] + """ + + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListApplicationsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListApplicationsAnchor] = UNSET, +) -> Union[ApplicationList, Error] | None: + """List all applications + + Returns applications deployed in the workspace. Each application includes its deployment status, + runtime configuration, and endpoint URL. Starting with API version 2026-04-28 the response is + wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query + parameters; older versions keep returning a bare array with all applications. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListApplicationsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListApplicationsAnchor]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[ApplicationList, Error] + """ + + return ( + await asyncio_detailed( + client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) + ).parsed diff --git a/src/blaxel/core/client/api/applications/update_application.py b/src/blaxel/core/client/api/applications/update_application.py new file mode 100644 index 00000000..b81e55f1 --- /dev/null +++ b/src/blaxel/core/client/api/applications/update_application.py @@ -0,0 +1,212 @@ +from http import HTTPStatus +from typing import Any, Union + +import httpx + +from ... import errors +from ...client import Client +from ...models.application import Application +from ...models.error import Error +from ...types import Response + + +def _get_kwargs( + application_name: str, + *, + body: Application, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "put", + "url": f"/applications/{application_name}", + } + + if type(body) is dict: + _body = body + else: + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[Application, Error] | None: + if response.status_code == 200: + response_200 = Application.from_dict(response.json()) + + return response_200 + if response.status_code == 400: + response_400 = Error.from_dict(response.json()) + + return response_400 + if response.status_code == 401: + response_401 = Error.from_dict(response.json()) + + return response_401 + if response.status_code == 403: + response_403 = Error.from_dict(response.json()) + + return response_403 + if response.status_code == 404: + response_404 = Error.from_dict(response.json()) + + return response_404 + if response.status_code == 500: + response_500 = Error.from_dict(response.json()) + + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[Application, Error]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + application_name: str, + *, + client: Client, + body: Application, +) -> Response[Union[Application, Error]]: + """Update application + + Updates an application's configuration and triggers a new deployment. Changes to runtime settings, + environment variables, or scaling parameters will be applied on the next deployment. + + Args: + application_name (str): + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + application_name: str, + *, + client: Client, + body: Application, +) -> Union[Application, Error] | None: + """Update application + + Updates an application's configuration and triggers a new deployment. Changes to runtime settings, + environment variables, or scaling parameters will be applied on the next deployment. + + Args: + application_name (str): + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return sync_detailed( + application_name=application_name, + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + application_name: str, + *, + client: Client, + body: Application, +) -> Response[Union[Application, Error]]: + """Update application + + Updates an application's configuration and triggers a new deployment. Changes to runtime settings, + environment variables, or scaling parameters will be applied on the next deployment. + + Args: + application_name (str): + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Application, Error]] + """ + + kwargs = _get_kwargs( + application_name=application_name, + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + application_name: str, + *, + client: Client, + body: Application, +) -> Union[Application, Error] | None: + """Update application + + Updates an application's configuration and triggers a new deployment. Changes to runtime settings, + environment variables, or scaling parameters will be applied on the next deployment. + + Args: + application_name (str): + body (Application): Long-running application deployment that runs your custom code as a + publicly accessible endpoint. Applications are always public and use mk3 generation. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Application, Error] + """ + + return ( + await asyncio_detailed( + application_name=application_name, + client=client, + body=body, + ) + ).parsed diff --git a/src/blaxel/core/client/api/compute/create_sandbox_preview.py b/src/blaxel/core/client/api/compute/create_sandbox_preview.py index 30a2e45a..8cec5d14 100644 --- a/src/blaxel/core/client/api/compute/create_sandbox_preview.py +++ b/src/blaxel/core/client/api/compute/create_sandbox_preview.py @@ -1,24 +1,32 @@ from http import HTTPStatus -from typing import Any +from typing import Any, Union import httpx from ... import errors from ...client import Client from ...models.preview import Preview -from ...types import Response +from ...types import UNSET, Response, Unset def _get_kwargs( sandbox_name: str, *, body: Preview, + force: Union[Unset, bool] = UNSET, ) -> dict[str, Any]: headers: dict[str, Any] = {} + params: dict[str, Any] = {} + + params["force"] = force + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "post", "url": f"/sandboxes/{sandbox_name}/previews", + "params": params, } if type(body) is dict: @@ -58,6 +66,7 @@ def sync_detailed( *, client: Client, body: Preview, + force: Union[Unset, bool] = UNSET, ) -> Response[Preview]: """Create Sandbox Preview @@ -65,6 +74,7 @@ def sync_detailed( Args: sandbox_name (str): + force (Union[Unset, bool]): body (Preview): Preview of a Resource Raises: @@ -78,6 +88,7 @@ def sync_detailed( kwargs = _get_kwargs( sandbox_name=sandbox_name, body=body, + force=force, ) response = client.get_httpx_client().request( @@ -92,6 +103,7 @@ def sync( *, client: Client, body: Preview, + force: Union[Unset, bool] = UNSET, ) -> Preview | None: """Create Sandbox Preview @@ -99,6 +111,7 @@ def sync( Args: sandbox_name (str): + force (Union[Unset, bool]): body (Preview): Preview of a Resource Raises: @@ -113,6 +126,7 @@ def sync( sandbox_name=sandbox_name, client=client, body=body, + force=force, ).parsed @@ -121,6 +135,7 @@ async def asyncio_detailed( *, client: Client, body: Preview, + force: Union[Unset, bool] = UNSET, ) -> Response[Preview]: """Create Sandbox Preview @@ -128,6 +143,7 @@ async def asyncio_detailed( Args: sandbox_name (str): + force (Union[Unset, bool]): body (Preview): Preview of a Resource Raises: @@ -141,6 +157,7 @@ async def asyncio_detailed( kwargs = _get_kwargs( sandbox_name=sandbox_name, body=body, + force=force, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -153,6 +170,7 @@ async def asyncio( *, client: Client, body: Preview, + force: Union[Unset, bool] = UNSET, ) -> Preview | None: """Create Sandbox Preview @@ -160,6 +178,7 @@ async def asyncio( Args: sandbox_name (str): + force (Union[Unset, bool]): body (Preview): Preview of a Resource Raises: @@ -175,5 +194,6 @@ async def asyncio( sandbox_name=sandbox_name, client=client, body=body, + force=force, ) ).parsed diff --git a/src/blaxel/core/client/api/compute/list_sandboxes.py b/src/blaxel/core/client/api/compute/list_sandboxes.py index 655e6877..cda9e0b8 100644 --- a/src/blaxel/core/client/api/compute/list_sandboxes.py +++ b/src/blaxel/core/client/api/compute/list_sandboxes.py @@ -6,14 +6,49 @@ from ... import errors from ...client import Client from ...models.error import Error -from ...models.sandbox import Sandbox -from ...types import Response +from ...models.list_sandboxes_anchor import ListSandboxesAnchor +from ...models.list_sandboxes_sort import ListSandboxesSort +from ...models.sandbox_list import SandboxList +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + show_terminated: Union[Unset, bool] = False, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListSandboxesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListSandboxesAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["showTerminated"] = show_terminated + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/sandboxes", + "params": params, } return _kwargs @@ -21,14 +56,9 @@ def _get_kwargs() -> dict[str, Any]: def _parse_response( *, client: Client, response: httpx.Response -) -> Union[Error, list["Sandbox"]] | None: +) -> Union[Error, SandboxList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Sandbox.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = SandboxList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -51,7 +81,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Error, list["Sandbox"]]]: +) -> Response[Union[Error, SandboxList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -63,21 +93,45 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Error, list["Sandbox"]]]: + show_terminated: Union[Unset, bool] = False, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListSandboxesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListSandboxesAnchor] = UNSET, +) -> Response[Union[Error, SandboxList]]: """List sandboxes - Returns all sandboxes in the workspace. Each sandbox includes its configuration, status, and - endpoint URL. + Returns sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint + URL. Terminated sandboxes are hidden by default; pass `showTerminated=true` to include them. + Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor + pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array + of all sandboxes. + + Args: + show_terminated (Union[Unset, bool]): Default: False. + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListSandboxesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListSandboxesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Sandbox']]] + Response[Union[Error, SandboxList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + show_terminated=show_terminated, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -89,43 +143,90 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Error, list["Sandbox"]] | None: + show_terminated: Union[Unset, bool] = False, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListSandboxesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListSandboxesAnchor] = UNSET, +) -> Union[Error, SandboxList] | None: """List sandboxes - Returns all sandboxes in the workspace. Each sandbox includes its configuration, status, and - endpoint URL. + Returns sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint + URL. Terminated sandboxes are hidden by default; pass `showTerminated=true` to include them. + Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor + pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array + of all sandboxes. + + Args: + show_terminated (Union[Unset, bool]): Default: False. + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListSandboxesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListSandboxesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Sandbox']] + Union[Error, SandboxList] """ return sync_detailed( client=client, + show_terminated=show_terminated, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Error, list["Sandbox"]]]: + show_terminated: Union[Unset, bool] = False, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListSandboxesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListSandboxesAnchor] = UNSET, +) -> Response[Union[Error, SandboxList]]: """List sandboxes - Returns all sandboxes in the workspace. Each sandbox includes its configuration, status, and - endpoint URL. + Returns sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint + URL. Terminated sandboxes are hidden by default; pass `showTerminated=true` to include them. + Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor + pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array + of all sandboxes. + + Args: + show_terminated (Union[Unset, bool]): Default: False. + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListSandboxesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListSandboxesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Sandbox']]] + Response[Union[Error, SandboxList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + show_terminated=show_terminated, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -135,22 +236,45 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Error, list["Sandbox"]] | None: + show_terminated: Union[Unset, bool] = False, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListSandboxesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListSandboxesAnchor] = UNSET, +) -> Union[Error, SandboxList] | None: """List sandboxes - Returns all sandboxes in the workspace. Each sandbox includes its configuration, status, and - endpoint URL. + Returns sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint + URL. Terminated sandboxes are hidden by default; pass `showTerminated=true` to include them. + Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor + pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array + of all sandboxes. + + Args: + show_terminated (Union[Unset, bool]): Default: False. + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListSandboxesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListSandboxesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Sandbox']] + Union[Error, SandboxList] """ return ( await asyncio_detailed( client=client, + show_terminated=show_terminated, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/drives/list_drives.py b/src/blaxel/core/client/api/drives/list_drives.py index 0848e1b8..c5fac21f 100644 --- a/src/blaxel/core/client/api/drives/list_drives.py +++ b/src/blaxel/core/client/api/drives/list_drives.py @@ -5,29 +5,54 @@ from ... import errors from ...client import Client -from ...models.drive import Drive -from ...types import Response +from ...models.drive_list import DriveList +from ...models.list_drives_anchor import ListDrivesAnchor +from ...models.list_drives_sort import ListDrivesSort +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListDrivesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListDrivesAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/drives", + "params": params, } return _kwargs -def _parse_response( - *, client: Client, response: httpx.Response -) -> Union[Any, list["Drive"]] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> Union[Any, DriveList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Drive.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = DriveList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -39,9 +64,7 @@ def _parse_response( return None -def _build_response( - *, client: Client, response: httpx.Response -) -> Response[Union[Any, list["Drive"]]]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[Union[Any, DriveList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -53,21 +76,41 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Any, list["Drive"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListDrivesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListDrivesAnchor] = UNSET, +) -> Response[Union[Any, DriveList]]: """List drives Returns all drives in the workspace. Drives provide persistent storage that can be attached to - agents, functions, and sandboxes. + agents, functions, and sandboxes. Starting with API version 2026-04-28, the response wraps items in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep returning a bare array with all drives. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListDrivesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListDrivesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, list['Drive']]] + Response[Union[Any, DriveList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -79,43 +122,82 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Any, list["Drive"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListDrivesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListDrivesAnchor] = UNSET, +) -> Union[Any, DriveList] | None: """List drives Returns all drives in the workspace. Drives provide persistent storage that can be attached to - agents, functions, and sandboxes. + agents, functions, and sandboxes. Starting with API version 2026-04-28, the response wraps items in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep returning a bare array with all drives. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListDrivesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListDrivesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, list['Drive']] + Union[Any, DriveList] """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Any, list["Drive"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListDrivesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListDrivesAnchor] = UNSET, +) -> Response[Union[Any, DriveList]]: """List drives Returns all drives in the workspace. Drives provide persistent storage that can be attached to - agents, functions, and sandboxes. + agents, functions, and sandboxes. Starting with API version 2026-04-28, the response wraps items in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep returning a bare array with all drives. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListDrivesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListDrivesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, list['Drive']]] + Response[Union[Any, DriveList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -125,22 +207,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Any, list["Drive"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListDrivesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListDrivesAnchor] = UNSET, +) -> Union[Any, DriveList] | None: """List drives Returns all drives in the workspace. Drives provide persistent storage that can be attached to - agents, functions, and sandboxes. + agents, functions, and sandboxes. Starting with API version 2026-04-28, the response wraps items in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep returning a bare array with all drives. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListDrivesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListDrivesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, list['Drive']] + Union[Any, DriveList] """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/functions/list_functions.py b/src/blaxel/core/client/api/functions/list_functions.py index 264e9f39..3ba0f0bf 100644 --- a/src/blaxel/core/client/api/functions/list_functions.py +++ b/src/blaxel/core/client/api/functions/list_functions.py @@ -6,14 +6,46 @@ from ... import errors from ...client import Client from ...models.error import Error -from ...models.function import Function -from ...types import Response +from ...models.function_list import FunctionList +from ...models.list_functions_anchor import ListFunctionsAnchor +from ...models.list_functions_sort import ListFunctionsSort +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListFunctionsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListFunctionsAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/functions", + "params": params, } return _kwargs @@ -21,14 +53,9 @@ def _get_kwargs() -> dict[str, Any]: def _parse_response( *, client: Client, response: httpx.Response -) -> Union[Error, list["Function"]] | None: +) -> Union[Error, FunctionList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Function.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = FunctionList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -51,7 +78,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Error, list["Function"]]]: +) -> Response[Union[Error, FunctionList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -63,21 +90,41 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Error, list["Function"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListFunctionsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListFunctionsAnchor] = UNSET, +) -> Response[Union[Error, FunctionList]]: """List all MCP servers - Returns all MCP server functions deployed in the workspace. Each function includes its deployment - status, transport protocol (websocket or http-stream), and endpoint URL. + Returns MCP server functions deployed in the workspace. Each function includes its deployment + status, transport protocol (websocket or http-stream), and endpoint URL. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array with all functions. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListFunctionsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListFunctionsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Function']]] + Response[Union[Error, FunctionList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -89,43 +136,82 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Error, list["Function"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListFunctionsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListFunctionsAnchor] = UNSET, +) -> Union[Error, FunctionList] | None: """List all MCP servers - Returns all MCP server functions deployed in the workspace. Each function includes its deployment - status, transport protocol (websocket or http-stream), and endpoint URL. + Returns MCP server functions deployed in the workspace. Each function includes its deployment + status, transport protocol (websocket or http-stream), and endpoint URL. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array with all functions. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListFunctionsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListFunctionsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Function']] + Union[Error, FunctionList] """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Error, list["Function"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListFunctionsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListFunctionsAnchor] = UNSET, +) -> Response[Union[Error, FunctionList]]: """List all MCP servers - Returns all MCP server functions deployed in the workspace. Each function includes its deployment - status, transport protocol (websocket or http-stream), and endpoint URL. + Returns MCP server functions deployed in the workspace. Each function includes its deployment + status, transport protocol (websocket or http-stream), and endpoint URL. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array with all functions. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListFunctionsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListFunctionsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Function']]] + Response[Union[Error, FunctionList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -135,22 +221,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Error, list["Function"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListFunctionsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListFunctionsAnchor] = UNSET, +) -> Union[Error, FunctionList] | None: """List all MCP servers - Returns all MCP server functions deployed in the workspace. Each function includes its deployment - status, transport protocol (websocket or http-stream), and endpoint URL. + Returns MCP server functions deployed in the workspace. Each function includes its deployment + status, transport protocol (websocket or http-stream), and endpoint URL. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array with all functions. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListFunctionsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListFunctionsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Function']] + Union[Error, FunctionList] """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/jobs/list_job_execution_tasks.py b/src/blaxel/core/client/api/jobs/list_job_execution_tasks.py new file mode 100644 index 00000000..22c1ad0f --- /dev/null +++ b/src/blaxel/core/client/api/jobs/list_job_execution_tasks.py @@ -0,0 +1,259 @@ +from http import HTTPStatus +from typing import Any, Union, cast + +import httpx + +from ... import errors +from ...client import Client +from ...models.job_execution_task_list import JobExecutionTaskList +from ...models.list_job_execution_tasks_sort import ListJobExecutionTasksSort +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + job_id: str, + execution_id: str, + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobExecutionTasksSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/jobs/{job_id}/executions/{execution_id}/tasks", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Client, response: httpx.Response +) -> Union[Any, JobExecutionTaskList] | None: + if response.status_code == 200: + response_200 = JobExecutionTaskList.from_dict(response.json()) + + return response_200 + if response.status_code == 400: + response_400 = cast(Any, None) + return response_400 + if response.status_code == 404: + response_404 = cast(Any, None) + return response_404 + if response.status_code == 500: + response_500 = cast(Any, None) + return response_500 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Client, response: httpx.Response +) -> Response[Union[Any, JobExecutionTaskList]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + job_id: str, + execution_id: str, + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobExecutionTasksSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Response[Union[Any, JobExecutionTaskList]]: + """List execution tasks + + Returns one cursor-paginated page of an execution's tasks. Tasks are derived from event history each + request; only the in-memory slicing is paginated, the events scan still fetches the whole event log + behind the scenes. Available starting with API version 2026-04-28. + + Args: + job_id (str): + execution_id (str): + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobExecutionTasksSort]): + q (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, JobExecutionTaskList]] + """ + + kwargs = _get_kwargs( + job_id=job_id, + execution_id=execution_id, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + job_id: str, + execution_id: str, + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobExecutionTasksSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Union[Any, JobExecutionTaskList] | None: + """List execution tasks + + Returns one cursor-paginated page of an execution's tasks. Tasks are derived from event history each + request; only the in-memory slicing is paginated, the events scan still fetches the whole event log + behind the scenes. Available starting with API version 2026-04-28. + + Args: + job_id (str): + execution_id (str): + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobExecutionTasksSort]): + q (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, JobExecutionTaskList] + """ + + return sync_detailed( + job_id=job_id, + execution_id=execution_id, + client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + ).parsed + + +async def asyncio_detailed( + job_id: str, + execution_id: str, + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobExecutionTasksSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Response[Union[Any, JobExecutionTaskList]]: + """List execution tasks + + Returns one cursor-paginated page of an execution's tasks. Tasks are derived from event history each + request; only the in-memory slicing is paginated, the events scan still fetches the whole event log + behind the scenes. Available starting with API version 2026-04-28. + + Args: + job_id (str): + execution_id (str): + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobExecutionTasksSort]): + q (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Union[Any, JobExecutionTaskList]] + """ + + kwargs = _get_kwargs( + job_id=job_id, + execution_id=execution_id, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + job_id: str, + execution_id: str, + *, + client: Client, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobExecutionTasksSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Union[Any, JobExecutionTaskList] | None: + """List execution tasks + + Returns one cursor-paginated page of an execution's tasks. Tasks are derived from event history each + request; only the in-memory slicing is paginated, the events scan still fetches the whole event log + behind the scenes. Available starting with API version 2026-04-28. + + Args: + job_id (str): + execution_id (str): + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobExecutionTasksSort]): + q (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Union[Any, JobExecutionTaskList] + """ + + return ( + await asyncio_detailed( + job_id=job_id, + execution_id=execution_id, + client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + ) + ).parsed diff --git a/src/blaxel/core/client/api/jobs/list_job_executions.py b/src/blaxel/core/client/api/jobs/list_job_executions.py index 640b2162..ac653aa5 100644 --- a/src/blaxel/core/client/api/jobs/list_job_executions.py +++ b/src/blaxel/core/client/api/jobs/list_job_executions.py @@ -5,7 +5,8 @@ from ... import errors from ...client import Client -from ...models.job_execution import JobExecution +from ...models.job_execution_list import JobExecutionList +from ...models.list_job_executions_sort import ListJobExecutionsSort from ...types import UNSET, Response, Unset @@ -14,6 +15,9 @@ def _get_kwargs( *, limit: Union[Unset, int] = 20, offset: Union[Unset, int] = 0, + cursor: Union[Unset, str] = UNSET, + sort: Union[Unset, ListJobExecutionsSort] = UNSET, + q: Union[Unset, str] = UNSET, ) -> dict[str, Any]: params: dict[str, Any] = {} @@ -21,6 +25,16 @@ def _get_kwargs( params["offset"] = offset + params["cursor"] = cursor + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} _kwargs: dict[str, Any] = { @@ -34,14 +48,9 @@ def _get_kwargs( def _parse_response( *, client: Client, response: httpx.Response -) -> Union[Any, list["JobExecution"]] | None: +) -> Union[Any, JobExecutionList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = JobExecution.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = JobExecutionList.from_dict(response.json()) return response_200 if response.status_code == 400: @@ -58,7 +67,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Any, list["JobExecution"]]]: +) -> Response[Union[Any, JobExecutionList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,29 +82,39 @@ def sync_detailed( client: Client, limit: Union[Unset, int] = 20, offset: Union[Unset, int] = 0, -) -> Response[Union[Any, list["JobExecution"]]]: + cursor: Union[Unset, str] = UNSET, + sort: Union[Unset, ListJobExecutionsSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Response[Union[Any, JobExecutionList]]: """List job executions - Returns paginated list of executions for a batch job, sorted by creation time. Each execution - contains status, task counts, and timing information. + Returns executions for a batch job. Starting with API version 2026-04-28 the response is wrapped in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep the legacy offset/limit contract and return a bare array. Args: job_id (str): limit (Union[Unset, int]): Default: 20. offset (Union[Unset, int]): Default: 0. + cursor (Union[Unset, str]): + sort (Union[Unset, ListJobExecutionsSort]): + q (Union[Unset, str]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, list['JobExecution']]] + Response[Union[Any, JobExecutionList]] """ kwargs = _get_kwargs( job_id=job_id, limit=limit, offset=offset, + cursor=cursor, + sort=sort, + q=q, ) response = client.get_httpx_client().request( @@ -111,23 +130,30 @@ def sync( client: Client, limit: Union[Unset, int] = 20, offset: Union[Unset, int] = 0, -) -> Union[Any, list["JobExecution"]] | None: + cursor: Union[Unset, str] = UNSET, + sort: Union[Unset, ListJobExecutionsSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Union[Any, JobExecutionList] | None: """List job executions - Returns paginated list of executions for a batch job, sorted by creation time. Each execution - contains status, task counts, and timing information. + Returns executions for a batch job. Starting with API version 2026-04-28 the response is wrapped in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep the legacy offset/limit contract and return a bare array. Args: job_id (str): limit (Union[Unset, int]): Default: 20. offset (Union[Unset, int]): Default: 0. + cursor (Union[Unset, str]): + sort (Union[Unset, ListJobExecutionsSort]): + q (Union[Unset, str]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, list['JobExecution']] + Union[Any, JobExecutionList] """ return sync_detailed( @@ -135,6 +161,9 @@ def sync( client=client, limit=limit, offset=offset, + cursor=cursor, + sort=sort, + q=q, ).parsed @@ -144,29 +173,39 @@ async def asyncio_detailed( client: Client, limit: Union[Unset, int] = 20, offset: Union[Unset, int] = 0, -) -> Response[Union[Any, list["JobExecution"]]]: + cursor: Union[Unset, str] = UNSET, + sort: Union[Unset, ListJobExecutionsSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Response[Union[Any, JobExecutionList]]: """List job executions - Returns paginated list of executions for a batch job, sorted by creation time. Each execution - contains status, task counts, and timing information. + Returns executions for a batch job. Starting with API version 2026-04-28 the response is wrapped in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep the legacy offset/limit contract and return a bare array. Args: job_id (str): limit (Union[Unset, int]): Default: 20. offset (Union[Unset, int]): Default: 0. + cursor (Union[Unset, str]): + sort (Union[Unset, ListJobExecutionsSort]): + q (Union[Unset, str]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, list['JobExecution']]] + Response[Union[Any, JobExecutionList]] """ kwargs = _get_kwargs( job_id=job_id, limit=limit, offset=offset, + cursor=cursor, + sort=sort, + q=q, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -180,23 +219,30 @@ async def asyncio( client: Client, limit: Union[Unset, int] = 20, offset: Union[Unset, int] = 0, -) -> Union[Any, list["JobExecution"]] | None: + cursor: Union[Unset, str] = UNSET, + sort: Union[Unset, ListJobExecutionsSort] = UNSET, + q: Union[Unset, str] = UNSET, +) -> Union[Any, JobExecutionList] | None: """List job executions - Returns paginated list of executions for a batch job, sorted by creation time. Each execution - contains status, task counts, and timing information. + Returns executions for a batch job. Starting with API version 2026-04-28 the response is wrapped in + `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older + versions keep the legacy offset/limit contract and return a bare array. Args: job_id (str): limit (Union[Unset, int]): Default: 20. offset (Union[Unset, int]): Default: 0. + cursor (Union[Unset, str]): + sort (Union[Unset, ListJobExecutionsSort]): + q (Union[Unset, str]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, list['JobExecution']] + Union[Any, JobExecutionList] """ return ( @@ -205,5 +251,8 @@ async def asyncio( client=client, limit=limit, offset=offset, + cursor=cursor, + sort=sort, + q=q, ) ).parsed diff --git a/src/blaxel/core/client/api/jobs/list_jobs.py b/src/blaxel/core/client/api/jobs/list_jobs.py index 039612cd..1e75e9fd 100644 --- a/src/blaxel/core/client/api/jobs/list_jobs.py +++ b/src/blaxel/core/client/api/jobs/list_jobs.py @@ -1,31 +1,58 @@ from http import HTTPStatus -from typing import Any +from typing import Any, Union import httpx from ... import errors from ...client import Client -from ...models.job import Job -from ...types import Response +from ...models.job_list import JobList +from ...models.list_jobs_anchor import ListJobsAnchor +from ...models.list_jobs_sort import ListJobsSort +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListJobsAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/jobs", + "params": params, } return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> list["Job"] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> JobList | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Job.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = JobList.from_dict(response.json()) return response_200 if client.raise_on_unexpected_status: @@ -34,7 +61,7 @@ def _parse_response(*, client: Client, response: httpx.Response) -> list["Job"] return None -def _build_response(*, client: Client, response: httpx.Response) -> Response[list["Job"]]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[JobList]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -46,21 +73,41 @@ def _build_response(*, client: Client, response: httpx.Response) -> Response[lis def sync_detailed( *, client: Client, -) -> Response[list["Job"]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListJobsAnchor] = UNSET, +) -> Response[JobList]: """List batch jobs - Returns all batch job definitions in the workspace. Each job can be triggered to run multiple - parallel tasks with configurable concurrency and retry settings. + Returns batch job definitions in the workspace. Each job can be triggered to run multiple parallel + tasks with configurable concurrency and retry settings. Starting with API version 2026-04-28 the + response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` + query parameters; older versions keep returning a bare array with all jobs. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListJobsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list['Job']] + Response[JobList] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -72,43 +119,82 @@ def sync_detailed( def sync( *, client: Client, -) -> list["Job"] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListJobsAnchor] = UNSET, +) -> JobList | None: """List batch jobs - Returns all batch job definitions in the workspace. Each job can be triggered to run multiple - parallel tasks with configurable concurrency and retry settings. + Returns batch job definitions in the workspace. Each job can be triggered to run multiple parallel + tasks with configurable concurrency and retry settings. Starting with API version 2026-04-28 the + response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` + query parameters; older versions keep returning a bare array with all jobs. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListJobsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list['Job'] + JobList """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[list["Job"]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListJobsAnchor] = UNSET, +) -> Response[JobList]: """List batch jobs - Returns all batch job definitions in the workspace. Each job can be triggered to run multiple - parallel tasks with configurable concurrency and retry settings. + Returns batch job definitions in the workspace. Each job can be triggered to run multiple parallel + tasks with configurable concurrency and retry settings. Starting with API version 2026-04-28 the + response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` + query parameters; older versions keep returning a bare array with all jobs. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListJobsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list['Job']] + Response[JobList] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -118,22 +204,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> list["Job"] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListJobsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListJobsAnchor] = UNSET, +) -> JobList | None: """List batch jobs - Returns all batch job definitions in the workspace. Each job can be triggered to run multiple - parallel tasks with configurable concurrency and retry settings. + Returns batch job definitions in the workspace. Each job can be triggered to run multiple parallel + tasks with configurable concurrency and retry settings. Starting with API version 2026-04-28 the + response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` + query parameters; older versions keep returning a bare array with all jobs. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListJobsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListJobsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list['Job'] + JobList """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/models/list_models.py b/src/blaxel/core/client/api/models/list_models.py index 790712f0..285a8031 100644 --- a/src/blaxel/core/client/api/models/list_models.py +++ b/src/blaxel/core/client/api/models/list_models.py @@ -6,29 +6,54 @@ from ... import errors from ...client import Client from ...models.error import Error -from ...models.model import Model -from ...types import Response +from ...models.list_models_anchor import ListModelsAnchor +from ...models.list_models_sort import ListModelsSort +from ...models.model_list import ModelList +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListModelsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListModelsAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/models", + "params": params, } return _kwargs -def _parse_response( - *, client: Client, response: httpx.Response -) -> Union[Error, list["Model"]] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> Union[Error, ModelList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Model.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = ModelList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -51,7 +76,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Error, list["Model"]]]: +) -> Response[Union[Error, ModelList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -63,21 +88,41 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Error, list["Model"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListModelsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListModelsAnchor] = UNSET, +) -> Response[Union[Error, ModelList]]: """List model endpoints - Returns all model gateway endpoints configured in the workspace. Each model represents a proxy to an - external LLM provider (OpenAI, Anthropic, etc.) with unified access control. + Returns model gateway endpoints configured in the workspace. Each model represents a proxy to an + external LLM provider (OpenAI, Anthropic, etc.) with unified access control. Starting with API + version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the + `cursor` and `limit` query parameters; older versions keep returning a bare array with all models. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListModelsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListModelsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Model']]] + Response[Union[Error, ModelList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -89,43 +134,82 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Error, list["Model"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListModelsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListModelsAnchor] = UNSET, +) -> Union[Error, ModelList] | None: """List model endpoints - Returns all model gateway endpoints configured in the workspace. Each model represents a proxy to an - external LLM provider (OpenAI, Anthropic, etc.) with unified access control. + Returns model gateway endpoints configured in the workspace. Each model represents a proxy to an + external LLM provider (OpenAI, Anthropic, etc.) with unified access control. Starting with API + version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the + `cursor` and `limit` query parameters; older versions keep returning a bare array with all models. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListModelsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListModelsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Model']] + Union[Error, ModelList] """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Error, list["Model"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListModelsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListModelsAnchor] = UNSET, +) -> Response[Union[Error, ModelList]]: """List model endpoints - Returns all model gateway endpoints configured in the workspace. Each model represents a proxy to an - external LLM provider (OpenAI, Anthropic, etc.) with unified access control. + Returns model gateway endpoints configured in the workspace. Each model represents a proxy to an + external LLM provider (OpenAI, Anthropic, etc.) with unified access control. Starting with API + version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the + `cursor` and `limit` query parameters; older versions keep returning a bare array with all models. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListModelsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListModelsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Model']]] + Response[Union[Error, ModelList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -135,22 +219,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Error, list["Model"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListModelsSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListModelsAnchor] = UNSET, +) -> Union[Error, ModelList] | None: """List model endpoints - Returns all model gateway endpoints configured in the workspace. Each model represents a proxy to an - external LLM provider (OpenAI, Anthropic, etc.) with unified access control. + Returns model gateway endpoints configured in the workspace. Each model represents a proxy to an + external LLM provider (OpenAI, Anthropic, etc.) with unified access control. Starting with API + version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the + `cursor` and `limit` query parameters; older versions keep returning a bare array with all models. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListModelsSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListModelsAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Model']] + Union[Error, ModelList] """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/policies/get_policy_usages.py b/src/blaxel/core/client/api/policies/get_policy_usages.py new file mode 100644 index 00000000..8efc2656 --- /dev/null +++ b/src/blaxel/core/client/api/policies/get_policy_usages.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import Client +from ...models.policy_usages import PolicyUsages +from ...types import Response + + +def _get_kwargs( + policy_name: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/policies/{policy_name}/usages", + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> PolicyUsages | None: + if response.status_code == 200: + response_200 = PolicyUsages.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[PolicyUsages]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + policy_name: str, + *, + client: Client, +) -> Response[PolicyUsages]: + """List resources using a policy + + Returns the names of every resource (agent, function, model, sandbox, job) currently referencing the + given policy. Replaces the client-side fan-out the policies UI used to do over the listings. + + Args: + policy_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PolicyUsages] + """ + + kwargs = _get_kwargs( + policy_name=policy_name, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + policy_name: str, + *, + client: Client, +) -> PolicyUsages | None: + """List resources using a policy + + Returns the names of every resource (agent, function, model, sandbox, job) currently referencing the + given policy. Replaces the client-side fan-out the policies UI used to do over the listings. + + Args: + policy_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PolicyUsages + """ + + return sync_detailed( + policy_name=policy_name, + client=client, + ).parsed + + +async def asyncio_detailed( + policy_name: str, + *, + client: Client, +) -> Response[PolicyUsages]: + """List resources using a policy + + Returns the names of every resource (agent, function, model, sandbox, job) currently referencing the + given policy. Replaces the client-side fan-out the policies UI used to do over the listings. + + Args: + policy_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PolicyUsages] + """ + + kwargs = _get_kwargs( + policy_name=policy_name, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + policy_name: str, + *, + client: Client, +) -> PolicyUsages | None: + """List resources using a policy + + Returns the names of every resource (agent, function, model, sandbox, job) currently referencing the + given policy. Replaces the client-side fan-out the policies UI used to do over the listings. + + Args: + policy_name (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PolicyUsages + """ + + return ( + await asyncio_detailed( + policy_name=policy_name, + client=client, + ) + ).parsed diff --git a/src/blaxel/core/client/api/policies/list_policies.py b/src/blaxel/core/client/api/policies/list_policies.py index 6f188ed5..7138a0df 100644 --- a/src/blaxel/core/client/api/policies/list_policies.py +++ b/src/blaxel/core/client/api/policies/list_policies.py @@ -1,31 +1,58 @@ from http import HTTPStatus -from typing import Any +from typing import Any, Union import httpx from ... import errors from ...client import Client -from ...models.policy import Policy -from ...types import Response +from ...models.list_policies_anchor import ListPoliciesAnchor +from ...models.list_policies_sort import ListPoliciesSort +from ...models.policy_list import PolicyList +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListPoliciesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListPoliciesAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/policies", + "params": params, } return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> list["Policy"] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> PolicyList | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Policy.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = PolicyList.from_dict(response.json()) return response_200 if client.raise_on_unexpected_status: @@ -34,7 +61,7 @@ def _parse_response(*, client: Client, response: httpx.Response) -> list["Policy return None -def _build_response(*, client: Client, response: httpx.Response) -> Response[list["Policy"]]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[PolicyList]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -46,21 +73,41 @@ def _build_response(*, client: Client, response: httpx.Response) -> Response[lis def sync_detailed( *, client: Client, -) -> Response[list["Policy"]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListPoliciesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListPoliciesAnchor] = UNSET, +) -> Response[PolicyList]: """List governance policies - Returns all governance policies in the workspace. Policies control deployment locations, hardware - flavors, and token limits for agents, functions, and models. + Returns governance policies in the workspace. Policies control deployment locations, hardware + flavors, and token limits for agents, functions, and models. Starting with API version 2026-04-28 + the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and + `limit` query parameters; older versions keep returning a bare array with all policies. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListPoliciesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListPoliciesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list['Policy']] + Response[PolicyList] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -72,43 +119,82 @@ def sync_detailed( def sync( *, client: Client, -) -> list["Policy"] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListPoliciesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListPoliciesAnchor] = UNSET, +) -> PolicyList | None: """List governance policies - Returns all governance policies in the workspace. Policies control deployment locations, hardware - flavors, and token limits for agents, functions, and models. + Returns governance policies in the workspace. Policies control deployment locations, hardware + flavors, and token limits for agents, functions, and models. Starting with API version 2026-04-28 + the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and + `limit` query parameters; older versions keep returning a bare array with all policies. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListPoliciesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListPoliciesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list['Policy'] + PolicyList """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[list["Policy"]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListPoliciesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListPoliciesAnchor] = UNSET, +) -> Response[PolicyList]: """List governance policies - Returns all governance policies in the workspace. Policies control deployment locations, hardware - flavors, and token limits for agents, functions, and models. + Returns governance policies in the workspace. Policies control deployment locations, hardware + flavors, and token limits for agents, functions, and models. Starting with API version 2026-04-28 + the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and + `limit` query parameters; older versions keep returning a bare array with all policies. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListPoliciesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListPoliciesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list['Policy']] + Response[PolicyList] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -118,22 +204,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> list["Policy"] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListPoliciesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListPoliciesAnchor] = UNSET, +) -> PolicyList | None: """List governance policies - Returns all governance policies in the workspace. Policies control deployment locations, hardware - flavors, and token limits for agents, functions, and models. + Returns governance policies in the workspace. Policies control deployment locations, hardware + flavors, and token limits for agents, functions, and models. Starting with API version 2026-04-28 + the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and + `limit` query parameters; older versions keep returning a bare array with all policies. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListPoliciesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListPoliciesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list['Policy'] + PolicyList """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/volumes/list_volumes.py b/src/blaxel/core/client/api/volumes/list_volumes.py index 23cfe6d6..07ddd9dc 100644 --- a/src/blaxel/core/client/api/volumes/list_volumes.py +++ b/src/blaxel/core/client/api/volumes/list_volumes.py @@ -6,29 +6,54 @@ from ... import errors from ...client import Client from ...models.error import Error -from ...models.volume import Volume -from ...types import Response +from ...models.list_volumes_anchor import ListVolumesAnchor +from ...models.list_volumes_sort import ListVolumesSort +from ...models.volume_list import VolumeList +from ...types import UNSET, Response, Unset -def _get_kwargs() -> dict[str, Any]: +def _get_kwargs( + *, + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListVolumesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListVolumesAnchor] = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["cursor"] = cursor + + params["limit"] = limit + + json_sort: Union[Unset, str] = UNSET + if not isinstance(sort, Unset): + json_sort = sort.value + + params["sort"] = json_sort + + params["q"] = q + + json_anchor: Union[Unset, str] = UNSET + if not isinstance(anchor, Unset): + json_anchor = anchor.value + + params["anchor"] = json_anchor + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": "/volumes", + "params": params, } return _kwargs -def _parse_response( - *, client: Client, response: httpx.Response -) -> Union[Error, list["Volume"]] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> Union[Error, VolumeList] | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = Volume.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = VolumeList.from_dict(response.json()) return response_200 if response.status_code == 401: @@ -51,7 +76,7 @@ def _parse_response( def _build_response( *, client: Client, response: httpx.Response -) -> Response[Union[Error, list["Volume"]]]: +) -> Response[Union[Error, VolumeList]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -63,21 +88,41 @@ def _build_response( def sync_detailed( *, client: Client, -) -> Response[Union[Error, list["Volume"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListVolumesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListVolumesAnchor] = UNSET, +) -> Response[Union[Error, VolumeList]]: """List persistent volumes - Returns all persistent storage volumes in the workspace. Volumes can be attached to sandboxes for - durable file storage that persists across sessions and sandbox deletions. + Returns persistent storage volumes in the workspace. Volumes can be attached to sandboxes for + durable file storage that persists across sessions and sandbox deletions. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array of volumes. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListVolumesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListVolumesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Volume']]] + Response[Union[Error, VolumeList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = client.get_httpx_client().request( **kwargs, @@ -89,43 +134,82 @@ def sync_detailed( def sync( *, client: Client, -) -> Union[Error, list["Volume"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListVolumesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListVolumesAnchor] = UNSET, +) -> Union[Error, VolumeList] | None: """List persistent volumes - Returns all persistent storage volumes in the workspace. Volumes can be attached to sandboxes for - durable file storage that persists across sessions and sandbox deletions. + Returns persistent storage volumes in the workspace. Volumes can be attached to sandboxes for + durable file storage that persists across sessions and sandbox deletions. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array of volumes. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListVolumesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListVolumesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Volume']] + Union[Error, VolumeList] """ return sync_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ).parsed async def asyncio_detailed( *, client: Client, -) -> Response[Union[Error, list["Volume"]]]: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListVolumesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListVolumesAnchor] = UNSET, +) -> Response[Union[Error, VolumeList]]: """List persistent volumes - Returns all persistent storage volumes in the workspace. Volumes can be attached to sandboxes for - durable file storage that persists across sessions and sandbox deletions. + Returns persistent storage volumes in the workspace. Volumes can be attached to sandboxes for + durable file storage that persists across sessions and sandbox deletions. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array of volumes. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListVolumesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListVolumesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Error, list['Volume']]] + Response[Union[Error, VolumeList]] """ - kwargs = _get_kwargs() + kwargs = _get_kwargs( + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, + ) response = await client.get_async_httpx_client().request(**kwargs) @@ -135,22 +219,41 @@ async def asyncio_detailed( async def asyncio( *, client: Client, -) -> Union[Error, list["Volume"]] | None: + cursor: Union[Unset, str] = UNSET, + limit: Union[Unset, int] = 50, + sort: Union[Unset, ListVolumesSort] = UNSET, + q: Union[Unset, str] = UNSET, + anchor: Union[Unset, ListVolumesAnchor] = UNSET, +) -> Union[Error, VolumeList] | None: """List persistent volumes - Returns all persistent storage volumes in the workspace. Volumes can be attached to sandboxes for - durable file storage that persists across sessions and sandbox deletions. + Returns persistent storage volumes in the workspace. Volumes can be attached to sandboxes for + durable file storage that persists across sessions and sandbox deletions. Starting with API version + 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` + and `limit` query parameters; older versions keep returning a bare array of volumes. + + Args: + cursor (Union[Unset, str]): + limit (Union[Unset, int]): Default: 50. + sort (Union[Unset, ListVolumesSort]): + q (Union[Unset, str]): + anchor (Union[Unset, ListVolumesAnchor]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Error, list['Volume']] + Union[Error, VolumeList] """ return ( await asyncio_detailed( client=client, + cursor=cursor, + limit=limit, + sort=sort, + q=q, + anchor=anchor, ) ).parsed diff --git a/src/blaxel/core/client/api/vpcs/get_egress_gateway_usage.py b/src/blaxel/core/client/api/vpcs/get_egress_gateway_usage.py new file mode 100644 index 00000000..62e894c3 --- /dev/null +++ b/src/blaxel/core/client/api/vpcs/get_egress_gateway_usage.py @@ -0,0 +1,134 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import Client +from ...models.egress_gateway_usage import EgressGatewayUsage +from ...types import Response + + +def _get_kwargs() -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/egressgateways/usage", + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> EgressGatewayUsage | None: + if response.status_code == 200: + response_200 = EgressGatewayUsage.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[EgressGatewayUsage]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Client, +) -> Response[EgressGatewayUsage]: + """Egress gateway sandbox attachments + + Returns the inverse map (gateway → sandbox names) for the workspace. Used by the egress-IPs UI to + render attachment counts without fetching the sandboxes listing full client-side. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[EgressGatewayUsage] + """ + + kwargs = _get_kwargs() + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Client, +) -> EgressGatewayUsage | None: + """Egress gateway sandbox attachments + + Returns the inverse map (gateway → sandbox names) for the workspace. Used by the egress-IPs UI to + render attachment counts without fetching the sandboxes listing full client-side. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + EgressGatewayUsage + """ + + return sync_detailed( + client=client, + ).parsed + + +async def asyncio_detailed( + *, + client: Client, +) -> Response[EgressGatewayUsage]: + """Egress gateway sandbox attachments + + Returns the inverse map (gateway → sandbox names) for the workspace. Used by the egress-IPs UI to + render attachment counts without fetching the sandboxes listing full client-side. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[EgressGatewayUsage] + """ + + kwargs = _get_kwargs() + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Client, +) -> EgressGatewayUsage | None: + """Egress gateway sandbox attachments + + Returns the inverse map (gateway → sandbox names) for the workspace. Used by the egress-IPs UI to + render attachment counts without fetching the sandboxes listing full client-side. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + EgressGatewayUsage + """ + + return ( + await asyncio_detailed( + client=client, + ) + ).parsed diff --git a/src/blaxel/core/client/api/workspaces/get_workspace.py b/src/blaxel/core/client/api/workspaces/get_workspace.py index d8d1c6c7..1e1bbc95 100644 --- a/src/blaxel/core/client/api/workspaces/get_workspace.py +++ b/src/blaxel/core/client/api/workspaces/get_workspace.py @@ -7,15 +7,24 @@ from ...client import Client from ...models.error import Error from ...models.workspace import Workspace -from ...types import Response +from ...types import UNSET, Response, Unset def _get_kwargs( workspace_name: str, + *, + count_resources: Union[Unset, bool] = False, ) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["countResources"] = count_resources + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "get", "url": f"/workspaces/{workspace_name}", + "params": params, } return _kwargs @@ -63,6 +72,7 @@ def sync_detailed( workspace_name: str, *, client: Client, + count_resources: Union[Unset, bool] = False, ) -> Response[Union[Error, Workspace]]: """Get workspace details @@ -71,6 +81,7 @@ def sync_detailed( Args: workspace_name (str): + count_resources (Union[Unset, bool]): Default: False. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -82,6 +93,7 @@ def sync_detailed( kwargs = _get_kwargs( workspace_name=workspace_name, + count_resources=count_resources, ) response = client.get_httpx_client().request( @@ -95,6 +107,7 @@ def sync( workspace_name: str, *, client: Client, + count_resources: Union[Unset, bool] = False, ) -> Union[Error, Workspace] | None: """Get workspace details @@ -103,6 +116,7 @@ def sync( Args: workspace_name (str): + count_resources (Union[Unset, bool]): Default: False. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -115,6 +129,7 @@ def sync( return sync_detailed( workspace_name=workspace_name, client=client, + count_resources=count_resources, ).parsed @@ -122,6 +137,7 @@ async def asyncio_detailed( workspace_name: str, *, client: Client, + count_resources: Union[Unset, bool] = False, ) -> Response[Union[Error, Workspace]]: """Get workspace details @@ -130,6 +146,7 @@ async def asyncio_detailed( Args: workspace_name (str): + count_resources (Union[Unset, bool]): Default: False. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -141,6 +158,7 @@ async def asyncio_detailed( kwargs = _get_kwargs( workspace_name=workspace_name, + count_resources=count_resources, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -152,6 +170,7 @@ async def asyncio( workspace_name: str, *, client: Client, + count_resources: Union[Unset, bool] = False, ) -> Union[Error, Workspace] | None: """Get workspace details @@ -160,6 +179,7 @@ async def asyncio( Args: workspace_name (str): + count_resources (Union[Unset, bool]): Default: False. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -173,5 +193,6 @@ async def asyncio( await asyncio_detailed( workspace_name=workspace_name, client=client, + count_resources=count_resources, ) ).parsed diff --git a/src/blaxel/core/client/models/__init__.py b/src/blaxel/core/client/models/__init__.py index c86b8df3..432701b3 100644 --- a/src/blaxel/core/client/models/__init__.py +++ b/src/blaxel/core/client/models/__init__.py @@ -1,10 +1,17 @@ """Contains all the data models used in inputs/outputs""" from .agent import Agent +from .agent_list import AgentList from .agent_runtime import AgentRuntime from .agent_runtime_generation import AgentRuntimeGeneration from .agent_spec import AgentSpec from .api_key import ApiKey +from .app_revision import AppRevision +from .app_revision_configuration import AppRevisionConfiguration +from .app_url import AppUrl +from .application import Application +from .application_list import ApplicationList +from .application_spec import ApplicationSpec from .check_workspace_availability_body import CheckWorkspaceAvailabilityBody from .cleanup_images_response_200 import CleanupImagesResponse200 from .configuration import Configuration @@ -27,17 +34,20 @@ from .custom_domain_spec import CustomDomainSpec from .custom_domain_spec_status import CustomDomainSpecStatus from .custom_domain_spec_txt_records import CustomDomainSpecTxtRecords +from .custom_domain_subdomain import CustomDomainSubdomain from .delete_drive_response_200 import DeleteDriveResponse200 from .delete_sandbox_preview_token_response_200 import DeleteSandboxPreviewTokenResponse200 from .delete_volume_template_version_response_200 import DeleteVolumeTemplateVersionResponse200 from .delete_workspace_service_account_response_200 import DeleteWorkspaceServiceAccountResponse200 from .drive import Drive +from .drive_list import DriveList from .drive_spec import DriveSpec from .drive_state import DriveState from .egress_config import EgressConfig from .egress_gateway import EgressGateway from .egress_gateway_metadata import EgressGatewayMetadata from .egress_gateway_spec import EgressGatewaySpec +from .egress_gateway_usage import EgressGatewayUsage from .egress_ip import EgressIP from .egress_ip_metadata import EgressIPMetadata from .egress_ip_spec import EgressIPSpec @@ -52,12 +62,14 @@ from .expiration_policy import ExpirationPolicy from .expiration_policy_action import ExpirationPolicyAction from .expiration_policy_type import ExpirationPolicyType +from .firewall_config import FirewallConfig from .flavor import Flavor from .flavor_type import FlavorType from .form import Form from .form_config import FormConfig from .form_secrets import FormSecrets from .function import Function +from .function_list import FunctionList from .function_runtime import FunctionRuntime from .function_runtime_generation import FunctionRuntimeGeneration from .function_runtime_transport import FunctionRuntimeTransport @@ -95,6 +107,7 @@ from .invite_workspace_user_body import InviteWorkspaceUserBody from .job import Job from .job_execution import JobExecution +from .job_execution_list import JobExecutionList from .job_execution_metadata import JobExecutionMetadata from .job_execution_spec import JobExecutionSpec from .job_execution_spec_env_override import JobExecutionSpecEnvOverride @@ -102,21 +115,47 @@ from .job_execution_status import JobExecutionStatus from .job_execution_task import JobExecutionTask from .job_execution_task_condition import JobExecutionTaskCondition +from .job_execution_task_list import JobExecutionTaskList from .job_execution_task_metadata import JobExecutionTaskMetadata from .job_execution_task_spec import JobExecutionTaskSpec from .job_execution_task_status import JobExecutionTaskStatus +from .job_list import JobList from .job_runtime import JobRuntime from .job_runtime_generation import JobRuntimeGeneration from .job_spec import JobSpec from .job_volume import JobVolume from .job_volume_type import JobVolumeType +from .list_agents_anchor import ListAgentsAnchor +from .list_agents_sort import ListAgentsSort +from .list_applications_anchor import ListApplicationsAnchor +from .list_applications_sort import ListApplicationsSort +from .list_drives_anchor import ListDrivesAnchor +from .list_drives_sort import ListDrivesSort +from .list_functions_anchor import ListFunctionsAnchor +from .list_functions_sort import ListFunctionsSort +from .list_job_execution_tasks_sort import ListJobExecutionTasksSort +from .list_job_executions_sort import ListJobExecutionsSort +from .list_jobs_anchor import ListJobsAnchor +from .list_jobs_sort import ListJobsSort +from .list_models_anchor import ListModelsAnchor +from .list_models_sort import ListModelsSort from .list_pending_image_shares_direction import ListPendingImageSharesDirection +from .list_policies_anchor import ListPoliciesAnchor +from .list_policies_sort import ListPoliciesSort +from .list_sandboxes_anchor import ListSandboxesAnchor +from .list_sandboxes_sort import ListSandboxesSort +from .list_volumes_anchor import ListVolumesAnchor +from .list_volumes_sort import ListVolumesSort +from .lite_volume import LiteVolume +from .lite_volume_metadata import LiteVolumeMetadata +from .lite_volume_spec import LiteVolumeSpec from .location_response import LocationResponse from .mcp_definition import MCPDefinition from .mcp_definition_categories_item import MCPDefinitionCategoriesItem from .metadata import Metadata from .metadata_labels import MetadataLabels from .model import Model +from .model_list import ModelList from .model_runtime import ModelRuntime from .model_runtime_generation import ModelRuntimeGeneration from .model_runtime_type import ModelRuntimeType @@ -125,6 +164,7 @@ from .o_auth import OAuth from .o_auth_scope_item import OAuthScopeItem from .owner_fields import OwnerFields +from .pagination_meta import PaginationMeta from .pending_image_share import PendingImageShare from .pending_image_share_render import PendingImageShareRender from .pending_invitation import PendingInvitation @@ -138,12 +178,20 @@ PendingInvitationWorkspaceDetailsEmailsItem, ) from .policy import Policy +from .policy_list import PolicyList from .policy_location import PolicyLocation from .policy_location_type import PolicyLocationType from .policy_max_tokens import PolicyMaxTokens from .policy_resource_type import PolicyResourceType from .policy_spec import PolicySpec from .policy_spec_type import PolicySpecType +from .policy_usage_counts import PolicyUsageCounts +from .policy_usages import PolicyUsages +from .policy_usages_agents_item import PolicyUsagesAgentsItem +from .policy_usages_functions_item import PolicyUsagesFunctionsItem +from .policy_usages_jobs_item import PolicyUsagesJobsItem +from .policy_usages_models_item import PolicyUsagesModelsItem +from .policy_usages_sandboxes_item import PolicyUsagesSandboxesItem from .port import Port from .port_protocol import PortProtocol from .preview import Preview @@ -173,6 +221,7 @@ from .sandbox_error import SandboxError from .sandbox_error_details import SandboxErrorDetails from .sandbox_lifecycle import SandboxLifecycle +from .sandbox_list import SandboxList from .sandbox_network import SandboxNetwork from .sandbox_runtime import SandboxRuntime from .sandbox_runtime_extra_args import SandboxRuntimeExtraArgs @@ -198,6 +247,7 @@ from .update_workspace_user_role_body import UpdateWorkspaceUserRoleBody from .volume import Volume from .volume_attachment import VolumeAttachment +from .volume_list import VolumeList from .volume_spec import VolumeSpec from .volume_state import VolumeState from .volume_template import VolumeTemplate @@ -211,17 +261,28 @@ from .workspace import Workspace from .workspace_availability import WorkspaceAvailability from .workspace_availability_reason import WorkspaceAvailabilityReason +from .workspace_hipaa_info import WorkspaceHipaaInfo +from .workspace_hipaa_unsafe import WorkspaceHipaaUnsafe +from .workspace_resource_counts import WorkspaceResourceCounts from .workspace_runtime import WorkspaceRuntime +from .workspace_sandbox_settings import WorkspaceSandboxSettings from .workspace_status import WorkspaceStatus from .workspace_user import WorkspaceUser from .workspace_user_source import WorkspaceUserSource __all__ = ( "Agent", + "AgentList", "AgentRuntime", "AgentRuntimeGeneration", "AgentSpec", "ApiKey", + "Application", + "ApplicationList", + "ApplicationSpec", + "AppRevision", + "AppRevisionConfiguration", + "AppUrl", "CheckWorkspaceAvailabilityBody", "CleanupImagesResponse200", "Configuration", @@ -244,17 +305,20 @@ "CustomDomainSpec", "CustomDomainSpecStatus", "CustomDomainSpecTxtRecords", + "CustomDomainSubdomain", "DeleteDriveResponse200", "DeleteSandboxPreviewTokenResponse200", "DeleteVolumeTemplateVersionResponse200", "DeleteWorkspaceServiceAccountResponse200", "Drive", + "DriveList", "DriveSpec", "DriveState", "EgressConfig", "EgressGateway", "EgressGatewayMetadata", "EgressGatewaySpec", + "EgressGatewayUsage", "EgressIP", "EgressIPMetadata", "EgressIPSpec", @@ -269,12 +333,14 @@ "ExpirationPolicy", "ExpirationPolicyAction", "ExpirationPolicyType", + "FirewallConfig", "Flavor", "FlavorType", "Form", "FormConfig", "FormSecrets", "Function", + "FunctionList", "FunctionRuntime", "FunctionRuntimeGeneration", "FunctionRuntimeTransport", @@ -310,6 +376,7 @@ "InviteWorkspaceUserBody", "Job", "JobExecution", + "JobExecutionList", "JobExecutionMetadata", "JobExecutionSpec", "JobExecutionSpecEnvOverride", @@ -317,21 +384,47 @@ "JobExecutionStatus", "JobExecutionTask", "JobExecutionTaskCondition", + "JobExecutionTaskList", "JobExecutionTaskMetadata", "JobExecutionTaskSpec", "JobExecutionTaskStatus", + "JobList", "JobRuntime", "JobRuntimeGeneration", "JobSpec", "JobVolume", "JobVolumeType", + "ListAgentsAnchor", + "ListAgentsSort", + "ListApplicationsAnchor", + "ListApplicationsSort", + "ListDrivesAnchor", + "ListDrivesSort", + "ListFunctionsAnchor", + "ListFunctionsSort", + "ListJobExecutionsSort", + "ListJobExecutionTasksSort", + "ListJobsAnchor", + "ListJobsSort", + "ListModelsAnchor", + "ListModelsSort", "ListPendingImageSharesDirection", + "ListPoliciesAnchor", + "ListPoliciesSort", + "ListSandboxesAnchor", + "ListSandboxesSort", + "ListVolumesAnchor", + "ListVolumesSort", + "LiteVolume", + "LiteVolumeMetadata", + "LiteVolumeSpec", "LocationResponse", "MCPDefinition", "MCPDefinitionCategoriesItem", "Metadata", "MetadataLabels", "Model", + "ModelList", "ModelRuntime", "ModelRuntimeGeneration", "ModelRuntimeType", @@ -340,6 +433,7 @@ "OAuth", "OAuthScopeItem", "OwnerFields", + "PaginationMeta", "PendingImageShare", "PendingImageShareRender", "PendingInvitation", @@ -351,12 +445,20 @@ "PendingInvitationWorkspaceDetails", "PendingInvitationWorkspaceDetailsEmailsItem", "Policy", + "PolicyList", "PolicyLocation", "PolicyLocationType", "PolicyMaxTokens", "PolicyResourceType", "PolicySpec", "PolicySpecType", + "PolicyUsageCounts", + "PolicyUsages", + "PolicyUsagesAgentsItem", + "PolicyUsagesFunctionsItem", + "PolicyUsagesJobsItem", + "PolicyUsagesModelsItem", + "PolicyUsagesSandboxesItem", "Port", "PortProtocol", "Preview", @@ -386,6 +488,7 @@ "SandboxError", "SandboxErrorDetails", "SandboxLifecycle", + "SandboxList", "SandboxNetwork", "SandboxRuntime", "SandboxRuntimeExtraArgs", @@ -411,6 +514,7 @@ "UpdateWorkspaceUserRoleBody", "Volume", "VolumeAttachment", + "VolumeList", "VolumeSpec", "VolumeState", "VolumeTemplate", @@ -424,7 +528,11 @@ "Workspace", "WorkspaceAvailability", "WorkspaceAvailabilityReason", + "WorkspaceHipaaInfo", + "WorkspaceHipaaUnsafe", + "WorkspaceResourceCounts", "WorkspaceRuntime", + "WorkspaceSandboxSettings", "WorkspaceStatus", "WorkspaceUser", "WorkspaceUserSource", diff --git a/src/blaxel/core/client/models/agent.py b/src/blaxel/core/client/models/agent.py index b0c8e09d..b1aa662c 100644 --- a/src/blaxel/core/client/models/agent.py +++ b/src/blaxel/core/client/models/agent.py @@ -36,7 +36,6 @@ class Agent: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/agent_list.py b/src/blaxel/core/client/models/agent_list.py new file mode 100644 index 00000000..c25dc81c --- /dev/null +++ b/src/blaxel/core/client/models/agent_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.agent import Agent + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="AgentList") + + +@_attrs_define +class AgentList: + """Cursor-paginated list of agents. Returned starting with API version 2026-04-28; older API versions return a bare + array of agents instead. + + Attributes: + data (Union[Unset, list['Agent']]): Page of agents. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Agent"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.agent import Agent + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Agent.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + agent_list = cls( + data=data, + meta=meta, + ) + + agent_list.additional_properties = d + return agent_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/agent_runtime.py b/src/blaxel/core/client/models/agent_runtime.py index 4cb72a90..e4666217 100644 --- a/src/blaxel/core/client/models/agent_runtime.py +++ b/src/blaxel/core/client/models/agent_runtime.py @@ -41,7 +41,6 @@ class AgentRuntime: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - envs: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.envs, Unset): envs = [] diff --git a/src/blaxel/core/client/models/agent_spec.py b/src/blaxel/core/client/models/agent_spec.py index 1fc8f3c0..7775b4fb 100644 --- a/src/blaxel/core/client/models/agent_spec.py +++ b/src/blaxel/core/client/models/agent_spec.py @@ -48,7 +48,6 @@ class AgentSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled policies: Union[Unset, list[str]] = UNSET diff --git a/src/blaxel/core/client/models/app_revision.py b/src/blaxel/core/client/models/app_revision.py new file mode 100644 index 00000000..7850c93b --- /dev/null +++ b/src/blaxel/core/client/models/app_revision.py @@ -0,0 +1,137 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.env import Env + + +T = TypeVar("T", bound="AppRevision") + + +@_attrs_define +class AppRevision: + """A single application revision containing the deployed image and configuration + + Attributes: + image (str): Container image for this revision (mandatory) + created_at (Union[Unset, str]): When this revision was created + created_by (Union[Unset, str]): Who created this revision + envs (Union[Unset, list['Env']]): Environment variables for this revision + id (Union[Unset, str]): Unique revision identifier + memory (Union[Unset, int]): Memory allocation in megabytes. Determines CPU allocation (CPU = memory / 2048). + Example: 2048. + snapshot (Union[Unset, str]): Snapshot reference if created from a fork (optional) + """ + + image: str + created_at: Union[Unset, str] = UNSET + created_by: Union[Unset, str] = UNSET + envs: Union[Unset, list["Env"]] = UNSET + id: Union[Unset, str] = UNSET + memory: Union[Unset, int] = UNSET + snapshot: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + image = self.image + + created_at = self.created_at + + created_by = self.created_by + + envs: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.envs, Unset): + envs = [] + for envs_item_data in self.envs: + if type(envs_item_data) is dict: + envs_item = envs_item_data + else: + envs_item = envs_item_data.to_dict() + envs.append(envs_item) + + id = self.id + + memory = self.memory + + snapshot = self.snapshot + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "image": image, + } + ) + if created_at is not UNSET: + field_dict["createdAt"] = created_at + if created_by is not UNSET: + field_dict["createdBy"] = created_by + if envs is not UNSET: + field_dict["envs"] = envs + if id is not UNSET: + field_dict["id"] = id + if memory is not UNSET: + field_dict["memory"] = memory + if snapshot is not UNSET: + field_dict["snapshot"] = snapshot + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.env import Env + + if not src_dict: + return None + d = src_dict.copy() + image = d.pop("image") + + created_at = d.pop("createdAt", d.pop("created_at", UNSET)) + + created_by = d.pop("createdBy", d.pop("created_by", UNSET)) + + envs = [] + _envs = d.pop("envs", UNSET) + for envs_item_data in _envs or []: + envs_item = Env.from_dict(envs_item_data) + + envs.append(envs_item) + + id = d.pop("id", UNSET) + + memory = d.pop("memory", UNSET) + + snapshot = d.pop("snapshot", UNSET) + + app_revision = cls( + image=image, + created_at=created_at, + created_by=created_by, + envs=envs, + id=id, + memory=memory, + snapshot=snapshot, + ) + + app_revision.additional_properties = d + return app_revision + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/app_revision_configuration.py b/src/blaxel/core/client/models/app_revision_configuration.py new file mode 100644 index 00000000..e6a0d80b --- /dev/null +++ b/src/blaxel/core/client/models/app_revision_configuration.py @@ -0,0 +1,97 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="AppRevisionConfiguration") + + +@_attrs_define +class AppRevisionConfiguration: + """Routing configuration controlling which revision is active and canary traffic splitting + + Attributes: + active (Union[Unset, str]): Active revision id + canary (Union[Unset, str]): Canary revision id + canary_percent (Union[Unset, int]): Canary revision percent (0-100) Example: 10. + sticky_session_ttl (Union[Unset, int]): Sticky session TTL in seconds (0 = disabled) + traffic (Union[Unset, int]): Traffic percentage for deployment Example: 100. + """ + + active: Union[Unset, str] = UNSET + canary: Union[Unset, str] = UNSET + canary_percent: Union[Unset, int] = UNSET + sticky_session_ttl: Union[Unset, int] = UNSET + traffic: Union[Unset, int] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + active = self.active + + canary = self.canary + + canary_percent = self.canary_percent + + sticky_session_ttl = self.sticky_session_ttl + + traffic = self.traffic + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if active is not UNSET: + field_dict["active"] = active + if canary is not UNSET: + field_dict["canary"] = canary + if canary_percent is not UNSET: + field_dict["canaryPercent"] = canary_percent + if sticky_session_ttl is not UNSET: + field_dict["stickySessionTtl"] = sticky_session_ttl + if traffic is not UNSET: + field_dict["traffic"] = traffic + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + active = d.pop("active", UNSET) + + canary = d.pop("canary", UNSET) + + canary_percent = d.pop("canaryPercent", d.pop("canary_percent", UNSET)) + + sticky_session_ttl = d.pop("stickySessionTtl", d.pop("sticky_session_ttl", UNSET)) + + traffic = d.pop("traffic", UNSET) + + app_revision_configuration = cls( + active=active, + canary=canary, + canary_percent=canary_percent, + sticky_session_ttl=sticky_session_ttl, + traffic=traffic, + ) + + app_revision_configuration.additional_properties = d + return app_revision_configuration + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/app_url.py b/src/blaxel/core/client/models/app_url.py new file mode 100644 index 00000000..7c38302b --- /dev/null +++ b/src/blaxel/core/client/models/app_url.py @@ -0,0 +1,76 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="AppUrl") + + +@_attrs_define +class AppUrl: + """A single URL entry for the application. If the domain is a wildcard custom domain (e.g. *.sandbox.vybe.build), use + subdomain to pick a specific subdomain. If the domain is a direct custom domain (e.g. app.vybe.build), subdomain is + not needed. + + Attributes: + domain (str): Custom domain (must be a verified custom domain in the workspace). Can be a wildcard domain (e.g. + sandbox.vybe.build registered as *.sandbox.vybe.build) or a direct domain (e.g. app.vybe.build). Example: + app.example.com. + subdomain (Union[Unset, str]): Subdomain to use with a wildcard custom domain (optional) Example: www. + """ + + domain: str + subdomain: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + domain = self.domain + + subdomain = self.subdomain + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "domain": domain, + } + ) + if subdomain is not UNSET: + field_dict["subdomain"] = subdomain + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + domain = d.pop("domain") + + subdomain = d.pop("subdomain", UNSET) + + app_url = cls( + domain=domain, + subdomain=subdomain, + ) + + app_url.additional_properties = d + return app_url + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/application.py b/src/blaxel/core/client/models/application.py new file mode 100644 index 00000000..e9c5b37f --- /dev/null +++ b/src/blaxel/core/client/models/application.py @@ -0,0 +1,125 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.application_spec import ApplicationSpec + from ..models.core_event import CoreEvent + from ..models.metadata import Metadata + + +T = TypeVar("T", bound="Application") + + +@_attrs_define +class Application: + """Long-running application deployment that runs your custom code as a publicly accessible endpoint. Applications are + always public and use mk3 generation. + + Attributes: + metadata (Metadata): Common metadata fields shared by all Blaxel resources including name, labels, timestamps, + and ownership information + spec (ApplicationSpec): Configuration for an application including revision management, URL routing, and + deployment region + events (Union[Unset, list['CoreEvent']]): Events happening on a resource deployed on Blaxel + status (Union[Unset, str]): Application status computed from events + """ + + metadata: "Metadata" + spec: "ApplicationSpec" + events: Union[Unset, list["CoreEvent"]] = UNSET + status: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + if type(self.metadata) is dict: + metadata = self.metadata + else: + metadata = self.metadata.to_dict() + + if type(self.spec) is dict: + spec = self.spec + else: + spec = self.spec.to_dict() + + events: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.events, Unset): + events = [] + for componentsschemas_core_events_item_data in self.events: + if type(componentsschemas_core_events_item_data) is dict: + componentsschemas_core_events_item = componentsschemas_core_events_item_data + else: + componentsschemas_core_events_item = ( + componentsschemas_core_events_item_data.to_dict() + ) + events.append(componentsschemas_core_events_item) + + status = self.status + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "metadata": metadata, + "spec": spec, + } + ) + if events is not UNSET: + field_dict["events"] = events + if status is not UNSET: + field_dict["status"] = status + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.application_spec import ApplicationSpec + from ..models.core_event import CoreEvent + from ..models.metadata import Metadata + + if not src_dict: + return None + d = src_dict.copy() + metadata = Metadata.from_dict(d.pop("metadata")) + + spec = ApplicationSpec.from_dict(d.pop("spec")) + + events = [] + _events = d.pop("events", UNSET) + for componentsschemas_core_events_item_data in _events or []: + componentsschemas_core_events_item = CoreEvent.from_dict( + componentsschemas_core_events_item_data + ) + + events.append(componentsschemas_core_events_item) + + status = d.pop("status", UNSET) + + application = cls( + metadata=metadata, + spec=spec, + events=events, + status=status, + ) + + application.additional_properties = d + return application + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/application_list.py b/src/blaxel/core/client/models/application_list.py new file mode 100644 index 00000000..c6ed52a1 --- /dev/null +++ b/src/blaxel/core/client/models/application_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.application import Application + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="ApplicationList") + + +@_attrs_define +class ApplicationList: + """Cursor-paginated list of applications. Returned starting with API version 2026-04-28; older API versions return a + bare array of applications instead. + + Attributes: + data (Union[Unset, list['Application']]): Page of applications. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Application"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.application import Application + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Application.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + application_list = cls( + data=data, + meta=meta, + ) + + application_list.additional_properties = d + return application_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/application_spec.py b/src/blaxel/core/client/models/application_spec.py new file mode 100644 index 00000000..a6698edd --- /dev/null +++ b/src/blaxel/core/client/models/application_spec.py @@ -0,0 +1,154 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.app_revision import AppRevision + from ..models.app_revision_configuration import AppRevisionConfiguration + from ..models.app_url import AppUrl + + +T = TypeVar("T", bound="ApplicationSpec") + + +@_attrs_define +class ApplicationSpec: + """Configuration for an application including revision management, URL routing, and deployment region + + Attributes: + enabled (Union[Unset, bool]): When false, the application is disabled and will not serve requests Default: True. + Example: True. + region (Union[Unset, str]): Region where the application is deployed (e.g. us-pdx-1, eu-lon-1) Example: us- + pdx-1. + revision (Union[Unset, AppRevisionConfiguration]): Routing configuration controlling which revision is active + and canary traffic splitting + revisions (Union[Unset, list['AppRevision']]): + urls (Union[Unset, list['AppUrl']]): URL configuration for the application. Each entry defines a custom URL + through which the application is accessible. The domain must be a verified custom domain in the workspace. + """ + + enabled: Union[Unset, bool] = True + region: Union[Unset, str] = UNSET + revision: Union[Unset, "AppRevisionConfiguration"] = UNSET + revisions: Union[Unset, list["AppRevision"]] = UNSET + urls: Union[Unset, list["AppUrl"]] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + enabled = self.enabled + + region = self.region + + revision: Union[Unset, dict[str, Any]] = UNSET + if ( + self.revision + and not isinstance(self.revision, Unset) + and not isinstance(self.revision, dict) + ): + revision = self.revision.to_dict() + elif self.revision and isinstance(self.revision, dict): + revision = self.revision + + revisions: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.revisions, Unset): + revisions = [] + for componentsschemas_app_revisions_item_data in self.revisions: + if type(componentsschemas_app_revisions_item_data) is dict: + componentsschemas_app_revisions_item = componentsschemas_app_revisions_item_data + else: + componentsschemas_app_revisions_item = ( + componentsschemas_app_revisions_item_data.to_dict() + ) + revisions.append(componentsschemas_app_revisions_item) + + urls: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.urls, Unset): + urls = [] + for componentsschemas_app_urls_item_data in self.urls: + if type(componentsschemas_app_urls_item_data) is dict: + componentsschemas_app_urls_item = componentsschemas_app_urls_item_data + else: + componentsschemas_app_urls_item = componentsschemas_app_urls_item_data.to_dict() + urls.append(componentsschemas_app_urls_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if enabled is not UNSET: + field_dict["enabled"] = enabled + if region is not UNSET: + field_dict["region"] = region + if revision is not UNSET: + field_dict["revision"] = revision + if revisions is not UNSET: + field_dict["revisions"] = revisions + if urls is not UNSET: + field_dict["urls"] = urls + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.app_revision import AppRevision + from ..models.app_revision_configuration import AppRevisionConfiguration + from ..models.app_url import AppUrl + + if not src_dict: + return None + d = src_dict.copy() + enabled = d.pop("enabled", UNSET) + + region = d.pop("region", UNSET) + + _revision = d.pop("revision", UNSET) + revision: Union[Unset, AppRevisionConfiguration] + if isinstance(_revision, Unset): + revision = UNSET + else: + revision = AppRevisionConfiguration.from_dict(_revision) + + revisions = [] + _revisions = d.pop("revisions", UNSET) + for componentsschemas_app_revisions_item_data in _revisions or []: + componentsschemas_app_revisions_item = AppRevision.from_dict( + componentsschemas_app_revisions_item_data + ) + + revisions.append(componentsschemas_app_revisions_item) + + urls = [] + _urls = d.pop("urls", UNSET) + for componentsschemas_app_urls_item_data in _urls or []: + componentsschemas_app_urls_item = AppUrl.from_dict(componentsschemas_app_urls_item_data) + + urls.append(componentsschemas_app_urls_item) + + application_spec = cls( + enabled=enabled, + region=region, + revision=revision, + revisions=revisions, + urls=urls, + ) + + application_spec.additional_properties = d + return application_spec + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/configuration.py b/src/blaxel/core/client/models/configuration.py index d0eec18b..9cd989f1 100644 --- a/src/blaxel/core/client/models/configuration.py +++ b/src/blaxel/core/client/models/configuration.py @@ -22,18 +22,20 @@ class Configuration: Attributes: continents (Union[Unset, list['Continent']]): Continents countries (Union[Unset, list['Country']]): Countries + detected_region (Union[Unset, str]): Auto-detected closest region based on viewer geolocation (from CloudFront + headers). Empty when geo headers are not available. private_locations (Union[Unset, list['PrivateLocation']]): Private locations managed with blaxel operator regions (Union[Unset, list['Region']]): Regions """ continents: Union[Unset, list["Continent"]] = UNSET countries: Union[Unset, list["Country"]] = UNSET + detected_region: Union[Unset, str] = UNSET private_locations: Union[Unset, list["PrivateLocation"]] = UNSET regions: Union[Unset, list["Region"]] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - continents: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.continents, Unset): continents = [] @@ -54,6 +56,8 @@ def to_dict(self) -> dict[str, Any]: countries_item = countries_item_data.to_dict() countries.append(countries_item) + detected_region = self.detected_region + private_locations: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.private_locations, Unset): private_locations = [] @@ -81,6 +85,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["continents"] = continents if countries is not UNSET: field_dict["countries"] = countries + if detected_region is not UNSET: + field_dict["detectedRegion"] = detected_region if private_locations is not UNSET: field_dict["privateLocations"] = private_locations if regions is not UNSET: @@ -112,6 +118,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: countries.append(countries_item) + detected_region = d.pop("detectedRegion", d.pop("detected_region", UNSET)) + private_locations = [] _private_locations = d.pop("privateLocations", d.pop("private_locations", UNSET)) for private_locations_item_data in _private_locations or []: @@ -129,6 +137,7 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: configuration = cls( continents=continents, countries=countries, + detected_region=detected_region, private_locations=private_locations, regions=regions, ) diff --git a/src/blaxel/core/client/models/create_job_execution_output.py b/src/blaxel/core/client/models/create_job_execution_output.py index ab7e2203..7d31cab9 100644 --- a/src/blaxel/core/client/models/create_job_execution_output.py +++ b/src/blaxel/core/client/models/create_job_execution_output.py @@ -37,7 +37,6 @@ class CreateJobExecutionOutput: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - execution_id = self.execution_id id = self.id diff --git a/src/blaxel/core/client/models/create_job_execution_request.py b/src/blaxel/core/client/models/create_job_execution_request.py index 110a3a1b..7ec4f73a 100644 --- a/src/blaxel/core/client/models/create_job_execution_request.py +++ b/src/blaxel/core/client/models/create_job_execution_request.py @@ -40,7 +40,6 @@ class CreateJobExecutionRequest: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - env: Union[Unset, dict[str, Any]] = UNSET if self.env and not isinstance(self.env, Unset) and not isinstance(self.env, dict): env = self.env.to_dict() diff --git a/src/blaxel/core/client/models/custom_domain.py b/src/blaxel/core/client/models/custom_domain.py index fe1fa967..6b17e9ab 100644 --- a/src/blaxel/core/client/models/custom_domain.py +++ b/src/blaxel/core/client/models/custom_domain.py @@ -28,7 +28,6 @@ class CustomDomain: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/custom_domain_metadata.py b/src/blaxel/core/client/models/custom_domain_metadata.py index ae0506f3..1b354e48 100644 --- a/src/blaxel/core/client/models/custom_domain_metadata.py +++ b/src/blaxel/core/client/models/custom_domain_metadata.py @@ -39,7 +39,6 @@ class CustomDomainMetadata: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - created_at = self.created_at updated_at = self.updated_at diff --git a/src/blaxel/core/client/models/custom_domain_spec.py b/src/blaxel/core/client/models/custom_domain_spec.py index 03116ca3..cb59ccb8 100644 --- a/src/blaxel/core/client/models/custom_domain_spec.py +++ b/src/blaxel/core/client/models/custom_domain_spec.py @@ -8,6 +8,7 @@ if TYPE_CHECKING: from ..models.custom_domain_spec_txt_records import CustomDomainSpecTxtRecords + from ..models.custom_domain_subdomain import CustomDomainSubdomain T = TypeVar("T", bound="CustomDomainSpec") @@ -19,27 +20,34 @@ class CustomDomainSpec: Attributes: cname_records (Union[Unset, str]): CNAME target for the domain + fallback_preview_id (Union[Unset, str]): Preview ID to route to when a preview lookup fails on this custom + domain Example: my-fallback-preview. last_verified_at (Union[Unset, str]): Last verification attempt timestamp region (Union[Unset, str]): Region that the custom domain is associated with Example: us-pdx-1. status (Union[Unset, CustomDomainSpecStatus]): Current status of the domain (pending, verified, failed) Example: verified. + subdomains (Union[Unset, list['CustomDomainSubdomain']]): List of subdomains (previews) currently using this + custom domain. Only populated on GET /customdomains/{domainName}. txt_records (Union[Unset, CustomDomainSpecTxtRecords]): Map of TXT record names to values for domain verification verification_error (Union[Unset, str]): Error message if verification failed """ cname_records: Union[Unset, str] = UNSET + fallback_preview_id: Union[Unset, str] = UNSET last_verified_at: Union[Unset, str] = UNSET region: Union[Unset, str] = UNSET status: Union[Unset, CustomDomainSpecStatus] = UNSET + subdomains: Union[Unset, list["CustomDomainSubdomain"]] = UNSET txt_records: Union[Unset, "CustomDomainSpecTxtRecords"] = UNSET verification_error: Union[Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - cname_records = self.cname_records + fallback_preview_id = self.fallback_preview_id + last_verified_at = self.last_verified_at region = self.region @@ -48,6 +56,16 @@ def to_dict(self) -> dict[str, Any]: if not isinstance(self.status, Unset): status = self.status.value + subdomains: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.subdomains, Unset): + subdomains = [] + for subdomains_item_data in self.subdomains: + if type(subdomains_item_data) is dict: + subdomains_item = subdomains_item_data + else: + subdomains_item = subdomains_item_data.to_dict() + subdomains.append(subdomains_item) + txt_records: Union[Unset, dict[str, Any]] = UNSET if ( self.txt_records @@ -65,12 +83,16 @@ def to_dict(self) -> dict[str, Any]: field_dict.update({}) if cname_records is not UNSET: field_dict["cnameRecords"] = cname_records + if fallback_preview_id is not UNSET: + field_dict["fallbackPreviewId"] = fallback_preview_id if last_verified_at is not UNSET: field_dict["lastVerifiedAt"] = last_verified_at if region is not UNSET: field_dict["region"] = region if status is not UNSET: field_dict["status"] = status + if subdomains is not UNSET: + field_dict["subdomains"] = subdomains if txt_records is not UNSET: field_dict["txtRecords"] = txt_records if verification_error is not UNSET: @@ -81,12 +103,15 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: from ..models.custom_domain_spec_txt_records import CustomDomainSpecTxtRecords + from ..models.custom_domain_subdomain import CustomDomainSubdomain if not src_dict: return None d = src_dict.copy() cname_records = d.pop("cnameRecords", d.pop("cname_records", UNSET)) + fallback_preview_id = d.pop("fallbackPreviewId", d.pop("fallback_preview_id", UNSET)) + last_verified_at = d.pop("lastVerifiedAt", d.pop("last_verified_at", UNSET)) region = d.pop("region", UNSET) @@ -98,6 +123,13 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: else: status = CustomDomainSpecStatus(_status) + subdomains = [] + _subdomains = d.pop("subdomains", UNSET) + for subdomains_item_data in _subdomains or []: + subdomains_item = CustomDomainSubdomain.from_dict(subdomains_item_data) + + subdomains.append(subdomains_item) + _txt_records = d.pop("txtRecords", d.pop("txt_records", UNSET)) txt_records: Union[Unset, CustomDomainSpecTxtRecords] if isinstance(_txt_records, Unset): @@ -109,9 +141,11 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: custom_domain_spec = cls( cname_records=cname_records, + fallback_preview_id=fallback_preview_id, last_verified_at=last_verified_at, region=region, status=status, + subdomains=subdomains, txt_records=txt_records, verification_error=verification_error, ) diff --git a/src/blaxel/core/client/models/custom_domain_subdomain.py b/src/blaxel/core/client/models/custom_domain_subdomain.py new file mode 100644 index 00000000..aaf35848 --- /dev/null +++ b/src/blaxel/core/client/models/custom_domain_subdomain.py @@ -0,0 +1,97 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CustomDomainSubdomain") + + +@_attrs_define +class CustomDomainSubdomain: + """A subdomain (preview) using a custom domain + + Attributes: + preview_name (Union[Unset, str]): Preview name + resource_name (Union[Unset, str]): Resource name + resource_type (Union[Unset, str]): Resource type (e.g., sandbox) + subdomain (Union[Unset, str]): Subdomain prefix used for routing + url (Union[Unset, str]): Full URL of the preview on this custom domain + """ + + preview_name: Union[Unset, str] = UNSET + resource_name: Union[Unset, str] = UNSET + resource_type: Union[Unset, str] = UNSET + subdomain: Union[Unset, str] = UNSET + url: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + preview_name = self.preview_name + + resource_name = self.resource_name + + resource_type = self.resource_type + + subdomain = self.subdomain + + url = self.url + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if preview_name is not UNSET: + field_dict["previewName"] = preview_name + if resource_name is not UNSET: + field_dict["resourceName"] = resource_name + if resource_type is not UNSET: + field_dict["resourceType"] = resource_type + if subdomain is not UNSET: + field_dict["subdomain"] = subdomain + if url is not UNSET: + field_dict["url"] = url + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + preview_name = d.pop("previewName", d.pop("preview_name", UNSET)) + + resource_name = d.pop("resourceName", d.pop("resource_name", UNSET)) + + resource_type = d.pop("resourceType", d.pop("resource_type", UNSET)) + + subdomain = d.pop("subdomain", UNSET) + + url = d.pop("url", UNSET) + + custom_domain_subdomain = cls( + preview_name=preview_name, + resource_name=resource_name, + resource_type=resource_type, + subdomain=subdomain, + url=url, + ) + + custom_domain_subdomain.additional_properties = d + return custom_domain_subdomain + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/delete_volume_template_version_response_200.py b/src/blaxel/core/client/models/delete_volume_template_version_response_200.py index 5a8cf60e..c7d99aee 100644 --- a/src/blaxel/core/client/models/delete_volume_template_version_response_200.py +++ b/src/blaxel/core/client/models/delete_volume_template_version_response_200.py @@ -25,7 +25,6 @@ class DeleteVolumeTemplateVersionResponse200: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - message = self.message template: Union[Unset, dict[str, Any]] = UNSET diff --git a/src/blaxel/core/client/models/drive.py b/src/blaxel/core/client/models/drive.py index aead16e7..9367391e 100644 --- a/src/blaxel/core/client/models/drive.py +++ b/src/blaxel/core/client/models/drive.py @@ -37,7 +37,6 @@ class Drive: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/drive_list.py b/src/blaxel/core/client/models/drive_list.py new file mode 100644 index 00000000..d538467e --- /dev/null +++ b/src/blaxel/core/client/models/drive_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.drive import Drive + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="DriveList") + + +@_attrs_define +class DriveList: + """Cursor-paginated list of drives. Returned starting with API version 2026-04-28; older API versions return a bare + array. + + Attributes: + data (Union[Unset, list['Drive']]): Page of drives. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Drive"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.drive import Drive + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Drive.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + drive_list = cls( + data=data, + meta=meta, + ) + + drive_list.additional_properties = d + return drive_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/egress_config.py b/src/blaxel/core/client/models/egress_config.py index 98a2603b..256fdd21 100644 --- a/src/blaxel/core/client/models/egress_config.py +++ b/src/blaxel/core/client/models/egress_config.py @@ -29,7 +29,6 @@ class EgressConfig: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - gateway = self.gateway mode = self.mode diff --git a/src/blaxel/core/client/models/egress_gateway.py b/src/blaxel/core/client/models/egress_gateway.py index 4cf8db08..cf6cfb23 100644 --- a/src/blaxel/core/client/models/egress_gateway.py +++ b/src/blaxel/core/client/models/egress_gateway.py @@ -34,7 +34,6 @@ class EgressGateway: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/egress_gateway_usage.py b/src/blaxel/core/client/models/egress_gateway_usage.py new file mode 100644 index 00000000..2db6c6ee --- /dev/null +++ b/src/blaxel/core/client/models/egress_gateway_usage.py @@ -0,0 +1,56 @@ +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="EgressGatewayUsage") + + +@_attrs_define +class EgressGatewayUsage: + """Sandboxes currently bound to each egress gateway. Returned by GET /egressgateways/usage so the egress-IPs UI can + render attachment counts without fetching the sandboxes listing full. Keys are gateway names; values are sandbox + names. + + """ + + additional_properties: dict[str, list[str]] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + for prop_name, prop in self.additional_properties.items(): + field_dict[prop_name] = prop + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + egress_gateway_usage = cls() + + additional_properties = {} + for prop_name, prop_dict in d.items(): + additional_property = cast(list[str], prop_dict) + + additional_properties[prop_name] = additional_property + + egress_gateway_usage.additional_properties = additional_properties + return egress_gateway_usage + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> list[str]: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: list[str]) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/egress_ip.py b/src/blaxel/core/client/models/egress_ip.py index e8542d77..92fca87c 100644 --- a/src/blaxel/core/client/models/egress_ip.py +++ b/src/blaxel/core/client/models/egress_ip.py @@ -33,7 +33,6 @@ class EgressIP: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/entrypoint.py b/src/blaxel/core/client/models/entrypoint.py index 9188c712..f56e3db8 100644 --- a/src/blaxel/core/client/models/entrypoint.py +++ b/src/blaxel/core/client/models/entrypoint.py @@ -32,7 +32,6 @@ class Entrypoint: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - args: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.args, Unset): args = [] diff --git a/src/blaxel/core/client/models/firewall_config.py b/src/blaxel/core/client/models/firewall_config.py new file mode 100644 index 00000000..505ab664 --- /dev/null +++ b/src/blaxel/core/client/models/firewall_config.py @@ -0,0 +1,66 @@ +from typing import Any, TypeVar, Union, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="FirewallConfig") + + +@_attrs_define +class FirewallConfig: + """Firewall configuration specifying which network lockdown rulesets to apply. Valid rulesets are "default" (no-op), + "proxy" (restrict egress to proxy), and "dedicated-ip" (restrict egress to dedicated IP gateway). + + Attributes: + rulesets (Union[Unset, list[str]]): List of firewall rulesets to apply. Valid values: "default" (no-op), "proxy" + (restrict egress to proxy), "dedicated-ip" (restrict egress to dedicated IP gateway). Example: ["proxy", + "dedicated-ip"]. + """ + + rulesets: Union[Unset, list[str]] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + rulesets: Union[Unset, list[str]] = UNSET + if not isinstance(self.rulesets, Unset): + rulesets = self.rulesets + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if rulesets is not UNSET: + field_dict["rulesets"] = rulesets + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + rulesets = cast(list[str], d.pop("rulesets", UNSET)) + + firewall_config = cls( + rulesets=rulesets, + ) + + firewall_config.additional_properties = d + return firewall_config + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/form.py b/src/blaxel/core/client/models/form.py index 6486251b..e55e8722 100644 --- a/src/blaxel/core/client/models/form.py +++ b/src/blaxel/core/client/models/form.py @@ -30,7 +30,6 @@ class Form: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - config: Union[Unset, dict[str, Any]] = UNSET if self.config and not isinstance(self.config, Unset) and not isinstance(self.config, dict): config = self.config.to_dict() diff --git a/src/blaxel/core/client/models/function.py b/src/blaxel/core/client/models/function.py index b3d16028..fd2528b4 100644 --- a/src/blaxel/core/client/models/function.py +++ b/src/blaxel/core/client/models/function.py @@ -36,7 +36,6 @@ class Function: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/function_list.py b/src/blaxel/core/client/models/function_list.py new file mode 100644 index 00000000..09c60964 --- /dev/null +++ b/src/blaxel/core/client/models/function_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.function import Function + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="FunctionList") + + +@_attrs_define +class FunctionList: + """Cursor-paginated list of MCP server functions. Returned starting with API version 2026-04-28; older API versions + return a bare array. + + Attributes: + data (Union[Unset, list['Function']]): Page of functions. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Function"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.function import Function + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Function.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + function_list = cls( + data=data, + meta=meta, + ) + + function_list.additional_properties = d + return function_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/function_runtime.py b/src/blaxel/core/client/models/function_runtime.py index 9e2623ab..3b9891e0 100644 --- a/src/blaxel/core/client/models/function_runtime.py +++ b/src/blaxel/core/client/models/function_runtime.py @@ -44,7 +44,6 @@ class FunctionRuntime: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - envs: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.envs, Unset): envs = [] diff --git a/src/blaxel/core/client/models/function_spec.py b/src/blaxel/core/client/models/function_spec.py index 21cc973d..b28bb432 100644 --- a/src/blaxel/core/client/models/function_spec.py +++ b/src/blaxel/core/client/models/function_spec.py @@ -44,7 +44,6 @@ class FunctionSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled integration_connections: Union[Unset, list[str]] = UNSET diff --git a/src/blaxel/core/client/models/get_drive_jwks_response_200.py b/src/blaxel/core/client/models/get_drive_jwks_response_200.py index 261bfe78..8e429369 100644 --- a/src/blaxel/core/client/models/get_drive_jwks_response_200.py +++ b/src/blaxel/core/client/models/get_drive_jwks_response_200.py @@ -23,7 +23,6 @@ class GetDriveJWKSResponse200: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - keys: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.keys, Unset): keys = [] diff --git a/src/blaxel/core/client/models/get_workspace_features_response_200.py b/src/blaxel/core/client/models/get_workspace_features_response_200.py index ef225b64..e2818c60 100644 --- a/src/blaxel/core/client/models/get_workspace_features_response_200.py +++ b/src/blaxel/core/client/models/get_workspace_features_response_200.py @@ -26,7 +26,6 @@ class GetWorkspaceFeaturesResponse200: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - features: Union[Unset, dict[str, Any]] = UNSET if ( self.features diff --git a/src/blaxel/core/client/models/image.py b/src/blaxel/core/client/models/image.py index 98e25bb5..2132b76c 100644 --- a/src/blaxel/core/client/models/image.py +++ b/src/blaxel/core/client/models/image.py @@ -24,7 +24,6 @@ class Image: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/image_metadata.py b/src/blaxel/core/client/models/image_metadata.py index a33148d8..c8b15521 100644 --- a/src/blaxel/core/client/models/image_metadata.py +++ b/src/blaxel/core/client/models/image_metadata.py @@ -44,7 +44,6 @@ class ImageMetadata: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - created_at = self.created_at display_name = self.display_name diff --git a/src/blaxel/core/client/models/image_spec.py b/src/blaxel/core/client/models/image_spec.py index 34225801..ff47facf 100644 --- a/src/blaxel/core/client/models/image_spec.py +++ b/src/blaxel/core/client/models/image_spec.py @@ -25,7 +25,6 @@ class ImageSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - size = self.size tags: Union[Unset, list[dict[str, Any]]] = UNSET diff --git a/src/blaxel/core/client/models/integration.py b/src/blaxel/core/client/models/integration.py index 57108161..b893983c 100644 --- a/src/blaxel/core/client/models/integration.py +++ b/src/blaxel/core/client/models/integration.py @@ -41,7 +41,6 @@ class Integration: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - additional_infos: Union[Unset, dict[str, Any]] = UNSET if ( self.additional_infos diff --git a/src/blaxel/core/client/models/integration_connection.py b/src/blaxel/core/client/models/integration_connection.py index 0ed7f358..ba41b5fc 100644 --- a/src/blaxel/core/client/models/integration_connection.py +++ b/src/blaxel/core/client/models/integration_connection.py @@ -28,7 +28,6 @@ class IntegrationConnection: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/integration_connection_spec.py b/src/blaxel/core/client/models/integration_connection_spec.py index 27c6d86b..2f42e019 100644 --- a/src/blaxel/core/client/models/integration_connection_spec.py +++ b/src/blaxel/core/client/models/integration_connection_spec.py @@ -34,7 +34,6 @@ class IntegrationConnectionSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - config: Union[Unset, dict[str, Any]] = UNSET if self.config and not isinstance(self.config, Unset) and not isinstance(self.config, dict): config = self.config.to_dict() diff --git a/src/blaxel/core/client/models/integration_endpoint.py b/src/blaxel/core/client/models/integration_endpoint.py index ade0dae2..d1c9fea6 100644 --- a/src/blaxel/core/client/models/integration_endpoint.py +++ b/src/blaxel/core/client/models/integration_endpoint.py @@ -38,7 +38,6 @@ class IntegrationEndpoint: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - body = self.body ignore_models: Union[Unset, list[dict[str, Any]]] = UNSET diff --git a/src/blaxel/core/client/models/integration_endpoints.py b/src/blaxel/core/client/models/integration_endpoints.py index 76c5b99a..61fb17b5 100644 --- a/src/blaxel/core/client/models/integration_endpoints.py +++ b/src/blaxel/core/client/models/integration_endpoints.py @@ -17,7 +17,6 @@ class IntegrationEndpoints: additional_properties: dict[str, "IntegrationEndpoint"] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} for prop_name, prop in self.additional_properties.items(): if type(prop) is dict: @@ -36,7 +35,6 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: d = src_dict.copy() integration_endpoints = cls() - additional_properties = {} for prop_name, prop_dict in d.items(): additional_property = IntegrationEndpoint.from_dict(prop_dict) diff --git a/src/blaxel/core/client/models/job.py b/src/blaxel/core/client/models/job.py index 50901929..04aae372 100644 --- a/src/blaxel/core/client/models/job.py +++ b/src/blaxel/core/client/models/job.py @@ -36,7 +36,6 @@ class Job: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/job_execution.py b/src/blaxel/core/client/models/job_execution.py index 4bae77c9..1710452c 100644 --- a/src/blaxel/core/client/models/job_execution.py +++ b/src/blaxel/core/client/models/job_execution.py @@ -36,7 +36,6 @@ class JobExecution: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/job_execution_list.py b/src/blaxel/core/client/models/job_execution_list.py new file mode 100644 index 00000000..e2886081 --- /dev/null +++ b/src/blaxel/core/client/models/job_execution_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.job_execution import JobExecution + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="JobExecutionList") + + +@_attrs_define +class JobExecutionList: + """Cursor-paginated list of job executions. Returned starting with API version 2026-04-28; older API versions keep the + legacy offset-based contract and return a bare array. + + Attributes: + data (Union[Unset, list['JobExecution']]): Page of job executions. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["JobExecution"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.job_execution import JobExecution + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = JobExecution.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + job_execution_list = cls( + data=data, + meta=meta, + ) + + job_execution_list.additional_properties = d + return job_execution_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/job_execution_spec.py b/src/blaxel/core/client/models/job_execution_spec.py index f18077f8..c0590774 100644 --- a/src/blaxel/core/client/models/job_execution_spec.py +++ b/src/blaxel/core/client/models/job_execution_spec.py @@ -35,7 +35,6 @@ class JobExecutionSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - env_override: Union[Unset, dict[str, Any]] = UNSET if ( self.env_override diff --git a/src/blaxel/core/client/models/job_execution_task.py b/src/blaxel/core/client/models/job_execution_task.py index b73e476d..f9319086 100644 --- a/src/blaxel/core/client/models/job_execution_task.py +++ b/src/blaxel/core/client/models/job_execution_task.py @@ -33,7 +33,6 @@ class JobExecutionTask: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - conditions: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.conditions, Unset): conditions = [] diff --git a/src/blaxel/core/client/models/job_execution_task_list.py b/src/blaxel/core/client/models/job_execution_task_list.py new file mode 100644 index 00000000..c03678c3 --- /dev/null +++ b/src/blaxel/core/client/models/job_execution_task_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.job_execution_task import JobExecutionTask + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="JobExecutionTaskList") + + +@_attrs_define +class JobExecutionTaskList: + """Cursor-paginated list of an execution's tasks. Tasks are derived from event history; pagination slices the in-memory + list and the cursor is a base64-JSON offset bound to (workspace, job, execution). + + Attributes: + data (Union[Unset, list['JobExecutionTask']]): Page of execution tasks. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["JobExecutionTask"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.job_execution_task import JobExecutionTask + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = JobExecutionTask.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + job_execution_task_list = cls( + data=data, + meta=meta, + ) + + job_execution_task_list.additional_properties = d + return job_execution_task_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/job_list.py b/src/blaxel/core/client/models/job_list.py new file mode 100644 index 00000000..96007c31 --- /dev/null +++ b/src/blaxel/core/client/models/job_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.job import Job + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="JobList") + + +@_attrs_define +class JobList: + """Cursor-paginated list of batch jobs. Returned starting with API version 2026-04-28; older API versions return a bare + array. + + Attributes: + data (Union[Unset, list['Job']]): Page of jobs. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Job"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.job import Job + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Job.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + job_list = cls( + data=data, + meta=meta, + ) + + job_list.additional_properties = d + return job_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/job_runtime.py b/src/blaxel/core/client/models/job_runtime.py index 83c418ed..299e2c3f 100644 --- a/src/blaxel/core/client/models/job_runtime.py +++ b/src/blaxel/core/client/models/job_runtime.py @@ -46,7 +46,6 @@ class JobRuntime: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - disk_percent = self.disk_percent envs: Union[Unset, list[dict[str, Any]]] = UNSET diff --git a/src/blaxel/core/client/models/job_spec.py b/src/blaxel/core/client/models/job_spec.py index c7b55d42..51ef6255 100644 --- a/src/blaxel/core/client/models/job_spec.py +++ b/src/blaxel/core/client/models/job_spec.py @@ -46,7 +46,6 @@ class JobSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled github_runner: Union[Unset, dict[str, Any]] = UNSET diff --git a/src/blaxel/core/client/models/list_agents_anchor.py b/src/blaxel/core/client/models/list_agents_anchor.py new file mode 100644 index 00000000..f423e8fd --- /dev/null +++ b/src/blaxel/core/client/models/list_agents_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListAgentsAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListAgentsAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_agents_sort.py b/src/blaxel/core/client/models/list_agents_sort.py new file mode 100644 index 00000000..639624c5 --- /dev/null +++ b/src/blaxel/core/client/models/list_agents_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListAgentsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListAgentsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_applications_anchor.py b/src/blaxel/core/client/models/list_applications_anchor.py new file mode 100644 index 00000000..7ee504a8 --- /dev/null +++ b/src/blaxel/core/client/models/list_applications_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListApplicationsAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListApplicationsAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_applications_sort.py b/src/blaxel/core/client/models/list_applications_sort.py new file mode 100644 index 00000000..eefa1c38 --- /dev/null +++ b/src/blaxel/core/client/models/list_applications_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListApplicationsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListApplicationsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_drives_anchor.py b/src/blaxel/core/client/models/list_drives_anchor.py new file mode 100644 index 00000000..341cb04f --- /dev/null +++ b/src/blaxel/core/client/models/list_drives_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListDrivesAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListDrivesAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_drives_sort.py b/src/blaxel/core/client/models/list_drives_sort.py new file mode 100644 index 00000000..19ff48d0 --- /dev/null +++ b/src/blaxel/core/client/models/list_drives_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListDrivesSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListDrivesSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_functions_anchor.py b/src/blaxel/core/client/models/list_functions_anchor.py new file mode 100644 index 00000000..9dfcff01 --- /dev/null +++ b/src/blaxel/core/client/models/list_functions_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListFunctionsAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListFunctionsAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_functions_sort.py b/src/blaxel/core/client/models/list_functions_sort.py new file mode 100644 index 00000000..a5923dad --- /dev/null +++ b/src/blaxel/core/client/models/list_functions_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListFunctionsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListFunctionsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_job_execution_tasks_sort.py b/src/blaxel/core/client/models/list_job_execution_tasks_sort.py new file mode 100644 index 00000000..00004144 --- /dev/null +++ b/src/blaxel/core/client/models/list_job_execution_tasks_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListJobExecutionTasksSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListJobExecutionTasksSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_job_executions_sort.py b/src/blaxel/core/client/models/list_job_executions_sort.py new file mode 100644 index 00000000..d1e5348c --- /dev/null +++ b/src/blaxel/core/client/models/list_job_executions_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListJobExecutionsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListJobExecutionsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_jobs_anchor.py b/src/blaxel/core/client/models/list_jobs_anchor.py new file mode 100644 index 00000000..5f3dfd40 --- /dev/null +++ b/src/blaxel/core/client/models/list_jobs_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListJobsAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListJobsAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_jobs_sort.py b/src/blaxel/core/client/models/list_jobs_sort.py new file mode 100644 index 00000000..ad85ed14 --- /dev/null +++ b/src/blaxel/core/client/models/list_jobs_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListJobsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListJobsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_models_anchor.py b/src/blaxel/core/client/models/list_models_anchor.py new file mode 100644 index 00000000..2d6badd5 --- /dev/null +++ b/src/blaxel/core/client/models/list_models_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListModelsAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListModelsAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_models_sort.py b/src/blaxel/core/client/models/list_models_sort.py new file mode 100644 index 00000000..693de7b0 --- /dev/null +++ b/src/blaxel/core/client/models/list_models_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListModelsSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListModelsSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_policies_anchor.py b/src/blaxel/core/client/models/list_policies_anchor.py new file mode 100644 index 00000000..db4dd42c --- /dev/null +++ b/src/blaxel/core/client/models/list_policies_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListPoliciesAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListPoliciesAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_policies_sort.py b/src/blaxel/core/client/models/list_policies_sort.py new file mode 100644 index 00000000..8e67357d --- /dev/null +++ b/src/blaxel/core/client/models/list_policies_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListPoliciesSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListPoliciesSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_sandboxes_anchor.py b/src/blaxel/core/client/models/list_sandboxes_anchor.py new file mode 100644 index 00000000..69040061 --- /dev/null +++ b/src/blaxel/core/client/models/list_sandboxes_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListSandboxesAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListSandboxesAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_sandboxes_sort.py b/src/blaxel/core/client/models/list_sandboxes_sort.py new file mode 100644 index 00000000..afd1763e --- /dev/null +++ b/src/blaxel/core/client/models/list_sandboxes_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListSandboxesSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListSandboxesSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_volumes_anchor.py b/src/blaxel/core/client/models/list_volumes_anchor.py new file mode 100644 index 00000000..99950d9d --- /dev/null +++ b/src/blaxel/core/client/models/list_volumes_anchor.py @@ -0,0 +1,17 @@ +from enum import Enum + + +class ListVolumesAnchor(str, Enum): + END = "end" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListVolumesAnchor | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/list_volumes_sort.py b/src/blaxel/core/client/models/list_volumes_sort.py new file mode 100644 index 00000000..1e6581f3 --- /dev/null +++ b/src/blaxel/core/client/models/list_volumes_sort.py @@ -0,0 +1,20 @@ +from enum import Enum + + +class ListVolumesSort(str, Enum): + CREATEDATASC = "createdAt:asc" + CREATEDATDESC = "createdAt:desc" + NAMEASC = "name:asc" + NAMEDESC = "name:desc" + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, value: object) -> "ListVolumesSort | None": + if isinstance(value, str): + upper_value = value.upper() + for member in cls: + if member.value.upper() == upper_value: + return member + return None diff --git a/src/blaxel/core/client/models/lite_volume.py b/src/blaxel/core/client/models/lite_volume.py new file mode 100644 index 00000000..8ce469f3 --- /dev/null +++ b/src/blaxel/core/client/models/lite_volume.py @@ -0,0 +1,138 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.lite_volume_metadata import LiteVolumeMetadata + from ..models.lite_volume_spec import LiteVolumeSpec + from ..models.volume_state import VolumeState + + +T = TypeVar("T", bound="LiteVolume") + + +@_attrs_define +class LiteVolume: + """LiteVolume is the listing-shape projection of a Volume. Drops events to keep page payloads small. + + Attributes: + metadata (Union[Unset, LiteVolumeMetadata]): Compact metadata for a Volume, returned in listing responses. + spec (Union[Unset, LiteVolumeSpec]): Compact spec for a Volume, returned in listing responses. + state (Union[Unset, VolumeState]): Current runtime state of the volume including attachment status + status (Union[Unset, str]): Computed status of the volume. + terminated_at (Union[Unset, str]): Termination timestamp for soft-deleted volumes. + """ + + metadata: Union[Unset, "LiteVolumeMetadata"] = UNSET + spec: Union[Unset, "LiteVolumeSpec"] = UNSET + state: Union[Unset, "VolumeState"] = UNSET + status: Union[Unset, str] = UNSET + terminated_at: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + metadata: Union[Unset, dict[str, Any]] = UNSET + if ( + self.metadata + and not isinstance(self.metadata, Unset) + and not isinstance(self.metadata, dict) + ): + metadata = self.metadata.to_dict() + elif self.metadata and isinstance(self.metadata, dict): + metadata = self.metadata + + spec: Union[Unset, dict[str, Any]] = UNSET + if self.spec and not isinstance(self.spec, Unset) and not isinstance(self.spec, dict): + spec = self.spec.to_dict() + elif self.spec and isinstance(self.spec, dict): + spec = self.spec + + state: Union[Unset, dict[str, Any]] = UNSET + if self.state and not isinstance(self.state, Unset) and not isinstance(self.state, dict): + state = self.state.to_dict() + elif self.state and isinstance(self.state, dict): + state = self.state + + status = self.status + + terminated_at = self.terminated_at + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if metadata is not UNSET: + field_dict["metadata"] = metadata + if spec is not UNSET: + field_dict["spec"] = spec + if state is not UNSET: + field_dict["state"] = state + if status is not UNSET: + field_dict["status"] = status + if terminated_at is not UNSET: + field_dict["terminatedAt"] = terminated_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.lite_volume_metadata import LiteVolumeMetadata + from ..models.lite_volume_spec import LiteVolumeSpec + from ..models.volume_state import VolumeState + + if not src_dict: + return None + d = src_dict.copy() + _metadata = d.pop("metadata", UNSET) + metadata: Union[Unset, LiteVolumeMetadata] + if isinstance(_metadata, Unset): + metadata = UNSET + else: + metadata = LiteVolumeMetadata.from_dict(_metadata) + + _spec = d.pop("spec", UNSET) + spec: Union[Unset, LiteVolumeSpec] + if isinstance(_spec, Unset): + spec = UNSET + else: + spec = LiteVolumeSpec.from_dict(_spec) + + _state = d.pop("state", UNSET) + state: Union[Unset, VolumeState] + if isinstance(_state, Unset): + state = UNSET + else: + state = VolumeState.from_dict(_state) + + status = d.pop("status", UNSET) + + terminated_at = d.pop("terminatedAt", d.pop("terminated_at", UNSET)) + + lite_volume = cls( + metadata=metadata, + spec=spec, + state=state, + status=status, + terminated_at=terminated_at, + ) + + lite_volume.additional_properties = d + return lite_volume + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/lite_volume_metadata.py b/src/blaxel/core/client/models/lite_volume_metadata.py new file mode 100644 index 00000000..08eb8e67 --- /dev/null +++ b/src/blaxel/core/client/models/lite_volume_metadata.py @@ -0,0 +1,88 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="LiteVolumeMetadata") + + +@_attrs_define +class LiteVolumeMetadata: + """Compact metadata for a Volume, returned in listing responses. + + Attributes: + created_at (Union[Unset, str]): + display_name (Union[Unset, str]): + name (Union[Unset, str]): + updated_at (Union[Unset, str]): + """ + + created_at: Union[Unset, str] = UNSET + display_name: Union[Unset, str] = UNSET + name: Union[Unset, str] = UNSET + updated_at: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + created_at = self.created_at + + display_name = self.display_name + + name = self.name + + updated_at = self.updated_at + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if created_at is not UNSET: + field_dict["createdAt"] = created_at + if display_name is not UNSET: + field_dict["displayName"] = display_name + if name is not UNSET: + field_dict["name"] = name + if updated_at is not UNSET: + field_dict["updatedAt"] = updated_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + created_at = d.pop("createdAt", d.pop("created_at", UNSET)) + + display_name = d.pop("displayName", d.pop("display_name", UNSET)) + + name = d.pop("name", UNSET) + + updated_at = d.pop("updatedAt", d.pop("updated_at", UNSET)) + + lite_volume_metadata = cls( + created_at=created_at, + display_name=display_name, + name=name, + updated_at=updated_at, + ) + + lite_volume_metadata.additional_properties = d + return lite_volume_metadata + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/lite_volume_spec.py b/src/blaxel/core/client/models/lite_volume_spec.py new file mode 100644 index 00000000..685b66cd --- /dev/null +++ b/src/blaxel/core/client/models/lite_volume_spec.py @@ -0,0 +1,70 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="LiteVolumeSpec") + + +@_attrs_define +class LiteVolumeSpec: + """Compact spec for a Volume, returned in listing responses. + + Attributes: + region (Union[Unset, str]): Region the volume is provisioned in. + size (Union[Unset, int]): Volume size in gigabytes. + """ + + region: Union[Unset, str] = UNSET + size: Union[Unset, int] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + region = self.region + + size = self.size + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if region is not UNSET: + field_dict["region"] = region + if size is not UNSET: + field_dict["size"] = size + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + region = d.pop("region", UNSET) + + size = d.pop("size", UNSET) + + lite_volume_spec = cls( + region=region, + size=size, + ) + + lite_volume_spec.additional_properties = d + return lite_volume_spec + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/location_response.py b/src/blaxel/core/client/models/location_response.py index a413cf84..1ba28924 100644 --- a/src/blaxel/core/client/models/location_response.py +++ b/src/blaxel/core/client/models/location_response.py @@ -34,7 +34,6 @@ class LocationResponse: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - continent = self.continent country = self.country diff --git a/src/blaxel/core/client/models/mcp_definition.py b/src/blaxel/core/client/models/mcp_definition.py index bd80c485..b46583e4 100644 --- a/src/blaxel/core/client/models/mcp_definition.py +++ b/src/blaxel/core/client/models/mcp_definition.py @@ -60,7 +60,6 @@ class MCPDefinition: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - created_at = self.created_at updated_at = self.updated_at diff --git a/src/blaxel/core/client/models/metadata.py b/src/blaxel/core/client/models/metadata.py index 96b34e84..1bf488a9 100644 --- a/src/blaxel/core/client/models/metadata.py +++ b/src/blaxel/core/client/models/metadata.py @@ -46,7 +46,6 @@ class Metadata: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - name = self.name created_at = self.created_at diff --git a/src/blaxel/core/client/models/model.py b/src/blaxel/core/client/models/model.py index e7689923..92b6ee53 100644 --- a/src/blaxel/core/client/models/model.py +++ b/src/blaxel/core/client/models/model.py @@ -36,7 +36,6 @@ class Model: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/model_list.py b/src/blaxel/core/client/models/model_list.py new file mode 100644 index 00000000..35084d04 --- /dev/null +++ b/src/blaxel/core/client/models/model_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.model import Model + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="ModelList") + + +@_attrs_define +class ModelList: + """Cursor-paginated list of model gateway endpoints. Returned starting with API version 2026-04-28; older API versions + return a bare array. + + Attributes: + data (Union[Unset, list['Model']]): Page of models. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Model"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.model import Model + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Model.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + model_list = cls( + data=data, + meta=meta, + ) + + model_list.additional_properties = d + return model_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/model_spec.py b/src/blaxel/core/client/models/model_spec.py index c26c2b52..1e053ae1 100644 --- a/src/blaxel/core/client/models/model_spec.py +++ b/src/blaxel/core/client/models/model_spec.py @@ -37,7 +37,6 @@ class ModelSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled flavors: Union[Unset, list[dict[str, Any]]] = UNSET diff --git a/src/blaxel/core/client/models/o_auth.py b/src/blaxel/core/client/models/o_auth.py index ad63ddf8..8965f520 100644 --- a/src/blaxel/core/client/models/o_auth.py +++ b/src/blaxel/core/client/models/o_auth.py @@ -26,7 +26,6 @@ class OAuth: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - scope: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.scope, Unset): scope = [] diff --git a/src/blaxel/core/client/models/pagination_meta.py b/src/blaxel/core/client/models/pagination_meta.py new file mode 100644 index 00000000..a9568bae --- /dev/null +++ b/src/blaxel/core/client/models/pagination_meta.py @@ -0,0 +1,83 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="PaginationMeta") + + +@_attrs_define +class PaginationMeta: + """Pagination metadata returned alongside a page of listing results. Always present on listing endpoints starting with + API version 2026-04-28. + + Attributes: + has_more (Union[Unset, bool]): True when more pages are available beyond the current one. + next_cursor (Union[Unset, str]): Opaque cursor to pass back as the `cursor` query param for the next page. Empty + when there are no more pages. + total (Union[Unset, int]): Total number of items in the workspace, ignoring the current page's filters. Lets the + UI render "page X of Y" without walking the cursor chain. Computed from the hash-only metadata.workspace GSI + count, so search (`q`) does not narrow it. + """ + + has_more: Union[Unset, bool] = UNSET + next_cursor: Union[Unset, str] = UNSET + total: Union[Unset, int] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + has_more = self.has_more + + next_cursor = self.next_cursor + + total = self.total + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if has_more is not UNSET: + field_dict["hasMore"] = has_more + if next_cursor is not UNSET: + field_dict["nextCursor"] = next_cursor + if total is not UNSET: + field_dict["total"] = total + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + has_more = d.pop("hasMore", d.pop("has_more", UNSET)) + + next_cursor = d.pop("nextCursor", d.pop("next_cursor", UNSET)) + + total = d.pop("total", UNSET) + + pagination_meta = cls( + has_more=has_more, + next_cursor=next_cursor, + total=total, + ) + + pagination_meta.additional_properties = d + return pagination_meta + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/pending_invitation_accept.py b/src/blaxel/core/client/models/pending_invitation_accept.py index 845871ad..063b69a7 100644 --- a/src/blaxel/core/client/models/pending_invitation_accept.py +++ b/src/blaxel/core/client/models/pending_invitation_accept.py @@ -27,7 +27,6 @@ class PendingInvitationAccept: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - email = self.email workspace: Union[Unset, dict[str, Any]] = UNSET diff --git a/src/blaxel/core/client/models/pending_invitation_render.py b/src/blaxel/core/client/models/pending_invitation_render.py index 3534130c..213c640a 100644 --- a/src/blaxel/core/client/models/pending_invitation_render.py +++ b/src/blaxel/core/client/models/pending_invitation_render.py @@ -44,7 +44,6 @@ class PendingInvitationRender: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - account: Union[Unset, dict[str, Any]] = UNSET if ( self.account diff --git a/src/blaxel/core/client/models/pending_invitation_workspace_details.py b/src/blaxel/core/client/models/pending_invitation_workspace_details.py index 6ec1525e..be4320b9 100644 --- a/src/blaxel/core/client/models/pending_invitation_workspace_details.py +++ b/src/blaxel/core/client/models/pending_invitation_workspace_details.py @@ -28,7 +28,6 @@ class PendingInvitationWorkspaceDetails: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - emails: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.emails, Unset): emails = [] diff --git a/src/blaxel/core/client/models/policy.py b/src/blaxel/core/client/models/policy.py index 9b913727..4eddf948 100644 --- a/src/blaxel/core/client/models/policy.py +++ b/src/blaxel/core/client/models/policy.py @@ -1,11 +1,14 @@ -from typing import TYPE_CHECKING, Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar, Union from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + if TYPE_CHECKING: from ..models.metadata import Metadata from ..models.policy_spec import PolicySpec + from ..models.policy_usage_counts import PolicyUsageCounts T = TypeVar("T", bound="Policy") @@ -19,14 +22,17 @@ class Policy: metadata (Metadata): Common metadata fields shared by all Blaxel resources including name, labels, timestamps, and ownership information spec (PolicySpec): Policy specification + usage (Union[Unset, PolicyUsageCounts]): Per-resource counts of how many resources reference a policy. Computed + by the policies listing endpoint to avoid client-side fan-out across the agents/models/functions/sandboxes/jobs + listings. """ metadata: "Metadata" spec: "PolicySpec" + usage: Union[Unset, "PolicyUsageCounts"] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: @@ -37,6 +43,12 @@ def to_dict(self) -> dict[str, Any]: else: spec = self.spec.to_dict() + usage: Union[Unset, dict[str, Any]] = UNSET + if self.usage and not isinstance(self.usage, Unset) and not isinstance(self.usage, dict): + usage = self.usage.to_dict() + elif self.usage and isinstance(self.usage, dict): + usage = self.usage + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -45,6 +57,8 @@ def to_dict(self) -> dict[str, Any]: "spec": spec, } ) + if usage is not UNSET: + field_dict["usage"] = usage return field_dict @@ -52,6 +66,7 @@ def to_dict(self) -> dict[str, Any]: def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: from ..models.metadata import Metadata from ..models.policy_spec import PolicySpec + from ..models.policy_usage_counts import PolicyUsageCounts if not src_dict: return None @@ -60,9 +75,17 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: spec = PolicySpec.from_dict(d.pop("spec")) + _usage = d.pop("usage", UNSET) + usage: Union[Unset, PolicyUsageCounts] + if isinstance(_usage, Unset): + usage = UNSET + else: + usage = PolicyUsageCounts.from_dict(_usage) + policy = cls( metadata=metadata, spec=spec, + usage=usage, ) policy.additional_properties = d diff --git a/src/blaxel/core/client/models/policy_list.py b/src/blaxel/core/client/models/policy_list.py new file mode 100644 index 00000000..9f677085 --- /dev/null +++ b/src/blaxel/core/client/models/policy_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.pagination_meta import PaginationMeta + from ..models.policy import Policy + + +T = TypeVar("T", bound="PolicyList") + + +@_attrs_define +class PolicyList: + """Cursor-paginated list of policies. Returned starting with API version 2026-04-28; older API versions return a bare + array. + + Attributes: + data (Union[Unset, list['Policy']]): Page of policies. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Policy"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.pagination_meta import PaginationMeta + from ..models.policy import Policy + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Policy.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + policy_list = cls( + data=data, + meta=meta, + ) + + policy_list.additional_properties = d + return policy_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_resource_type.py b/src/blaxel/core/client/models/policy_resource_type.py index 1b31d72c..28944091 100644 --- a/src/blaxel/core/client/models/policy_resource_type.py +++ b/src/blaxel/core/client/models/policy_resource_type.py @@ -3,6 +3,7 @@ class PolicyResourceType(str, Enum): AGENT = "agent" + APPLICATION = "application" FUNCTION = "function" MODEL = "model" SANDBOX = "sandbox" diff --git a/src/blaxel/core/client/models/policy_spec.py b/src/blaxel/core/client/models/policy_spec.py index 19ad5059..e343e629 100644 --- a/src/blaxel/core/client/models/policy_spec.py +++ b/src/blaxel/core/client/models/policy_spec.py @@ -40,7 +40,6 @@ class PolicySpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - flavors: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.flavors, Unset): flavors = [] diff --git a/src/blaxel/core/client/models/policy_usage_counts.py b/src/blaxel/core/client/models/policy_usage_counts.py new file mode 100644 index 00000000..a9435a08 --- /dev/null +++ b/src/blaxel/core/client/models/policy_usage_counts.py @@ -0,0 +1,98 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="PolicyUsageCounts") + + +@_attrs_define +class PolicyUsageCounts: + """Per-resource counts of how many resources reference a policy. Computed by the policies listing endpoint to avoid + client-side fan-out across the agents/models/functions/sandboxes/jobs listings. + + Attributes: + agents (Union[Unset, int]): + functions (Union[Unset, int]): + jobs (Union[Unset, int]): + models (Union[Unset, int]): + sandboxes (Union[Unset, int]): + """ + + agents: Union[Unset, int] = UNSET + functions: Union[Unset, int] = UNSET + jobs: Union[Unset, int] = UNSET + models: Union[Unset, int] = UNSET + sandboxes: Union[Unset, int] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + agents = self.agents + + functions = self.functions + + jobs = self.jobs + + models = self.models + + sandboxes = self.sandboxes + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if agents is not UNSET: + field_dict["agents"] = agents + if functions is not UNSET: + field_dict["functions"] = functions + if jobs is not UNSET: + field_dict["jobs"] = jobs + if models is not UNSET: + field_dict["models"] = models + if sandboxes is not UNSET: + field_dict["sandboxes"] = sandboxes + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + agents = d.pop("agents", UNSET) + + functions = d.pop("functions", UNSET) + + jobs = d.pop("jobs", UNSET) + + models = d.pop("models", UNSET) + + sandboxes = d.pop("sandboxes", UNSET) + + policy_usage_counts = cls( + agents=agents, + functions=functions, + jobs=jobs, + models=models, + sandboxes=sandboxes, + ) + + policy_usage_counts.additional_properties = d + return policy_usage_counts + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages.py b/src/blaxel/core/client/models/policy_usages.py new file mode 100644 index 00000000..8aea6698 --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages.py @@ -0,0 +1,179 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.policy_usages_agents_item import PolicyUsagesAgentsItem + from ..models.policy_usages_functions_item import PolicyUsagesFunctionsItem + from ..models.policy_usages_jobs_item import PolicyUsagesJobsItem + from ..models.policy_usages_models_item import PolicyUsagesModelsItem + from ..models.policy_usages_sandboxes_item import PolicyUsagesSandboxesItem + + +T = TypeVar("T", bound="PolicyUsages") + + +@_attrs_define +class PolicyUsages: + """Resources currently referencing a policy. Returned by GET /policies/{name}/usages so the policies UI can render + attachments without fetching the agents/models/functions listings full. + + Attributes: + agents (Union[Unset, list['PolicyUsagesAgentsItem']]): Names of agents whose spec.policies contains this policy. + functions (Union[Unset, list['PolicyUsagesFunctionsItem']]): Names of functions whose spec.policies contains + this policy. + jobs (Union[Unset, list['PolicyUsagesJobsItem']]): Names of jobs whose spec.policies contains this policy. + models (Union[Unset, list['PolicyUsagesModelsItem']]): Names of models whose spec.policies contains this policy. + sandboxes (Union[Unset, list['PolicyUsagesSandboxesItem']]): Names of sandboxes whose spec.policies contains + this policy. + """ + + agents: Union[Unset, list["PolicyUsagesAgentsItem"]] = UNSET + functions: Union[Unset, list["PolicyUsagesFunctionsItem"]] = UNSET + jobs: Union[Unset, list["PolicyUsagesJobsItem"]] = UNSET + models: Union[Unset, list["PolicyUsagesModelsItem"]] = UNSET + sandboxes: Union[Unset, list["PolicyUsagesSandboxesItem"]] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + agents: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.agents, Unset): + agents = [] + for agents_item_data in self.agents: + if type(agents_item_data) is dict: + agents_item = agents_item_data + else: + agents_item = agents_item_data.to_dict() + agents.append(agents_item) + + functions: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.functions, Unset): + functions = [] + for functions_item_data in self.functions: + if type(functions_item_data) is dict: + functions_item = functions_item_data + else: + functions_item = functions_item_data.to_dict() + functions.append(functions_item) + + jobs: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.jobs, Unset): + jobs = [] + for jobs_item_data in self.jobs: + if type(jobs_item_data) is dict: + jobs_item = jobs_item_data + else: + jobs_item = jobs_item_data.to_dict() + jobs.append(jobs_item) + + models: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.models, Unset): + models = [] + for models_item_data in self.models: + if type(models_item_data) is dict: + models_item = models_item_data + else: + models_item = models_item_data.to_dict() + models.append(models_item) + + sandboxes: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.sandboxes, Unset): + sandboxes = [] + for sandboxes_item_data in self.sandboxes: + if type(sandboxes_item_data) is dict: + sandboxes_item = sandboxes_item_data + else: + sandboxes_item = sandboxes_item_data.to_dict() + sandboxes.append(sandboxes_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if agents is not UNSET: + field_dict["agents"] = agents + if functions is not UNSET: + field_dict["functions"] = functions + if jobs is not UNSET: + field_dict["jobs"] = jobs + if models is not UNSET: + field_dict["models"] = models + if sandboxes is not UNSET: + field_dict["sandboxes"] = sandboxes + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.policy_usages_agents_item import PolicyUsagesAgentsItem + from ..models.policy_usages_functions_item import PolicyUsagesFunctionsItem + from ..models.policy_usages_jobs_item import PolicyUsagesJobsItem + from ..models.policy_usages_models_item import PolicyUsagesModelsItem + from ..models.policy_usages_sandboxes_item import PolicyUsagesSandboxesItem + + if not src_dict: + return None + d = src_dict.copy() + agents = [] + _agents = d.pop("agents", UNSET) + for agents_item_data in _agents or []: + agents_item = PolicyUsagesAgentsItem.from_dict(agents_item_data) + + agents.append(agents_item) + + functions = [] + _functions = d.pop("functions", UNSET) + for functions_item_data in _functions or []: + functions_item = PolicyUsagesFunctionsItem.from_dict(functions_item_data) + + functions.append(functions_item) + + jobs = [] + _jobs = d.pop("jobs", UNSET) + for jobs_item_data in _jobs or []: + jobs_item = PolicyUsagesJobsItem.from_dict(jobs_item_data) + + jobs.append(jobs_item) + + models = [] + _models = d.pop("models", UNSET) + for models_item_data in _models or []: + models_item = PolicyUsagesModelsItem.from_dict(models_item_data) + + models.append(models_item) + + sandboxes = [] + _sandboxes = d.pop("sandboxes", UNSET) + for sandboxes_item_data in _sandboxes or []: + sandboxes_item = PolicyUsagesSandboxesItem.from_dict(sandboxes_item_data) + + sandboxes.append(sandboxes_item) + + policy_usages = cls( + agents=agents, + functions=functions, + jobs=jobs, + models=models, + sandboxes=sandboxes, + ) + + policy_usages.additional_properties = d + return policy_usages + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages_agents_item.py b/src/blaxel/core/client/models/policy_usages_agents_item.py new file mode 100644 index 00000000..575ef1ea --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages_agents_item.py @@ -0,0 +1,45 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PolicyUsagesAgentsItem") + + +@_attrs_define +class PolicyUsagesAgentsItem: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + policy_usages_agents_item = cls() + + policy_usages_agents_item.additional_properties = d + return policy_usages_agents_item + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages_functions_item.py b/src/blaxel/core/client/models/policy_usages_functions_item.py new file mode 100644 index 00000000..b0bf2753 --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages_functions_item.py @@ -0,0 +1,45 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PolicyUsagesFunctionsItem") + + +@_attrs_define +class PolicyUsagesFunctionsItem: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + policy_usages_functions_item = cls() + + policy_usages_functions_item.additional_properties = d + return policy_usages_functions_item + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages_jobs_item.py b/src/blaxel/core/client/models/policy_usages_jobs_item.py new file mode 100644 index 00000000..f7698c49 --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages_jobs_item.py @@ -0,0 +1,45 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PolicyUsagesJobsItem") + + +@_attrs_define +class PolicyUsagesJobsItem: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + policy_usages_jobs_item = cls() + + policy_usages_jobs_item.additional_properties = d + return policy_usages_jobs_item + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages_models_item.py b/src/blaxel/core/client/models/policy_usages_models_item.py new file mode 100644 index 00000000..fe89c9ba --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages_models_item.py @@ -0,0 +1,45 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PolicyUsagesModelsItem") + + +@_attrs_define +class PolicyUsagesModelsItem: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + policy_usages_models_item = cls() + + policy_usages_models_item.additional_properties = d + return policy_usages_models_item + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/policy_usages_sandboxes_item.py b/src/blaxel/core/client/models/policy_usages_sandboxes_item.py new file mode 100644 index 00000000..a66d42fd --- /dev/null +++ b/src/blaxel/core/client/models/policy_usages_sandboxes_item.py @@ -0,0 +1,45 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PolicyUsagesSandboxesItem") + + +@_attrs_define +class PolicyUsagesSandboxesItem: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + policy_usages_sandboxes_item = cls() + + policy_usages_sandboxes_item.additional_properties = d + return policy_usages_sandboxes_item + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/preview.py b/src/blaxel/core/client/models/preview.py index 38d1601a..bba76417 100644 --- a/src/blaxel/core/client/models/preview.py +++ b/src/blaxel/core/client/models/preview.py @@ -33,7 +33,6 @@ class Preview: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/preview_spec.py b/src/blaxel/core/client/models/preview_spec.py index 2a6d50b2..2f4cbc8a 100644 --- a/src/blaxel/core/client/models/preview_spec.py +++ b/src/blaxel/core/client/models/preview_spec.py @@ -46,7 +46,6 @@ class PreviewSpec: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - custom_domain = self.custom_domain expires = self.expires diff --git a/src/blaxel/core/client/models/preview_token.py b/src/blaxel/core/client/models/preview_token.py index 3ae85791..accc7383 100644 --- a/src/blaxel/core/client/models/preview_token.py +++ b/src/blaxel/core/client/models/preview_token.py @@ -25,7 +25,6 @@ class PreviewToken: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/proxy_config.py b/src/blaxel/core/client/models/proxy_config.py index 6da195db..a79e00b3 100644 --- a/src/blaxel/core/client/models/proxy_config.py +++ b/src/blaxel/core/client/models/proxy_config.py @@ -18,24 +18,39 @@ class ProxyConfig: destination header/body injection Attributes: + allowed_domains (Union[Unset, list[str]]): List of allowed external domains (allowlist). When set, only these + domains are reachable. Supports wildcards (e.g. *.s3.amazonaws.com). Example: ["api.stripe.com", + "api.openai.com", "*.s3.amazonaws.com"]. bypass (Union[Unset, list[str]]): Domains that bypass the proxy entirely via the NO_PROXY directive. Traffic to these destinations goes direct, not through the CONNECT tunnel. Supports wildcards. Note that localhost, private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), 169.254.169.254, .local and .internal are always bypassed by default. Example: ["*.s3.amazonaws.com"]. + forbidden_domains (Union[Unset, list[str]]): List of forbidden external domains (denylist). When set, all + domains except these are reachable. Supports wildcards (e.g. *.malware.com). If both allowedDomains and + forbiddenDomains are set, allowedDomains takes precedence. Example: ["*.malware.com", "evil.example.org"]. routing (Union[Unset, list['ProxyTarget']]): Per-destination routing rules with header/body injection and secrets. Use destinations ["*"] for global rules that apply to all destinations. """ + allowed_domains: Union[Unset, list[str]] = UNSET bypass: Union[Unset, list[str]] = UNSET + forbidden_domains: Union[Unset, list[str]] = UNSET routing: Union[Unset, list["ProxyTarget"]] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + allowed_domains: Union[Unset, list[str]] = UNSET + if not isinstance(self.allowed_domains, Unset): + allowed_domains = self.allowed_domains bypass: Union[Unset, list[str]] = UNSET if not isinstance(self.bypass, Unset): bypass = self.bypass + forbidden_domains: Union[Unset, list[str]] = UNSET + if not isinstance(self.forbidden_domains, Unset): + forbidden_domains = self.forbidden_domains + routing: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.routing, Unset): routing = [] @@ -49,8 +64,12 @@ def to_dict(self) -> dict[str, Any]: field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) + if allowed_domains is not UNSET: + field_dict["allowedDomains"] = allowed_domains if bypass is not UNSET: field_dict["bypass"] = bypass + if forbidden_domains is not UNSET: + field_dict["forbiddenDomains"] = forbidden_domains if routing is not UNSET: field_dict["routing"] = routing @@ -63,8 +82,14 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None d = src_dict.copy() + allowed_domains = cast(list[str], d.pop("allowedDomains", d.pop("allowed_domains", UNSET))) + bypass = cast(list[str], d.pop("bypass", UNSET)) + forbidden_domains = cast( + list[str], d.pop("forbiddenDomains", d.pop("forbidden_domains", UNSET)) + ) + routing = [] _routing = d.pop("routing", UNSET) for routing_item_data in _routing or []: @@ -73,7 +98,9 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: routing.append(routing_item) proxy_config = cls( + allowed_domains=allowed_domains, bypass=bypass, + forbidden_domains=forbidden_domains, routing=routing, ) diff --git a/src/blaxel/core/client/models/proxy_target.py b/src/blaxel/core/client/models/proxy_target.py index 2b08464a..69fae5fb 100644 --- a/src/blaxel/core/client/models/proxy_target.py +++ b/src/blaxel/core/client/models/proxy_target.py @@ -39,7 +39,6 @@ class ProxyTarget: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - body: Union[Unset, dict[str, Any]] = UNSET if self.body and not isinstance(self.body, Unset) and not isinstance(self.body, dict): body = self.body.to_dict() diff --git a/src/blaxel/core/client/models/public_ips.py b/src/blaxel/core/client/models/public_ips.py index 7dae820d..fa7f59a5 100644 --- a/src/blaxel/core/client/models/public_ips.py +++ b/src/blaxel/core/client/models/public_ips.py @@ -17,7 +17,6 @@ class PublicIps: additional_properties: dict[str, "PublicIp"] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} for prop_name, prop in self.additional_properties.items(): if type(prop) is dict: diff --git a/src/blaxel/core/client/models/region.py b/src/blaxel/core/client/models/region.py index 9c193c56..9a2a7eb1 100644 --- a/src/blaxel/core/client/models/region.py +++ b/src/blaxel/core/client/models/region.py @@ -46,7 +46,6 @@ class Region: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - agent_drive_public_url: Union[Unset, dict[str, Any]] = UNSET if ( self.agent_drive_public_url diff --git a/src/blaxel/core/client/models/sandbox.py b/src/blaxel/core/client/models/sandbox.py index 17a0d431..64caf28e 100644 --- a/src/blaxel/core/client/models/sandbox.py +++ b/src/blaxel/core/client/models/sandbox.py @@ -44,7 +44,6 @@ class Sandbox: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/sandbox_definition.py b/src/blaxel/core/client/models/sandbox_definition.py index 5074b15d..4adf930d 100644 --- a/src/blaxel/core/client/models/sandbox_definition.py +++ b/src/blaxel/core/client/models/sandbox_definition.py @@ -53,7 +53,6 @@ class SandboxDefinition: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - categories: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.categories, Unset): categories = [] diff --git a/src/blaxel/core/client/models/sandbox_error.py b/src/blaxel/core/client/models/sandbox_error.py index f73196d4..aa861111 100644 --- a/src/blaxel/core/client/models/sandbox_error.py +++ b/src/blaxel/core/client/models/sandbox_error.py @@ -42,7 +42,6 @@ class SandboxError: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - code = self.code message = self.message diff --git a/src/blaxel/core/client/models/sandbox_lifecycle.py b/src/blaxel/core/client/models/sandbox_lifecycle.py index 45a4c2fd..ea0dfbd3 100644 --- a/src/blaxel/core/client/models/sandbox_lifecycle.py +++ b/src/blaxel/core/client/models/sandbox_lifecycle.py @@ -28,7 +28,6 @@ class SandboxLifecycle: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - expiration_policies: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.expiration_policies, Unset): expiration_policies = [] diff --git a/src/blaxel/core/client/models/sandbox_list.py b/src/blaxel/core/client/models/sandbox_list.py new file mode 100644 index 00000000..a0fc1b36 --- /dev/null +++ b/src/blaxel/core/client/models/sandbox_list.py @@ -0,0 +1,103 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.pagination_meta import PaginationMeta + from ..models.sandbox import Sandbox + + +T = TypeVar("T", bound="SandboxList") + + +@_attrs_define +class SandboxList: + """Cursor-paginated list of sandboxes. Returned starting with API version 2026-04-28; older API versions return a bare + array. + + Attributes: + data (Union[Unset, list['Sandbox']]): Page of sandboxes. Items use the lite shape (no inline event history) to + keep the page payload small, matching the unpaginated response. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["Sandbox"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.pagination_meta import PaginationMeta + from ..models.sandbox import Sandbox + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = Sandbox.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + sandbox_list = cls( + data=data, + meta=meta, + ) + + sandbox_list.additional_properties = d + return sandbox_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/sandbox_network.py b/src/blaxel/core/client/models/sandbox_network.py index 19e337ef..f2da3325 100644 --- a/src/blaxel/core/client/models/sandbox_network.py +++ b/src/blaxel/core/client/models/sandbox_network.py @@ -7,6 +7,7 @@ if TYPE_CHECKING: from ..models.egress_config import EgressConfig + from ..models.firewall_config import FirewallConfig from ..models.proxy_config import ProxyConfig @@ -15,29 +16,35 @@ @_attrs_define class SandboxNetwork: - """Network configuration for a sandbox including domain filtering, egress IP binding, and proxy settings - - Attributes: - allowed_domains (Union[Unset, list[str]]): List of allowed external domains (allowlist). When set, only these - domains are reachable. Supports wildcards (e.g. *.s3.amazonaws.com). Example: ["api.stripe.com", - "api.openai.com", "*.s3.amazonaws.com"]. - egress (Union[Unset, EgressConfig]): Egress configuration for routing sandbox outbound traffic through a - dedicated IP gateway - forbidden_domains (Union[Unset, list[str]]): List of forbidden external domains (denylist). When set, all - domains except these are reachable. Supports wildcards (e.g. *.malware.com). If both allowedDomains and - forbiddenDomains are set, allowedDomains takes precedence. Example: ["*.malware.com", "evil.example.org"]. - proxy (Union[Unset, ProxyConfig]): Proxy configuration for routing sandbox HTTP traffic through the platform - proxy with MITM inspection and per-destination header/body injection + """Network configuration for a sandbox including subnet, firewall rulesets, domain filtering, egress IP binding, and + proxy settings + + Attributes: + allowed_domains (Union[Unset, list[str]]): Deprecated: use proxy.allowedDomains instead. List of allowed + external domains (allowlist). Kept for backward compatibility. Example: ["api.stripe.com", "api.openai.com", + "*.s3.amazonaws.com"]. + egress (Union[Unset, EgressConfig]): Egress configuration for routing sandbox outbound traffic through a + dedicated IP gateway + firewall (Union[Unset, FirewallConfig]): Firewall configuration specifying which network lockdown rulesets to + apply. Valid rulesets are "default" (no-op), "proxy" (restrict egress to proxy), and "dedicated-ip" (restrict + egress to dedicated IP gateway). + forbidden_domains (Union[Unset, list[str]]): Deprecated: use proxy.forbiddenDomains instead. List of forbidden + external domains (denylist). Kept for backward compatibility. Example: ["*.malware.com", "evil.example.org"]. + proxy (Union[Unset, ProxyConfig]): Proxy configuration for routing sandbox HTTP traffic through the platform + proxy with MITM inspection and per-destination header/body injection + subnet (Union[Unset, str]): Subnet name for the sandbox. Takes priority over any subnet derived from egress + config. Defaults to "default" when absent. Example: default. """ allowed_domains: Union[Unset, list[str]] = UNSET egress: Union[Unset, "EgressConfig"] = UNSET + firewall: Union[Unset, "FirewallConfig"] = UNSET forbidden_domains: Union[Unset, list[str]] = UNSET proxy: Union[Unset, "ProxyConfig"] = UNSET + subnet: Union[Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - allowed_domains: Union[Unset, list[str]] = UNSET if not isinstance(self.allowed_domains, Unset): allowed_domains = self.allowed_domains @@ -48,6 +55,16 @@ def to_dict(self) -> dict[str, Any]: elif self.egress and isinstance(self.egress, dict): egress = self.egress + firewall: Union[Unset, dict[str, Any]] = UNSET + if ( + self.firewall + and not isinstance(self.firewall, Unset) + and not isinstance(self.firewall, dict) + ): + firewall = self.firewall.to_dict() + elif self.firewall and isinstance(self.firewall, dict): + firewall = self.firewall + forbidden_domains: Union[Unset, list[str]] = UNSET if not isinstance(self.forbidden_domains, Unset): forbidden_domains = self.forbidden_domains @@ -58,6 +75,8 @@ def to_dict(self) -> dict[str, Any]: elif self.proxy and isinstance(self.proxy, dict): proxy = self.proxy + subnet = self.subnet + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -65,16 +84,21 @@ def to_dict(self) -> dict[str, Any]: field_dict["allowedDomains"] = allowed_domains if egress is not UNSET: field_dict["egress"] = egress + if firewall is not UNSET: + field_dict["firewall"] = firewall if forbidden_domains is not UNSET: field_dict["forbiddenDomains"] = forbidden_domains if proxy is not UNSET: field_dict["proxy"] = proxy + if subnet is not UNSET: + field_dict["subnet"] = subnet return field_dict @classmethod def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: from ..models.egress_config import EgressConfig + from ..models.firewall_config import FirewallConfig from ..models.proxy_config import ProxyConfig if not src_dict: @@ -89,6 +113,13 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: else: egress = EgressConfig.from_dict(_egress) + _firewall = d.pop("firewall", UNSET) + firewall: Union[Unset, FirewallConfig] + if isinstance(_firewall, Unset): + firewall = UNSET + else: + firewall = FirewallConfig.from_dict(_firewall) + forbidden_domains = cast( list[str], d.pop("forbiddenDomains", d.pop("forbidden_domains", UNSET)) ) @@ -100,11 +131,15 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: else: proxy = ProxyConfig.from_dict(_proxy) + subnet = d.pop("subnet", UNSET) + sandbox_network = cls( allowed_domains=allowed_domains, egress=egress, + firewall=firewall, forbidden_domains=forbidden_domains, proxy=proxy, + subnet=subnet, ) sandbox_network.additional_properties = d diff --git a/src/blaxel/core/client/models/sandbox_runtime.py b/src/blaxel/core/client/models/sandbox_runtime.py index bc93a366..26855cd5 100644 --- a/src/blaxel/core/client/models/sandbox_runtime.py +++ b/src/blaxel/core/client/models/sandbox_runtime.py @@ -33,8 +33,9 @@ class SandboxRuntime: ports (Union[Unset, list['Port']]): Set of ports for a resource termination_grace_period_seconds (Union[Unset, int]): Duration in seconds the pod needs to terminate gracefully. Defaults to 0 for immediate termination. Example: 30. - ttl (Union[Unset, str]): Time-to-live duration after which the sandbox is automatically deleted (e.g., '30m', - '24h', '7d') Example: 24h. + ttl (Union[Unset, str]): Max-age from creation: the sandbox is deleted this long after it is created, regardless + of activity (not an idle timeout). Units s, m, h, d, w (e.g., '30m', '24h', '7d', '2w'). For idle-based cleanup, + use a lifecycle expiration policy of type ttl-idle. Example: 24h. """ envs: Union[Unset, list["Env"]] = UNSET @@ -48,7 +49,6 @@ class SandboxRuntime: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - envs: Union[Unset, list[dict[str, Any]]] = UNSET if not isinstance(self.envs, Unset): envs = [] diff --git a/src/blaxel/core/client/models/sandbox_spec.py b/src/blaxel/core/client/models/sandbox_spec.py index baf93cc3..03237513 100644 --- a/src/blaxel/core/client/models/sandbox_spec.py +++ b/src/blaxel/core/client/models/sandbox_spec.py @@ -24,13 +24,14 @@ class SandboxSpec: Example: True. lifecycle (Union[Unset, SandboxLifecycle]): Lifecycle configuration controlling automatic sandbox deletion based on idle time, max age, or specific dates - network (Union[Unset, SandboxNetwork]): Network configuration for a sandbox including domain filtering, egress - IP binding, and proxy settings + network (Union[Unset, SandboxNetwork]): Network configuration for a sandbox including subnet, firewall rulesets, + domain filtering, egress IP binding, and proxy settings region (Union[Unset, str]): Region where the sandbox should be created (e.g. us-pdx-1, eu-lon-1). If not specified, defaults to the region closest to the user. Example: us-pdx-1. runtime (Union[Unset, SandboxRuntime]): Runtime configuration defining how the sandbox VM is provisioned and its resource limits volumes (Union[Unset, list['VolumeAttachment']]): + vpc (Union[Unset, str]): VPC name for the sandbox. Defaults to "default" when absent. Example: default. """ enabled: Union[Unset, bool] = True @@ -39,10 +40,10 @@ class SandboxSpec: region: Union[Unset, str] = UNSET runtime: Union[Unset, "SandboxRuntime"] = UNSET volumes: Union[Unset, list["VolumeAttachment"]] = UNSET + vpc: Union[Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled lifecycle: Union[Unset, dict[str, Any]] = UNSET @@ -91,6 +92,8 @@ def to_dict(self) -> dict[str, Any]: ) volumes.append(componentsschemas_volume_attachments_item) + vpc = self.vpc + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -106,6 +109,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["runtime"] = runtime if volumes is not UNSET: field_dict["volumes"] = volumes + if vpc is not UNSET: + field_dict["vpc"] = vpc return field_dict @@ -153,6 +158,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: volumes.append(componentsschemas_volume_attachments_item) + vpc = d.pop("vpc", UNSET) + sandbox_spec = cls( enabled=enabled, lifecycle=lifecycle, @@ -160,6 +167,7 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: region=region, runtime=runtime, volumes=volumes, + vpc=vpc, ) sandbox_spec.additional_properties = d diff --git a/src/blaxel/core/client/models/sso_domain.py b/src/blaxel/core/client/models/sso_domain.py index a69f25cd..de9c67bb 100644 --- a/src/blaxel/core/client/models/sso_domain.py +++ b/src/blaxel/core/client/models/sso_domain.py @@ -28,7 +28,6 @@ class SSODomain: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/template.py b/src/blaxel/core/client/models/template.py index 56ee013b..363ed0f8 100644 --- a/src/blaxel/core/client/models/template.py +++ b/src/blaxel/core/client/models/template.py @@ -47,7 +47,6 @@ class Template: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - default_branch = self.default_branch description = self.description diff --git a/src/blaxel/core/client/models/test_feature_flag_response_200.py b/src/blaxel/core/client/models/test_feature_flag_response_200.py index ab81dc75..68967aa9 100644 --- a/src/blaxel/core/client/models/test_feature_flag_response_200.py +++ b/src/blaxel/core/client/models/test_feature_flag_response_200.py @@ -33,7 +33,6 @@ class TestFeatureFlagResponse200: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - enabled = self.enabled evaluated_at: Union[Unset, str] = UNSET diff --git a/src/blaxel/core/client/models/trigger.py b/src/blaxel/core/client/models/trigger.py index 8ddd3013..debd5c97 100644 --- a/src/blaxel/core/client/models/trigger.py +++ b/src/blaxel/core/client/models/trigger.py @@ -20,7 +20,8 @@ class Trigger: Attributes: configuration (Union[Unset, TriggerConfiguration]): Trigger configuration enabled (Union[Unset, bool]): Enable or disable the trigger (default: true) Example: True. - id (Union[Unset, str]): The id of the trigger Example: trigger-1. + id (Union[Unset, str]): Identifier of the trigger. Optional — the server auto-generates a unique id when one is + not provided, and disambiguates duplicates within a resource. Example: trigger-1. type_ (Union[Unset, TriggerType]): The type of trigger, can be http or http-async Example: http. """ @@ -31,7 +32,6 @@ class Trigger: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - configuration: Union[Unset, dict[str, Any]] = UNSET if ( self.configuration diff --git a/src/blaxel/core/client/models/trigger_configuration.py b/src/blaxel/core/client/models/trigger_configuration.py index 798d50bc..cf320103 100644 --- a/src/blaxel/core/client/models/trigger_configuration.py +++ b/src/blaxel/core/client/models/trigger_configuration.py @@ -39,7 +39,6 @@ class TriggerConfiguration: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - authentication_type = self.authentication_type callback_secret = self.callback_secret diff --git a/src/blaxel/core/client/models/volume.py b/src/blaxel/core/client/models/volume.py index 9640491a..61556357 100644 --- a/src/blaxel/core/client/models/volume.py +++ b/src/blaxel/core/client/models/volume.py @@ -40,7 +40,6 @@ class Volume: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/volume_list.py b/src/blaxel/core/client/models/volume_list.py new file mode 100644 index 00000000..9b33d132 --- /dev/null +++ b/src/blaxel/core/client/models/volume_list.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.lite_volume import LiteVolume + from ..models.pagination_meta import PaginationMeta + + +T = TypeVar("T", bound="VolumeList") + + +@_attrs_define +class VolumeList: + """Cursor-paginated list of volumes. Returned starting with API version 2026-04-28; older API versions return a bare + array. Items use the lite shape (no inline event history). + + Attributes: + data (Union[Unset, list['LiteVolume']]): Page of volumes. + meta (Union[Unset, PaginationMeta]): Pagination metadata returned alongside a page of listing results. Always + present on listing endpoints starting with API version 2026-04-28. + """ + + data: Union[Unset, list["LiteVolume"]] = UNSET + meta: Union[Unset, "PaginationMeta"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data: Union[Unset, list[dict[str, Any]]] = UNSET + if not isinstance(self.data, Unset): + data = [] + for data_item_data in self.data: + if type(data_item_data) is dict: + data_item = data_item_data + else: + data_item = data_item_data.to_dict() + data.append(data_item) + + meta: Union[Unset, dict[str, Any]] = UNSET + if self.meta and not isinstance(self.meta, Unset) and not isinstance(self.meta, dict): + meta = self.meta.to_dict() + elif self.meta and isinstance(self.meta, dict): + meta = self.meta + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if data is not UNSET: + field_dict["data"] = data + if meta is not UNSET: + field_dict["meta"] = meta + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.lite_volume import LiteVolume + from ..models.pagination_meta import PaginationMeta + + if not src_dict: + return None + d = src_dict.copy() + data = [] + _data = d.pop("data", UNSET) + for data_item_data in _data or []: + data_item = LiteVolume.from_dict(data_item_data) + + data.append(data_item) + + _meta = d.pop("meta", UNSET) + meta: Union[Unset, PaginationMeta] + if isinstance(_meta, Unset): + meta = UNSET + else: + meta = PaginationMeta.from_dict(_meta) + + volume_list = cls( + data=data, + meta=meta, + ) + + volume_list.additional_properties = d + return volume_list + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/volume_template.py b/src/blaxel/core/client/models/volume_template.py index d43a9145..ac1143c6 100644 --- a/src/blaxel/core/client/models/volume_template.py +++ b/src/blaxel/core/client/models/volume_template.py @@ -34,7 +34,6 @@ class VolumeTemplate: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/vpc.py b/src/blaxel/core/client/models/vpc.py index 005a9f2e..1d1b279f 100644 --- a/src/blaxel/core/client/models/vpc.py +++ b/src/blaxel/core/client/models/vpc.py @@ -34,7 +34,6 @@ class VPC: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - if type(self.metadata) is dict: metadata = self.metadata else: diff --git a/src/blaxel/core/client/models/workspace.py b/src/blaxel/core/client/models/workspace.py index 9a62f326..93131a67 100644 --- a/src/blaxel/core/client/models/workspace.py +++ b/src/blaxel/core/client/models/workspace.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from ..models.group_workspace_mapping import GroupWorkspaceMapping from ..models.metadata_labels import MetadataLabels + from ..models.workspace_resource_counts import WorkspaceResourceCounts from ..models.workspace_runtime import WorkspaceRuntime @@ -34,6 +35,9 @@ class Workspace: used to categorize resources by environment, project, team, or any custom taxonomy. name (Union[Unset, str]): Workspace name Example: my-workspace. region (Union[Unset, str]): Workspace write region Example: us-west-2. + resource_counts (Union[Unset, WorkspaceResourceCounts]): Per-resource counts (agents, functions, models, + sandboxes, policies, jobs, volumes, drives, volumetemplates, integrationconnections, previews, customdomains, + serviceaccounts, images). Only populated when GetWorkspace is called with ?countResources=true. runtime (Union[Unset, WorkspaceRuntime]): Runtime configuration for the workspace infrastructure status (Union[Unset, WorkspaceStatus]): Workspace status (created, account_binded, account_configured, workspace_configured, ready, error) Example: ready. @@ -51,13 +55,13 @@ class Workspace: labels: Union[Unset, "MetadataLabels"] = UNSET name: Union[Unset, str] = UNSET region: Union[Unset, str] = UNSET + resource_counts: Union[Unset, "WorkspaceResourceCounts"] = UNSET runtime: Union[Unset, "WorkspaceRuntime"] = UNSET status: Union[Unset, WorkspaceStatus] = UNSET status_reason: Union[Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - created_at = self.created_at updated_at = self.updated_at @@ -92,6 +96,16 @@ def to_dict(self) -> dict[str, Any]: region = self.region + resource_counts: Union[Unset, dict[str, Any]] = UNSET + if ( + self.resource_counts + and not isinstance(self.resource_counts, Unset) + and not isinstance(self.resource_counts, dict) + ): + resource_counts = self.resource_counts.to_dict() + elif self.resource_counts and isinstance(self.resource_counts, dict): + resource_counts = self.resource_counts + runtime: Union[Unset, dict[str, Any]] = UNSET if ( self.runtime @@ -133,6 +147,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["name"] = name if region is not UNSET: field_dict["region"] = region + if resource_counts is not UNSET: + field_dict["resourceCounts"] = resource_counts if runtime is not UNSET: field_dict["runtime"] = runtime if status is not UNSET: @@ -146,6 +162,7 @@ def to_dict(self) -> dict[str, Any]: def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: from ..models.group_workspace_mapping import GroupWorkspaceMapping from ..models.metadata_labels import MetadataLabels + from ..models.workspace_resource_counts import WorkspaceResourceCounts from ..models.workspace_runtime import WorkspaceRuntime if not src_dict: @@ -183,6 +200,13 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: region = d.pop("region", UNSET) + _resource_counts = d.pop("resourceCounts", d.pop("resource_counts", UNSET)) + resource_counts: Union[Unset, WorkspaceResourceCounts] + if isinstance(_resource_counts, Unset): + resource_counts = UNSET + else: + resource_counts = WorkspaceResourceCounts.from_dict(_resource_counts) + _runtime = d.pop("runtime", UNSET) runtime: Union[Unset, WorkspaceRuntime] if isinstance(_runtime, Unset): @@ -211,6 +235,7 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: labels=labels, name=name, region=region, + resource_counts=resource_counts, runtime=runtime, status=status, status_reason=status_reason, diff --git a/src/blaxel/core/client/models/workspace_hipaa_info.py b/src/blaxel/core/client/models/workspace_hipaa_info.py new file mode 100644 index 00000000..fb1093a4 --- /dev/null +++ b/src/blaxel/core/client/models/workspace_hipaa_info.py @@ -0,0 +1,89 @@ +from typing import TYPE_CHECKING, Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.workspace_hipaa_unsafe import WorkspaceHipaaUnsafe + + +T = TypeVar("T", bound="WorkspaceHipaaInfo") + + +@_attrs_define +class WorkspaceHipaaInfo: + """HIPAA compliance state for a workspace. `accountEnabled` mirrors the account-level `hipaa_compliance` addon (set + server-side from operator tooling and Stripe billing events). `unsafe` records a per-workspace opt-out toggled from + workspace settings; absent when the account does not have the addon. + + Attributes: + account_enabled (Union[Unset, bool]): True when the parent account has the HIPAA compliance addon active. Set + server-side from operator tooling and Stripe billing events; cannot be changed from workspace settings. + unsafe (Union[Unset, WorkspaceHipaaUnsafe]): Per-workspace HIPAA opt-out record. Toggled from workspace + settings; the backend stamps `updatedBy` and `updatedAt`. + """ + + account_enabled: Union[Unset, bool] = UNSET + unsafe: Union[Unset, "WorkspaceHipaaUnsafe"] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + account_enabled = self.account_enabled + + unsafe: Union[Unset, dict[str, Any]] = UNSET + if self.unsafe and not isinstance(self.unsafe, Unset) and not isinstance(self.unsafe, dict): + unsafe = self.unsafe.to_dict() + elif self.unsafe and isinstance(self.unsafe, dict): + unsafe = self.unsafe + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if account_enabled is not UNSET: + field_dict["accountEnabled"] = account_enabled + if unsafe is not UNSET: + field_dict["unsafe"] = unsafe + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.workspace_hipaa_unsafe import WorkspaceHipaaUnsafe + + if not src_dict: + return None + d = src_dict.copy() + account_enabled = d.pop("accountEnabled", d.pop("account_enabled", UNSET)) + + _unsafe = d.pop("unsafe", UNSET) + unsafe: Union[Unset, WorkspaceHipaaUnsafe] + if isinstance(_unsafe, Unset): + unsafe = UNSET + else: + unsafe = WorkspaceHipaaUnsafe.from_dict(_unsafe) + + workspace_hipaa_info = cls( + account_enabled=account_enabled, + unsafe=unsafe, + ) + + workspace_hipaa_info.additional_properties = d + return workspace_hipaa_info + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/workspace_hipaa_unsafe.py b/src/blaxel/core/client/models/workspace_hipaa_unsafe.py new file mode 100644 index 00000000..223c707b --- /dev/null +++ b/src/blaxel/core/client/models/workspace_hipaa_unsafe.py @@ -0,0 +1,80 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="WorkspaceHipaaUnsafe") + + +@_attrs_define +class WorkspaceHipaaUnsafe: + """Per-workspace HIPAA opt-out record. Toggled from workspace settings; the backend stamps `updatedBy` and `updatedAt`. + + Attributes: + enabled (Union[Unset, bool]): True marks this workspace as HIPAA-unsafe (NOT compliant), overriding the account- + level addon. False marks the workspace as HIPAA compliant. + updated_at (Union[Unset, str]): RFC3339 timestamp when the opt-out was last toggled. Stamped server-side. + updated_by (Union[Unset, str]): User id (sub) of the actor that last toggled this opt-out. Stamped server-side. + """ + + enabled: Union[Unset, bool] = UNSET + updated_at: Union[Unset, str] = UNSET + updated_by: Union[Unset, str] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + enabled = self.enabled + + updated_at = self.updated_at + + updated_by = self.updated_by + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if enabled is not UNSET: + field_dict["enabled"] = enabled + if updated_at is not UNSET: + field_dict["updatedAt"] = updated_at + if updated_by is not UNSET: + field_dict["updatedBy"] = updated_by + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + enabled = d.pop("enabled", UNSET) + + updated_at = d.pop("updatedAt", d.pop("updated_at", UNSET)) + + updated_by = d.pop("updatedBy", d.pop("updated_by", UNSET)) + + workspace_hipaa_unsafe = cls( + enabled=enabled, + updated_at=updated_at, + updated_by=updated_by, + ) + + workspace_hipaa_unsafe.additional_properties = d + return workspace_hipaa_unsafe + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/workspace_resource_counts.py b/src/blaxel/core/client/models/workspace_resource_counts.py new file mode 100644 index 00000000..b550cb3d --- /dev/null +++ b/src/blaxel/core/client/models/workspace_resource_counts.py @@ -0,0 +1,49 @@ +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="WorkspaceResourceCounts") + + +@_attrs_define +class WorkspaceResourceCounts: + """Per-resource counts (agents, functions, models, sandboxes, policies, jobs, volumes, drives, volumetemplates, + integrationconnections, previews, customdomains, serviceaccounts, images). Only populated when GetWorkspace is + called with ?countResources=true. + + """ + + additional_properties: dict[str, int] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + workspace_resource_counts = cls() + + workspace_resource_counts.additional_properties = d + return workspace_resource_counts + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> int: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: int) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/src/blaxel/core/client/models/workspace_runtime.py b/src/blaxel/core/client/models/workspace_runtime.py index a7082dc3..f28bf4de 100644 --- a/src/blaxel/core/client/models/workspace_runtime.py +++ b/src/blaxel/core/client/models/workspace_runtime.py @@ -1,10 +1,14 @@ -from typing import Any, TypeVar, Union +from typing import TYPE_CHECKING, Any, TypeVar, Union from attrs import define as _attrs_define from attrs import field as _attrs_field from ..types import UNSET, Unset +if TYPE_CHECKING: + from ..models.workspace_sandbox_settings import WorkspaceSandboxSettings + + T = TypeVar("T", bound="WorkspaceRuntime") @@ -15,31 +19,56 @@ class WorkspaceRuntime: Attributes: generation (Union[Unset, str]): Infrastructure generation version for the workspace (affects available features and deployment behavior) Example: mk3. + sandbox (Union[Unset, WorkspaceSandboxSettings]): Workspace-wide sandbox configuration that applies to all + sandbox deployments in the workspace. """ generation: Union[Unset, str] = UNSET + sandbox: Union[Unset, "WorkspaceSandboxSettings"] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: generation = self.generation + sandbox: Union[Unset, dict[str, Any]] = UNSET + if ( + self.sandbox + and not isinstance(self.sandbox, Unset) + and not isinstance(self.sandbox, dict) + ): + sandbox = self.sandbox.to_dict() + elif self.sandbox and isinstance(self.sandbox, dict): + sandbox = self.sandbox + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) if generation is not UNSET: field_dict["generation"] = generation + if sandbox is not UNSET: + field_dict["sandbox"] = sandbox return field_dict @classmethod def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + from ..models.workspace_sandbox_settings import WorkspaceSandboxSettings + if not src_dict: return None d = src_dict.copy() generation = d.pop("generation", UNSET) + _sandbox = d.pop("sandbox", UNSET) + sandbox: Union[Unset, WorkspaceSandboxSettings] + if isinstance(_sandbox, Unset): + sandbox = UNSET + else: + sandbox = WorkspaceSandboxSettings.from_dict(_sandbox) + workspace_runtime = cls( generation=generation, + sandbox=sandbox, ) workspace_runtime.additional_properties = d diff --git a/src/blaxel/core/client/models/workspace_sandbox_settings.py b/src/blaxel/core/client/models/workspace_sandbox_settings.py new file mode 100644 index 00000000..099ec2cd --- /dev/null +++ b/src/blaxel/core/client/models/workspace_sandbox_settings.py @@ -0,0 +1,65 @@ +from typing import Any, TypeVar, Union + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="WorkspaceSandboxSettings") + + +@_attrs_define +class WorkspaceSandboxSettings: + """Workspace-wide sandbox configuration that applies to all sandbox deployments in the workspace. + + Attributes: + disable_process_logging (Union[Unset, bool]): When true, sandbox deployments in this workspace set + SANDBOX_DISABLE_PROCESS_LOGGING=true to disable per-process stdout/stderr logging. Requires sandbox-api + v0.2.28+. + """ + + disable_process_logging: Union[Unset, bool] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + disable_process_logging = self.disable_process_logging + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if disable_process_logging is not UNSET: + field_dict["disableProcessLogging"] = disable_process_logging + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: + if not src_dict: + return None + d = src_dict.copy() + disable_process_logging = d.pop( + "disableProcessLogging", d.pop("disable_process_logging", UNSET) + ) + + workspace_sandbox_settings = cls( + disable_process_logging=disable_process_logging, + ) + + workspace_sandbox_settings.additional_properties = d + return workspace_sandbox_settings + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties From ecee9a7033ef9dfb7544e154e25e52cb1429b5a5 Mon Sep 17 00:00:00 2001 From: cdrappier Date: Wed, 10 Jun 2026 18:49:53 +0000 Subject: [PATCH 2/3] fix: handle bare array responses from pre-pagination API The regenerated list endpoints now expect paginated {data, meta} wrappers, but the API still returns bare arrays for older API versions. Fix: - from_dict() in all *List models: if src_dict is a list, wrap as {"data": src_dict} - list() methods in DriveInstance, VolumeInstance, SandboxInstance: extract .data from response - list_executions in BlJobWrapper: extract .data from paginated response Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- src/blaxel/core/client/models/agent_list.py | 2 ++ src/blaxel/core/client/models/application_list.py | 2 ++ src/blaxel/core/client/models/drive_list.py | 2 ++ src/blaxel/core/client/models/function_list.py | 2 ++ src/blaxel/core/client/models/job_execution_list.py | 2 ++ .../core/client/models/job_execution_task_list.py | 2 ++ src/blaxel/core/client/models/job_list.py | 2 ++ src/blaxel/core/client/models/model_list.py | 2 ++ src/blaxel/core/client/models/policy_list.py | 2 ++ src/blaxel/core/client/models/sandbox_list.py | 2 ++ src/blaxel/core/client/models/volume_list.py | 2 ++ src/blaxel/core/drive/drive.py | 10 ++++++++-- src/blaxel/core/jobs/__init__.py | 12 ++++++++++-- src/blaxel/core/sandbox/default/sandbox.py | 5 ++++- src/blaxel/core/sandbox/sync/sandbox.py | 5 ++++- src/blaxel/core/volume/volume.py | 10 ++++++++-- 16 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/blaxel/core/client/models/agent_list.py b/src/blaxel/core/client/models/agent_list.py index c25dc81c..0062e9c5 100644 --- a/src/blaxel/core/client/models/agent_list.py +++ b/src/blaxel/core/client/models/agent_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/application_list.py b/src/blaxel/core/client/models/application_list.py index c6ed52a1..8ec61cab 100644 --- a/src/blaxel/core/client/models/application_list.py +++ b/src/blaxel/core/client/models/application_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/drive_list.py b/src/blaxel/core/client/models/drive_list.py index d538467e..aaaa9867 100644 --- a/src/blaxel/core/client/models/drive_list.py +++ b/src/blaxel/core/client/models/drive_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/function_list.py b/src/blaxel/core/client/models/function_list.py index 09c60964..f1937bc7 100644 --- a/src/blaxel/core/client/models/function_list.py +++ b/src/blaxel/core/client/models/function_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/job_execution_list.py b/src/blaxel/core/client/models/job_execution_list.py index e2886081..9dfc0f64 100644 --- a/src/blaxel/core/client/models/job_execution_list.py +++ b/src/blaxel/core/client/models/job_execution_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/job_execution_task_list.py b/src/blaxel/core/client/models/job_execution_task_list.py index c03678c3..f7ab6052 100644 --- a/src/blaxel/core/client/models/job_execution_task_list.py +++ b/src/blaxel/core/client/models/job_execution_task_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/job_list.py b/src/blaxel/core/client/models/job_list.py index 96007c31..9c72820d 100644 --- a/src/blaxel/core/client/models/job_list.py +++ b/src/blaxel/core/client/models/job_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/model_list.py b/src/blaxel/core/client/models/model_list.py index 35084d04..23ba522f 100644 --- a/src/blaxel/core/client/models/model_list.py +++ b/src/blaxel/core/client/models/model_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/policy_list.py b/src/blaxel/core/client/models/policy_list.py index 9f677085..5f80ab8e 100644 --- a/src/blaxel/core/client/models/policy_list.py +++ b/src/blaxel/core/client/models/policy_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/sandbox_list.py b/src/blaxel/core/client/models/sandbox_list.py index a0fc1b36..f8e35ad7 100644 --- a/src/blaxel/core/client/models/sandbox_list.py +++ b/src/blaxel/core/client/models/sandbox_list.py @@ -63,6 +63,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/client/models/volume_list.py b/src/blaxel/core/client/models/volume_list.py index 9b33d132..a3f2a941 100644 --- a/src/blaxel/core/client/models/volume_list.py +++ b/src/blaxel/core/client/models/volume_list.py @@ -62,6 +62,8 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T | None: if not src_dict: return None + if isinstance(src_dict, list): + src_dict = {"data": src_dict} d = src_dict.copy() data = [] _data = d.pop("data", UNSET) diff --git a/src/blaxel/core/drive/drive.py b/src/blaxel/core/drive/drive.py index f9cb0f9f..3208aae8 100644 --- a/src/blaxel/core/drive/drive.py +++ b/src/blaxel/core/drive/drive.py @@ -249,7 +249,10 @@ async def get(cls, drive_name: str) -> "DriveInstance": @classmethod async def list(cls) -> list["DriveInstance"]: response = await list_drives(client=client) - return [cls(drive) for drive in response or []] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(drive) for drive in items] @classmethod async def create_if_not_exists( @@ -401,7 +404,10 @@ def get(cls, drive_name: str) -> "SyncDriveInstance": def list(cls) -> List["SyncDriveInstance"]: """List all drives synchronously.""" response = list_drives_sync(client=client) - return [cls(drive) for drive in response or []] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(drive) for drive in items] @classmethod def create_if_not_exists( diff --git a/src/blaxel/core/jobs/__init__.py b/src/blaxel/core/jobs/__init__.py index 14ecb603..cd76ef81 100644 --- a/src/blaxel/core/jobs/__init__.py +++ b/src/blaxel/core/jobs/__init__.py @@ -308,7 +308,11 @@ def list_executions(self, limit: int = 20, offset: int = 0) -> List[JobExecution if response.status_code != 200: raise Exception(f"Failed to list job executions: {response.status_code}") - return response.parsed or [] + parsed = response.parsed + if parsed is None: + return [] + items = getattr(parsed, "data", parsed) or [] + return list(items) async def alist_executions(self, limit: int = 20, offset: int = 0) -> List[JobExecution]: """ @@ -333,7 +337,11 @@ async def alist_executions(self, limit: int = 20, offset: int = 0) -> List[JobEx if response.status_code != 200: raise Exception(f"Failed to list job executions: {response.status_code}") - return response.parsed or [] + parsed = response.parsed + if parsed is None: + return [] + items = getattr(parsed, "data", parsed) or [] + return list(items) def get_execution_status(self, execution_id: str) -> str: """ diff --git a/src/blaxel/core/sandbox/default/sandbox.py b/src/blaxel/core/sandbox/default/sandbox.py index f80a6008..7a80f59f 100644 --- a/src/blaxel/core/sandbox/default/sandbox.py +++ b/src/blaxel/core/sandbox/default/sandbox.py @@ -357,7 +357,10 @@ async def get(cls, sandbox_name: str) -> "SandboxInstance": @classmethod async def list(cls) -> List["SandboxInstance"]: response = await list_sandboxes(client=client) - return [cls(sandbox) for sandbox in response] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(sandbox) for sandbox in items] @classmethod async def update_metadata( diff --git a/src/blaxel/core/sandbox/sync/sandbox.py b/src/blaxel/core/sandbox/sync/sandbox.py index cf64e2af..37921b14 100644 --- a/src/blaxel/core/sandbox/sync/sandbox.py +++ b/src/blaxel/core/sandbox/sync/sandbox.py @@ -297,7 +297,10 @@ def get(cls, sandbox_name: str) -> "SyncSandboxInstance": @classmethod def list(cls) -> List["SyncSandboxInstance"]: response = list_sandboxes(client=client) - return [cls(sandbox) for sandbox in response] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(sandbox) for sandbox in items] @classmethod def update_metadata( diff --git a/src/blaxel/core/volume/volume.py b/src/blaxel/core/volume/volume.py index 0ecfe5ca..b280c4b5 100644 --- a/src/blaxel/core/volume/volume.py +++ b/src/blaxel/core/volume/volume.py @@ -256,7 +256,10 @@ async def get(cls, volume_name: str) -> "VolumeInstance": @classmethod async def list(cls) -> list["VolumeInstance"]: response = await list_volumes(client=client) - return [cls(volume) for volume in response or []] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(volume) for volume in items] @classmethod async def create_if_not_exists( @@ -410,7 +413,10 @@ def get(cls, volume_name: str) -> "SyncVolumeInstance": def list(cls) -> List["SyncVolumeInstance"]: """List all volumes synchronously.""" response = list_volumes_sync(client=client) - return [cls(volume) for volume in response or []] + if response is None: + return [] + items = getattr(response, "data", response) or [] + return [cls(volume) for volume in items] @classmethod def create_if_not_exists( From 527007f84d5dcd4983415ab3875a2b08d2cd59ee Mon Sep 17 00:00:00 2001 From: cdrappier Date: Wed, 10 Jun 2026 19:00:25 +0000 Subject: [PATCH 3/3] fix: add error handling to delete helper functions Check for Error responses in _delete_application_by_name and _delete_application_by_name_sync, raising ApplicationAPIError instead of silently returning Error typed as Application. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- src/blaxel/core/application/application.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/blaxel/core/application/application.py b/src/blaxel/core/application/application.py index d69c8fb9..944d9b12 100644 --- a/src/blaxel/core/application/application.py +++ b/src/blaxel/core/application/application.py @@ -436,12 +436,20 @@ def create_if_not_exists( async def _delete_application_by_name(application_name: str) -> Application: """Delete an application by name (async).""" response = await delete_application(application_name=application_name, client=client) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) return response def _delete_application_by_name_sync(application_name: str) -> Application: """Delete an application by name (sync).""" response = delete_application_sync(application_name=application_name, client=client) + if isinstance(response, Error): + status_code = int(response.code) if response.code is not UNSET else None + message = response.message if response.message is not UNSET else response.error + raise ApplicationAPIError(message, status_code=status_code, code=response.error) return response