diff --git a/fern/.gitignore b/fern/.gitignore
new file mode 100644
index 0000000000..2114f1dd17
--- /dev/null
+++ b/fern/.gitignore
@@ -0,0 +1,2 @@
+**/.preview
+**/.definition
diff --git a/fern/fern.config.json b/fern/fern.config.json
new file mode 100644
index 0000000000..e6d3226d4c
--- /dev/null
+++ b/fern/fern.config.json
@@ -0,0 +1,4 @@
+{
+ "organization": "nvidia",
+ "version": "5.46.1"
+}
\ No newline at end of file
diff --git a/fern/generators.yml b/fern/generators.yml
new file mode 100644
index 0000000000..746dd83b81
--- /dev/null
+++ b/fern/generators.yml
@@ -0,0 +1,20 @@
+# yaml-language-server: $schema=https://schema.buildwithfern.dev/generators-yml.json
+api:
+ specs:
+ - openapi: ../openapi/openapi.yaml
+default-group: local
+groups:
+ local:
+ generators:
+ - name: fern-typescript-sdk
+ output:
+ location: local-file-system
+ path: ../sdks/typescript
+ version: 3.71.8
+ python-sdk:
+ generators:
+ - name: fern-python-sdk
+ version: 5.14.14
+ output:
+ location: local-file-system
+ path: ../sdks/python
diff --git a/sdks/python/.fern/metadata.json b/sdks/python/.fern/metadata.json
new file mode 100644
index 0000000000..79a21230c8
--- /dev/null
+++ b/sdks/python/.fern/metadata.json
@@ -0,0 +1,8 @@
+{
+ "cliVersion": "5.46.1",
+ "generatorName": "fernapi/fern-python-sdk",
+ "generatorVersion": "5.14.14",
+ "originGitCommit": "36bbf2906e7b4ada998c6006932f83e2399e9ac2",
+ "originGitCommitIsDirty": true,
+ "invokedBy": "manual"
+}
\ No newline at end of file
diff --git a/sdks/python/CONTRIBUTING.md b/sdks/python/CONTRIBUTING.md
new file mode 100644
index 0000000000..af948ce725
--- /dev/null
+++ b/sdks/python/CONTRIBUTING.md
@@ -0,0 +1,125 @@
+# Contributing
+
+Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project.
+
+## Getting Started
+
+### Prerequisites
+
+- Python 3.9+
+- pip
+- poetry
+
+### Installation
+
+Install the project dependencies:
+
+```bash
+poetry install
+```
+
+### Building
+
+Build the project:
+
+```bash
+poetry build
+```
+
+### Testing
+
+Run the test suite:
+
+```bash
+poetry run pytest
+```
+
+### Linting and Formatting
+
+Check code style:
+
+```bash
+poetry run ruff check .
+poetry run ruff format .
+```
+
+### Type Checking
+
+Run the type checker:
+
+```bash
+poetry run mypy .
+```
+
+## About Generated Code
+
+**Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated.
+
+### Generated Files
+
+The following directories contain generated code:
+- `src/` - API client classes and types
+- Most Python files in the project
+
+### How to Customize
+
+If you need to customize the SDK, you have two options:
+
+#### Option 1: Use `.fernignore`
+
+For custom code that should persist across SDK regenerations:
+
+1. Create a `.fernignore` file in the project root
+2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax)
+3. Add your custom code to those files
+
+Files listed in `.fernignore` will not be overwritten when the SDK is regenerated.
+
+For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code).
+
+#### Option 2: Contribute to the Generator
+
+If you want to change how code is generated for all users of this SDK:
+
+1. The Python SDK generator lives in the [Fern repository](https://github.com/fern-api/fern)
+2. Generator code is located at `generators/python-v2/`
+3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md)
+4. Submit a pull request with your changes to the generator
+
+This approach is best for:
+- Bug fixes in generated code
+- New features that would benefit all users
+- Improvements to code generation patterns
+
+## Making Changes
+
+### Workflow
+
+1. Create a new branch for your changes
+2. Make your modifications
+3. Run tests to ensure nothing breaks: `poetry run pytest`
+4. Run linting and formatting: `poetry run ruff check .` and `poetry run ruff format .`
+5. Run type checking: `poetry run mypy .`
+6. Build the project: `poetry build`
+7. Commit your changes with a clear commit message
+8. Push your branch and create a pull request
+
+### Commit Messages
+
+Write clear, descriptive commit messages that explain what changed and why.
+
+### Code Style
+
+This project uses automated code formatting and linting. Run `poetry run ruff format .` and `poetry run ruff check .` before committing to ensure your code meets the project's style guidelines.
+
+## Questions or Issues?
+
+If you have questions or run into issues:
+
+1. Check the [Fern documentation](https://buildwithfern.com)
+2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues)
+3. Open a new issue if your question hasn't been addressed
+
+## License
+
+By contributing to this project, you agree that your contributions will be licensed under the same license as the project.
diff --git a/sdks/python/__init__.py b/sdks/python/__init__.py
new file mode 100644
index 0000000000..2130908017
--- /dev/null
+++ b/sdks/python/__init__.py
@@ -0,0 +1,1397 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import (
+ ActionRails,
+ ActivatedRail,
+ Adapter,
+ AdapterEntityFilter,
+ AdapterEntityFilterDescription,
+ AdapterEntityFilterModel,
+ AdapterEntityFilterName,
+ AdaptersPage,
+ AiDefenseRailConfig,
+ Annotation,
+ AnnotationFilter,
+ AnnotationInput,
+ AnnotationInput_Feedback,
+ AnnotationInput_Label,
+ AnnotationInput_Metadata,
+ AnnotationInput_Note,
+ AnnotationKind,
+ AnnotationSortField,
+ Annotation_Feedback,
+ Annotation_Label,
+ Annotation_Metadata,
+ Annotation_Note,
+ AnnotationsPage,
+ ApiEndpointData,
+ AtifAgent,
+ AtifContentPart,
+ AtifContentPartImage,
+ AtifContentPartText,
+ AtifContentPart_Image,
+ AtifContentPart_Text,
+ AtifFinalMetrics,
+ AtifImageSource,
+ AtifImageSourceMediaType,
+ AtifMetrics,
+ AtifObservation,
+ AtifObservationResult,
+ AtifObservationResultContent,
+ AtifStep,
+ AtifStepAgent,
+ AtifStepAgentMessage,
+ AtifStepAgentReasoningEffort,
+ AtifStepSystem,
+ AtifStepSystemMessage,
+ AtifStepUser,
+ AtifStepUserMessage,
+ AtifStep_Agent,
+ AtifStep_System,
+ AtifStep_User,
+ AtifSubagentTrajectoryRef,
+ AtifToolCall,
+ AuthContext,
+ AuthDiscoveryResponse,
+ AutoAlignOptions,
+ AutoAlignRailConfig,
+ BackendFormat,
+ BaseModelFilter,
+ BaseModelFilterName,
+ CacheStatsConfig,
+ CacheStatus,
+ CapturedChatCompletionsRequest,
+ CapturedChatCompletionsResponse,
+ CapturedChatMessage,
+ ChatCompletionAssistantMessageParam,
+ ChatCompletionContentPartImageParam,
+ ChatCompletionContentPartTextParam,
+ ChatCompletionFunctionMessageParam,
+ ChatCompletionMessageToolCallParam,
+ ChatCompletionMessageToolCallParamType,
+ ChatCompletionSystemMessageParam,
+ ChatCompletionToolMessageParam,
+ ChatCompletionUserMessageParam,
+ ChatCompletionUserMessageParamContent,
+ ChatCompletionUserMessageParamContentOneItem,
+ ChatCompletionUserMessageParamContentOneItem_ImageUrl,
+ ChatCompletionUserMessageParamContentOneItem_Text,
+ ChatCompletionsIngestResponse,
+ ChatMessageRole,
+ ClavataRailConfig,
+ ClavataRailConfigLabelMatchLogic,
+ ClavataRailOptions,
+ ComputeResourceSpec,
+ ComputeResources,
+ ContainerExecutorConfig,
+ ContainerSpec,
+ ContentSafetyConfig,
+ CpuExecutionProviderInput,
+ CpuExecutionProviderOutput,
+ CrowdStrikeAidrRailConfig,
+ DatasetMetadataContent,
+ DatasetMetadataContentSchema,
+ DatasetMetadataContentSchemasByPathValue,
+ DateRangeFilter,
+ DatetimeFilter,
+ DeleteResponse,
+ DialogRails,
+ DistributedGpuExecutionProviderInput,
+ DistributedGpuExecutionProviderOutput,
+ DockerJobExecutionProfile,
+ DockerJobExecutionProfileConfig,
+ DockerJobNetworkConfig,
+ DockerJobStorageConfig,
+ DockerVolumeMount,
+ DockerVolumeMountKind,
+ E2EJobExecutionProfile,
+ Engine,
+ EntitiesPage,
+ Entity,
+ EvaluationContext,
+ EvaluatorAggregate,
+ EvaluatorResult,
+ EvaluatorResultDataType,
+ EvaluatorResultFilter,
+ EvaluatorResultSortField,
+ EvaluatorResultsPage,
+ ExecutedAction,
+ ExperimentContext,
+ ExperimentFilter,
+ ExperimentGroupFilter,
+ ExperimentGroupRequest,
+ ExperimentGroupResponse,
+ ExperimentGroupResponsesPage,
+ ExperimentRequest,
+ ExperimentResponse,
+ ExperimentResponsesPage,
+ ExperimentSessionFilter,
+ ExperimentSessionResponse,
+ ExperimentSessionResponsesPage,
+ FactCheckingRailConfig,
+ FeedbackAnnotation,
+ FeedbackAnnotationInput,
+ FeedbackAnnotationInputValue,
+ FeedbackAnnotationValue,
+ FiddlerGuardrails,
+ FileStorageType,
+ FilesetFileOutput,
+ FilesetFilter,
+ FilesetFilterDescription,
+ FilesetFilterName,
+ FilesetMetadataInput,
+ FilesetMetadataOutput,
+ FilesetOutput,
+ FilesetOutputStorage,
+ FilesetOutputStorage_Huggingface,
+ FilesetOutputStorage_Local,
+ FilesetOutputStorage_Ngc,
+ FilesetOutputStorage_S3,
+ FilesetOutputsPage,
+ FilesetPurpose,
+ FinetuningType,
+ FinetuningTypeFilter,
+ FloatFilter,
+ Function,
+ FunctionCall,
+ GLiNerDetection,
+ GLiNerDetectionOptions,
+ GenerationLog,
+ GenerationLogOptions,
+ GenerationOptions,
+ GenerationOptionsOutputVars,
+ GenerationRailsOptions,
+ GenerationRailsOptionsInput,
+ GenerationRailsOptionsOutput,
+ GenerationRailsOptionsRetrieval,
+ GenerationStats,
+ GenericSortField,
+ GpuExecutionProviderInput,
+ GpuExecutionProviderOutput,
+ GuardrailCheckResponse,
+ GuardrailConfig,
+ GuardrailConfigData,
+ GuardrailConfigFilter,
+ GuardrailConfigFilterDescription,
+ GuardrailConfigFilterName,
+ GuardrailConfigsPage,
+ GuardrailsAiRailConfig,
+ GuardrailsAiValidatorConfig,
+ GuardrailsDataInput,
+ GuardrailsDataInputConfig,
+ GuardrailsDataOutput,
+ HttpValidationError,
+ HuggingfaceStorageConfig,
+ HuggingfaceStorageConfigRepoType,
+ ImagePullSecret,
+ ImageUrl,
+ ImageUrlDetail,
+ InferenceParams,
+ IngestResponse,
+ InjectionDetection,
+ InputRails,
+ Instruction,
+ JailbreakDetectionConfig,
+ JobExecutionProfileConfig,
+ K8SNimOperatorConfig,
+ KubernetesEmptyDirVolume,
+ KubernetesJobExecutionProfile,
+ KubernetesJobExecutionProfileConfig,
+ KubernetesJobStorageConfig,
+ KubernetesObjectMetadata,
+ KubernetesPersistentVolumeClaim,
+ KubernetesVolume,
+ KubernetesVolumeMount,
+ LabelAnnotation,
+ LabelAnnotationInput,
+ LabelAnnotationInputValue,
+ LabelAnnotationInputValueType,
+ LabelAnnotationValue,
+ LabelAnnotationValueType,
+ LinearLayerSpec,
+ ListFilesetFilesResponse,
+ LlmCallInfo,
+ LocalStorageConfig,
+ LogAdapterConfig,
+ Lora,
+ MambaConfig,
+ MessageTemplate,
+ MetadataAnnotation,
+ MetadataAnnotationInput,
+ MiddlewareCall,
+ MoEConfig,
+ Model,
+ ModelCacheConfig,
+ ModelDeployment,
+ ModelDeploymentConfig,
+ ModelDeploymentConfigFilter,
+ ModelDeploymentConfigFilterDescription,
+ ModelDeploymentConfigFilterName,
+ ModelDeploymentConfigModelSpec,
+ ModelDeploymentConfigsPage,
+ ModelDeploymentFilter,
+ ModelDeploymentFilterConfig,
+ ModelDeploymentFilterName,
+ ModelDeploymentFilterStatusMessage,
+ ModelDeploymentStatus,
+ ModelDeploymentStatusHistoryItem,
+ ModelDeploymentsPage,
+ ModelEntity,
+ ModelEntityFilter,
+ ModelEntityFilterAdapters,
+ ModelEntityFilterBaseModel,
+ ModelEntityFilterDescription,
+ ModelEntityFilterFinetuningType,
+ ModelEntityFilterName,
+ ModelEntitySortField,
+ ModelEntitysPage,
+ ModelMetadataContent,
+ ModelMode,
+ ModelParameters,
+ ModelProvider,
+ ModelProviderFilter,
+ ModelProviderFilterDescription,
+ ModelProviderFilterHostUrl,
+ ModelProviderFilterName,
+ ModelProviderSort,
+ ModelProviderStatus,
+ ModelProvidersPage,
+ ModelSpec,
+ ModelType,
+ MultilingualConfig,
+ NgcStorageConfig,
+ NgcStorageConfigTargetType,
+ NoteAnnotation,
+ NoteAnnotationInput,
+ NumericFilter,
+ OidcDiscoveryResponse,
+ OpenAiListModelsResp,
+ OpenAiModelResp,
+ OtelExportLogsPartialSuccess,
+ OtelExportLogsServiceResponse,
+ OutputRails,
+ OutputRailsStreamingConfig,
+ PaginationData,
+ PangeaRailConfig,
+ PangeaRailOptions,
+ PatronusEvaluateApiParams,
+ PatronusEvaluateConfigInput,
+ PatronusEvaluateConfigOutput,
+ PatronusEvaluationSuccessStrategy,
+ PatronusRailConfigInput,
+ PatronusRailConfigOutput,
+ PlatformJobEnvironmentVariable,
+ PlatformJobListResultResponse,
+ PlatformJobListTaskResponse,
+ PlatformJobLog,
+ PlatformJobLogPage,
+ PlatformJobResponse,
+ PlatformJobResponsesPage,
+ PlatformJobResultResponse,
+ PlatformJobSecretEnvironmentVariableRef,
+ PlatformJobSortField,
+ PlatformJobSpecInput,
+ PlatformJobSpecOutput,
+ PlatformJobStatus,
+ PlatformJobStatusResponse,
+ PlatformJobStep,
+ PlatformJobStepSpecInput,
+ PlatformJobStepSpecInputExecutor,
+ PlatformJobStepSpecInputExecutor_Cpu,
+ PlatformJobStepSpecInputExecutor_Gpu,
+ PlatformJobStepSpecInputExecutor_GpuDistributed,
+ PlatformJobStepSpecInputExecutor_Subprocess,
+ PlatformJobStepSpecOutput,
+ PlatformJobStepSpecOutputExecutor,
+ PlatformJobStepSpecOutputExecutor_Cpu,
+ PlatformJobStepSpecOutputExecutor_Gpu,
+ PlatformJobStepSpecOutputExecutor_GpuDistributed,
+ PlatformJobStepSpecOutputExecutor_Subprocess,
+ PlatformJobStepStatusResponse,
+ PlatformJobStepWithContext,
+ PlatformJobStepWithContextsPage,
+ PlatformJobStepsListFilter,
+ PlatformJobTask,
+ PlatformJobTaskStatusResponse,
+ PlatformJobsListFilter,
+ PlatformJobsListFilterName,
+ PlatformJobsListFilterSource,
+ PlatformJobsListFilterStatus,
+ PlatformSecretAccessResponse,
+ PlatformSecretAdminRotationResponse,
+ PlatformSecretResponse,
+ PlatformSecretResponsesPage,
+ PrivateAiDetection,
+ PrivateAiDetectionOptions,
+ Project,
+ ProjectSortField,
+ ProjectsPage,
+ PromptData,
+ RailStatus,
+ RailsConfigDataInput,
+ RailsConfigDataOutput,
+ RailsConfigInput,
+ RailsConfigOutput,
+ RailsInput,
+ RailsOutput,
+ ReasoningConfig,
+ RegexDetection,
+ RegexDetectionOptions,
+ RetrievalRails,
+ RoleBinding,
+ RoleBindingFilter,
+ RoleBindingFilterGrantedBy,
+ RoleBindingFilterPrincipal,
+ RoleBindingFilterRole,
+ RoleBindingsPage,
+ S3StorageConfig,
+ S3StorageConfigSignatureVersion,
+ SecretRef,
+ SensitiveDataDetection,
+ SensitiveDataDetectionOptions,
+ ServedModelMapping,
+ SingleCallConfig,
+ SlidingWindowConfig,
+ Span,
+ SpanEvaluationContext,
+ SpanFilter,
+ SpanKind,
+ SpanSortField,
+ SpanStatus,
+ SpansPage,
+ StatusEnum,
+ StepLifecycle,
+ StorageConfigType,
+ StringFilter,
+ SubprocessExecutionProvider,
+ SubprocessJobExecutionProfile,
+ SubprocessJobExecutionProfileConfig,
+ SubprocessJobExecutionProfileProvider,
+ TaskPrompt,
+ TaskPromptMessagesItem,
+ ToolCallConfig,
+ ToolCallingMetadataContent,
+ ToolInputRails,
+ ToolOutputRails,
+ Trace,
+ TraceFilter,
+ TraceSortField,
+ TracesPage,
+ TracingConfig,
+ TrendMicroRailConfig,
+ UpdateAdapterRequest,
+ UserMessagesConfig,
+ ValidationError,
+ ValidationErrorLocItem,
+ VirtualModel,
+ VirtualModelInferenceConfig,
+ VirtualModelsPage,
+ VolcanoJobExecutionProfile,
+ VolcanoJobExecutionProfileConfig,
+ Workspace,
+ WorkspaceMember,
+ WorkspaceMemberListResponse,
+ WorkspacesPage,
+ )
+ from .errors import (
+ BadRequestError,
+ ConflictError,
+ InternalServerError,
+ NotFoundError,
+ ServiceUnavailableError,
+ UnprocessableEntityError,
+ )
+ from . import (
+ adapters,
+ annotations,
+ discovery,
+ entity_store,
+ evaluator_results,
+ experiment_groups,
+ experiments,
+ files,
+ guardrails,
+ iam,
+ inference_gateway,
+ ingest,
+ jobs,
+ model_deployment_configs,
+ model_deployments,
+ model_providers,
+ models,
+ otlp,
+ secrets,
+ secrets_admin,
+ spans,
+ traces,
+ virtual_models,
+ )
+ from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient
+ from .client import AsyncNvidiaApi, NvidiaApi
+ from .experiment_groups import ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort
+ from .experiments import ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort
+ from .files import (
+ CreateFilesetRequestStorage,
+ CreateFilesetRequestStorage_Huggingface,
+ CreateFilesetRequestStorage_Local,
+ CreateFilesetRequestStorage_Ngc,
+ CreateFilesetRequestStorage_S3,
+ )
+ from .guardrails import (
+ GuardrailCheckRequestFunctionCall,
+ GuardrailCheckRequestMessagesItem,
+ GuardrailCheckRequestMessagesItem_Assistant,
+ GuardrailCheckRequestMessagesItem_Function,
+ GuardrailCheckRequestMessagesItem_System,
+ GuardrailCheckRequestMessagesItem_Tool,
+ GuardrailCheckRequestMessagesItem_User,
+ GuardrailCheckRequestStop,
+ GuardrailCheckRequestToolChoice,
+ )
+ from .ingest import AtifIngestRequestSchemaVersion
+ from .jobs import (
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob,
+ )
+ from .spans import ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode
+ from .traces import (
+ GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode,
+ ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "ActionRails": ".types",
+ "ActivatedRail": ".types",
+ "Adapter": ".types",
+ "AdapterEntityFilter": ".types",
+ "AdapterEntityFilterDescription": ".types",
+ "AdapterEntityFilterModel": ".types",
+ "AdapterEntityFilterName": ".types",
+ "AdaptersPage": ".types",
+ "AiDefenseRailConfig": ".types",
+ "Annotation": ".types",
+ "AnnotationFilter": ".types",
+ "AnnotationInput": ".types",
+ "AnnotationInput_Feedback": ".types",
+ "AnnotationInput_Label": ".types",
+ "AnnotationInput_Metadata": ".types",
+ "AnnotationInput_Note": ".types",
+ "AnnotationKind": ".types",
+ "AnnotationSortField": ".types",
+ "Annotation_Feedback": ".types",
+ "Annotation_Label": ".types",
+ "Annotation_Metadata": ".types",
+ "Annotation_Note": ".types",
+ "AnnotationsPage": ".types",
+ "ApiEndpointData": ".types",
+ "AsyncNvidiaApi": ".client",
+ "AtifAgent": ".types",
+ "AtifContentPart": ".types",
+ "AtifContentPartImage": ".types",
+ "AtifContentPartText": ".types",
+ "AtifContentPart_Image": ".types",
+ "AtifContentPart_Text": ".types",
+ "AtifFinalMetrics": ".types",
+ "AtifImageSource": ".types",
+ "AtifImageSourceMediaType": ".types",
+ "AtifIngestRequestSchemaVersion": ".ingest",
+ "AtifMetrics": ".types",
+ "AtifObservation": ".types",
+ "AtifObservationResult": ".types",
+ "AtifObservationResultContent": ".types",
+ "AtifStep": ".types",
+ "AtifStepAgent": ".types",
+ "AtifStepAgentMessage": ".types",
+ "AtifStepAgentReasoningEffort": ".types",
+ "AtifStepSystem": ".types",
+ "AtifStepSystemMessage": ".types",
+ "AtifStepUser": ".types",
+ "AtifStepUserMessage": ".types",
+ "AtifStep_Agent": ".types",
+ "AtifStep_System": ".types",
+ "AtifStep_User": ".types",
+ "AtifSubagentTrajectoryRef": ".types",
+ "AtifToolCall": ".types",
+ "AuthContext": ".types",
+ "AuthDiscoveryResponse": ".types",
+ "AutoAlignOptions": ".types",
+ "AutoAlignRailConfig": ".types",
+ "BackendFormat": ".types",
+ "BadRequestError": ".errors",
+ "BaseModelFilter": ".types",
+ "BaseModelFilterName": ".types",
+ "CacheStatsConfig": ".types",
+ "CacheStatus": ".types",
+ "CapturedChatCompletionsRequest": ".types",
+ "CapturedChatCompletionsResponse": ".types",
+ "CapturedChatMessage": ".types",
+ "ChatCompletionAssistantMessageParam": ".types",
+ "ChatCompletionContentPartImageParam": ".types",
+ "ChatCompletionContentPartTextParam": ".types",
+ "ChatCompletionFunctionMessageParam": ".types",
+ "ChatCompletionMessageToolCallParam": ".types",
+ "ChatCompletionMessageToolCallParamType": ".types",
+ "ChatCompletionSystemMessageParam": ".types",
+ "ChatCompletionToolMessageParam": ".types",
+ "ChatCompletionUserMessageParam": ".types",
+ "ChatCompletionUserMessageParamContent": ".types",
+ "ChatCompletionUserMessageParamContentOneItem": ".types",
+ "ChatCompletionUserMessageParamContentOneItem_ImageUrl": ".types",
+ "ChatCompletionUserMessageParamContentOneItem_Text": ".types",
+ "ChatCompletionsIngestResponse": ".types",
+ "ChatMessageRole": ".types",
+ "ClavataRailConfig": ".types",
+ "ClavataRailConfigLabelMatchLogic": ".types",
+ "ClavataRailOptions": ".types",
+ "ComputeResourceSpec": ".types",
+ "ComputeResources": ".types",
+ "ConflictError": ".errors",
+ "ContainerExecutorConfig": ".types",
+ "ContainerSpec": ".types",
+ "ContentSafetyConfig": ".types",
+ "CpuExecutionProviderInput": ".types",
+ "CpuExecutionProviderOutput": ".types",
+ "CreateFilesetRequestStorage": ".files",
+ "CreateFilesetRequestStorage_Huggingface": ".files",
+ "CreateFilesetRequestStorage_Local": ".files",
+ "CreateFilesetRequestStorage_Ngc": ".files",
+ "CreateFilesetRequestStorage_S3": ".files",
+ "CrowdStrikeAidrRailConfig": ".types",
+ "DatasetMetadataContent": ".types",
+ "DatasetMetadataContentSchema": ".types",
+ "DatasetMetadataContentSchemasByPathValue": ".types",
+ "DateRangeFilter": ".types",
+ "DatetimeFilter": ".types",
+ "DefaultAioHttpClient": "._default_clients",
+ "DefaultAsyncHttpxClient": "._default_clients",
+ "DeleteResponse": ".types",
+ "DialogRails": ".types",
+ "DistributedGpuExecutionProviderInput": ".types",
+ "DistributedGpuExecutionProviderOutput": ".types",
+ "DockerJobExecutionProfile": ".types",
+ "DockerJobExecutionProfileConfig": ".types",
+ "DockerJobNetworkConfig": ".types",
+ "DockerJobStorageConfig": ".types",
+ "DockerVolumeMount": ".types",
+ "DockerVolumeMountKind": ".types",
+ "E2EJobExecutionProfile": ".types",
+ "Engine": ".types",
+ "EntitiesPage": ".types",
+ "Entity": ".types",
+ "EvaluationContext": ".types",
+ "EvaluatorAggregate": ".types",
+ "EvaluatorResult": ".types",
+ "EvaluatorResultDataType": ".types",
+ "EvaluatorResultFilter": ".types",
+ "EvaluatorResultSortField": ".types",
+ "EvaluatorResultsPage": ".types",
+ "ExecutedAction": ".types",
+ "ExperimentContext": ".types",
+ "ExperimentFilter": ".types",
+ "ExperimentGroupFilter": ".types",
+ "ExperimentGroupRequest": ".types",
+ "ExperimentGroupResponse": ".types",
+ "ExperimentGroupResponsesPage": ".types",
+ "ExperimentRequest": ".types",
+ "ExperimentResponse": ".types",
+ "ExperimentResponsesPage": ".types",
+ "ExperimentSessionFilter": ".types",
+ "ExperimentSessionResponse": ".types",
+ "ExperimentSessionResponsesPage": ".types",
+ "FactCheckingRailConfig": ".types",
+ "FeedbackAnnotation": ".types",
+ "FeedbackAnnotationInput": ".types",
+ "FeedbackAnnotationInputValue": ".types",
+ "FeedbackAnnotationValue": ".types",
+ "FiddlerGuardrails": ".types",
+ "FileStorageType": ".types",
+ "FilesetFileOutput": ".types",
+ "FilesetFilter": ".types",
+ "FilesetFilterDescription": ".types",
+ "FilesetFilterName": ".types",
+ "FilesetMetadataInput": ".types",
+ "FilesetMetadataOutput": ".types",
+ "FilesetOutput": ".types",
+ "FilesetOutputStorage": ".types",
+ "FilesetOutputStorage_Huggingface": ".types",
+ "FilesetOutputStorage_Local": ".types",
+ "FilesetOutputStorage_Ngc": ".types",
+ "FilesetOutputStorage_S3": ".types",
+ "FilesetOutputsPage": ".types",
+ "FilesetPurpose": ".types",
+ "FinetuningType": ".types",
+ "FinetuningTypeFilter": ".types",
+ "FloatFilter": ".types",
+ "Function": ".types",
+ "FunctionCall": ".types",
+ "GLiNerDetection": ".types",
+ "GLiNerDetectionOptions": ".types",
+ "GenerationLog": ".types",
+ "GenerationLogOptions": ".types",
+ "GenerationOptions": ".types",
+ "GenerationOptionsOutputVars": ".types",
+ "GenerationRailsOptions": ".types",
+ "GenerationRailsOptionsInput": ".types",
+ "GenerationRailsOptionsOutput": ".types",
+ "GenerationRailsOptionsRetrieval": ".types",
+ "GenerationStats": ".types",
+ "GenericSortField": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem": ".jobs",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker": ".jobs",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E": ".jobs",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob": ".jobs",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess": ".jobs",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob": ".jobs",
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode": ".traces",
+ "GpuExecutionProviderInput": ".types",
+ "GpuExecutionProviderOutput": ".types",
+ "GuardrailCheckRequestFunctionCall": ".guardrails",
+ "GuardrailCheckRequestMessagesItem": ".guardrails",
+ "GuardrailCheckRequestMessagesItem_Assistant": ".guardrails",
+ "GuardrailCheckRequestMessagesItem_Function": ".guardrails",
+ "GuardrailCheckRequestMessagesItem_System": ".guardrails",
+ "GuardrailCheckRequestMessagesItem_Tool": ".guardrails",
+ "GuardrailCheckRequestMessagesItem_User": ".guardrails",
+ "GuardrailCheckRequestStop": ".guardrails",
+ "GuardrailCheckRequestToolChoice": ".guardrails",
+ "GuardrailCheckResponse": ".types",
+ "GuardrailConfig": ".types",
+ "GuardrailConfigData": ".types",
+ "GuardrailConfigFilter": ".types",
+ "GuardrailConfigFilterDescription": ".types",
+ "GuardrailConfigFilterName": ".types",
+ "GuardrailConfigsPage": ".types",
+ "GuardrailsAiRailConfig": ".types",
+ "GuardrailsAiValidatorConfig": ".types",
+ "GuardrailsDataInput": ".types",
+ "GuardrailsDataInputConfig": ".types",
+ "GuardrailsDataOutput": ".types",
+ "HttpValidationError": ".types",
+ "HuggingfaceStorageConfig": ".types",
+ "HuggingfaceStorageConfigRepoType": ".types",
+ "ImagePullSecret": ".types",
+ "ImageUrl": ".types",
+ "ImageUrlDetail": ".types",
+ "InferenceParams": ".types",
+ "IngestResponse": ".types",
+ "InjectionDetection": ".types",
+ "InputRails": ".types",
+ "Instruction": ".types",
+ "InternalServerError": ".errors",
+ "JailbreakDetectionConfig": ".types",
+ "JobExecutionProfileConfig": ".types",
+ "K8SNimOperatorConfig": ".types",
+ "KubernetesEmptyDirVolume": ".types",
+ "KubernetesJobExecutionProfile": ".types",
+ "KubernetesJobExecutionProfileConfig": ".types",
+ "KubernetesJobStorageConfig": ".types",
+ "KubernetesObjectMetadata": ".types",
+ "KubernetesPersistentVolumeClaim": ".types",
+ "KubernetesVolume": ".types",
+ "KubernetesVolumeMount": ".types",
+ "LabelAnnotation": ".types",
+ "LabelAnnotationInput": ".types",
+ "LabelAnnotationInputValue": ".types",
+ "LabelAnnotationInputValueType": ".types",
+ "LabelAnnotationValue": ".types",
+ "LabelAnnotationValueType": ".types",
+ "LinearLayerSpec": ".types",
+ "ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort": ".experiment_groups",
+ "ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort": ".experiments",
+ "ListFilesetFilesResponse": ".types",
+ "ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode": ".spans",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode": ".traces",
+ "LlmCallInfo": ".types",
+ "LocalStorageConfig": ".types",
+ "LogAdapterConfig": ".types",
+ "Lora": ".types",
+ "MambaConfig": ".types",
+ "MessageTemplate": ".types",
+ "MetadataAnnotation": ".types",
+ "MetadataAnnotationInput": ".types",
+ "MiddlewareCall": ".types",
+ "MoEConfig": ".types",
+ "Model": ".types",
+ "ModelCacheConfig": ".types",
+ "ModelDeployment": ".types",
+ "ModelDeploymentConfig": ".types",
+ "ModelDeploymentConfigFilter": ".types",
+ "ModelDeploymentConfigFilterDescription": ".types",
+ "ModelDeploymentConfigFilterName": ".types",
+ "ModelDeploymentConfigModelSpec": ".types",
+ "ModelDeploymentConfigsPage": ".types",
+ "ModelDeploymentFilter": ".types",
+ "ModelDeploymentFilterConfig": ".types",
+ "ModelDeploymentFilterName": ".types",
+ "ModelDeploymentFilterStatusMessage": ".types",
+ "ModelDeploymentStatus": ".types",
+ "ModelDeploymentStatusHistoryItem": ".types",
+ "ModelDeploymentsPage": ".types",
+ "ModelEntity": ".types",
+ "ModelEntityFilter": ".types",
+ "ModelEntityFilterAdapters": ".types",
+ "ModelEntityFilterBaseModel": ".types",
+ "ModelEntityFilterDescription": ".types",
+ "ModelEntityFilterFinetuningType": ".types",
+ "ModelEntityFilterName": ".types",
+ "ModelEntitySortField": ".types",
+ "ModelEntitysPage": ".types",
+ "ModelMetadataContent": ".types",
+ "ModelMode": ".types",
+ "ModelParameters": ".types",
+ "ModelProvider": ".types",
+ "ModelProviderFilter": ".types",
+ "ModelProviderFilterDescription": ".types",
+ "ModelProviderFilterHostUrl": ".types",
+ "ModelProviderFilterName": ".types",
+ "ModelProviderSort": ".types",
+ "ModelProviderStatus": ".types",
+ "ModelProvidersPage": ".types",
+ "ModelSpec": ".types",
+ "ModelType": ".types",
+ "MultilingualConfig": ".types",
+ "NgcStorageConfig": ".types",
+ "NgcStorageConfigTargetType": ".types",
+ "NotFoundError": ".errors",
+ "NoteAnnotation": ".types",
+ "NoteAnnotationInput": ".types",
+ "NumericFilter": ".types",
+ "NvidiaApi": ".client",
+ "OidcDiscoveryResponse": ".types",
+ "OpenAiListModelsResp": ".types",
+ "OpenAiModelResp": ".types",
+ "OtelExportLogsPartialSuccess": ".types",
+ "OtelExportLogsServiceResponse": ".types",
+ "OutputRails": ".types",
+ "OutputRailsStreamingConfig": ".types",
+ "PaginationData": ".types",
+ "PangeaRailConfig": ".types",
+ "PangeaRailOptions": ".types",
+ "PatronusEvaluateApiParams": ".types",
+ "PatronusEvaluateConfigInput": ".types",
+ "PatronusEvaluateConfigOutput": ".types",
+ "PatronusEvaluationSuccessStrategy": ".types",
+ "PatronusRailConfigInput": ".types",
+ "PatronusRailConfigOutput": ".types",
+ "PlatformJobEnvironmentVariable": ".types",
+ "PlatformJobListResultResponse": ".types",
+ "PlatformJobListTaskResponse": ".types",
+ "PlatformJobLog": ".types",
+ "PlatformJobLogPage": ".types",
+ "PlatformJobResponse": ".types",
+ "PlatformJobResponsesPage": ".types",
+ "PlatformJobResultResponse": ".types",
+ "PlatformJobSecretEnvironmentVariableRef": ".types",
+ "PlatformJobSortField": ".types",
+ "PlatformJobSpecInput": ".types",
+ "PlatformJobSpecOutput": ".types",
+ "PlatformJobStatus": ".types",
+ "PlatformJobStatusResponse": ".types",
+ "PlatformJobStep": ".types",
+ "PlatformJobStepSpecInput": ".types",
+ "PlatformJobStepSpecInputExecutor": ".types",
+ "PlatformJobStepSpecInputExecutor_Cpu": ".types",
+ "PlatformJobStepSpecInputExecutor_Gpu": ".types",
+ "PlatformJobStepSpecInputExecutor_GpuDistributed": ".types",
+ "PlatformJobStepSpecInputExecutor_Subprocess": ".types",
+ "PlatformJobStepSpecOutput": ".types",
+ "PlatformJobStepSpecOutputExecutor": ".types",
+ "PlatformJobStepSpecOutputExecutor_Cpu": ".types",
+ "PlatformJobStepSpecOutputExecutor_Gpu": ".types",
+ "PlatformJobStepSpecOutputExecutor_GpuDistributed": ".types",
+ "PlatformJobStepSpecOutputExecutor_Subprocess": ".types",
+ "PlatformJobStepStatusResponse": ".types",
+ "PlatformJobStepWithContext": ".types",
+ "PlatformJobStepWithContextsPage": ".types",
+ "PlatformJobStepsListFilter": ".types",
+ "PlatformJobTask": ".types",
+ "PlatformJobTaskStatusResponse": ".types",
+ "PlatformJobsListFilter": ".types",
+ "PlatformJobsListFilterName": ".types",
+ "PlatformJobsListFilterSource": ".types",
+ "PlatformJobsListFilterStatus": ".types",
+ "PlatformSecretAccessResponse": ".types",
+ "PlatformSecretAdminRotationResponse": ".types",
+ "PlatformSecretResponse": ".types",
+ "PlatformSecretResponsesPage": ".types",
+ "PrivateAiDetection": ".types",
+ "PrivateAiDetectionOptions": ".types",
+ "Project": ".types",
+ "ProjectSortField": ".types",
+ "ProjectsPage": ".types",
+ "PromptData": ".types",
+ "RailStatus": ".types",
+ "RailsConfigDataInput": ".types",
+ "RailsConfigDataOutput": ".types",
+ "RailsConfigInput": ".types",
+ "RailsConfigOutput": ".types",
+ "RailsInput": ".types",
+ "RailsOutput": ".types",
+ "ReasoningConfig": ".types",
+ "RegexDetection": ".types",
+ "RegexDetectionOptions": ".types",
+ "RetrievalRails": ".types",
+ "RoleBinding": ".types",
+ "RoleBindingFilter": ".types",
+ "RoleBindingFilterGrantedBy": ".types",
+ "RoleBindingFilterPrincipal": ".types",
+ "RoleBindingFilterRole": ".types",
+ "RoleBindingsPage": ".types",
+ "S3StorageConfig": ".types",
+ "S3StorageConfigSignatureVersion": ".types",
+ "SecretRef": ".types",
+ "SensitiveDataDetection": ".types",
+ "SensitiveDataDetectionOptions": ".types",
+ "ServedModelMapping": ".types",
+ "ServiceUnavailableError": ".errors",
+ "SingleCallConfig": ".types",
+ "SlidingWindowConfig": ".types",
+ "Span": ".types",
+ "SpanEvaluationContext": ".types",
+ "SpanFilter": ".types",
+ "SpanKind": ".types",
+ "SpanSortField": ".types",
+ "SpanStatus": ".types",
+ "SpansPage": ".types",
+ "StatusEnum": ".types",
+ "StepLifecycle": ".types",
+ "StorageConfigType": ".types",
+ "StringFilter": ".types",
+ "SubprocessExecutionProvider": ".types",
+ "SubprocessJobExecutionProfile": ".types",
+ "SubprocessJobExecutionProfileConfig": ".types",
+ "SubprocessJobExecutionProfileProvider": ".types",
+ "TaskPrompt": ".types",
+ "TaskPromptMessagesItem": ".types",
+ "ToolCallConfig": ".types",
+ "ToolCallingMetadataContent": ".types",
+ "ToolInputRails": ".types",
+ "ToolOutputRails": ".types",
+ "Trace": ".types",
+ "TraceFilter": ".types",
+ "TraceSortField": ".types",
+ "TracesPage": ".types",
+ "TracingConfig": ".types",
+ "TrendMicroRailConfig": ".types",
+ "UnprocessableEntityError": ".errors",
+ "UpdateAdapterRequest": ".types",
+ "UserMessagesConfig": ".types",
+ "ValidationError": ".types",
+ "ValidationErrorLocItem": ".types",
+ "VirtualModel": ".types",
+ "VirtualModelInferenceConfig": ".types",
+ "VirtualModelsPage": ".types",
+ "VolcanoJobExecutionProfile": ".types",
+ "VolcanoJobExecutionProfileConfig": ".types",
+ "Workspace": ".types",
+ "WorkspaceMember": ".types",
+ "WorkspaceMemberListResponse": ".types",
+ "WorkspacesPage": ".types",
+ "adapters": ".adapters",
+ "annotations": ".annotations",
+ "discovery": ".discovery",
+ "entity_store": ".entity_store",
+ "evaluator_results": ".evaluator_results",
+ "experiment_groups": ".experiment_groups",
+ "experiments": ".experiments",
+ "files": ".files",
+ "guardrails": ".guardrails",
+ "iam": ".iam",
+ "inference_gateway": ".inference_gateway",
+ "ingest": ".ingest",
+ "jobs": ".jobs",
+ "model_deployment_configs": ".model_deployment_configs",
+ "model_deployments": ".model_deployments",
+ "model_providers": ".model_providers",
+ "models": ".models",
+ "otlp": ".otlp",
+ "secrets": ".secrets",
+ "secrets_admin": ".secrets_admin",
+ "spans": ".spans",
+ "traces": ".traces",
+ "virtual_models": ".virtual_models",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "ActionRails",
+ "ActivatedRail",
+ "Adapter",
+ "AdapterEntityFilter",
+ "AdapterEntityFilterDescription",
+ "AdapterEntityFilterModel",
+ "AdapterEntityFilterName",
+ "AdaptersPage",
+ "AiDefenseRailConfig",
+ "Annotation",
+ "AnnotationFilter",
+ "AnnotationInput",
+ "AnnotationInput_Feedback",
+ "AnnotationInput_Label",
+ "AnnotationInput_Metadata",
+ "AnnotationInput_Note",
+ "AnnotationKind",
+ "AnnotationSortField",
+ "Annotation_Feedback",
+ "Annotation_Label",
+ "Annotation_Metadata",
+ "Annotation_Note",
+ "AnnotationsPage",
+ "ApiEndpointData",
+ "AsyncNvidiaApi",
+ "AtifAgent",
+ "AtifContentPart",
+ "AtifContentPartImage",
+ "AtifContentPartText",
+ "AtifContentPart_Image",
+ "AtifContentPart_Text",
+ "AtifFinalMetrics",
+ "AtifImageSource",
+ "AtifImageSourceMediaType",
+ "AtifIngestRequestSchemaVersion",
+ "AtifMetrics",
+ "AtifObservation",
+ "AtifObservationResult",
+ "AtifObservationResultContent",
+ "AtifStep",
+ "AtifStepAgent",
+ "AtifStepAgentMessage",
+ "AtifStepAgentReasoningEffort",
+ "AtifStepSystem",
+ "AtifStepSystemMessage",
+ "AtifStepUser",
+ "AtifStepUserMessage",
+ "AtifStep_Agent",
+ "AtifStep_System",
+ "AtifStep_User",
+ "AtifSubagentTrajectoryRef",
+ "AtifToolCall",
+ "AuthContext",
+ "AuthDiscoveryResponse",
+ "AutoAlignOptions",
+ "AutoAlignRailConfig",
+ "BackendFormat",
+ "BadRequestError",
+ "BaseModelFilter",
+ "BaseModelFilterName",
+ "CacheStatsConfig",
+ "CacheStatus",
+ "CapturedChatCompletionsRequest",
+ "CapturedChatCompletionsResponse",
+ "CapturedChatMessage",
+ "ChatCompletionAssistantMessageParam",
+ "ChatCompletionContentPartImageParam",
+ "ChatCompletionContentPartTextParam",
+ "ChatCompletionFunctionMessageParam",
+ "ChatCompletionMessageToolCallParam",
+ "ChatCompletionMessageToolCallParamType",
+ "ChatCompletionSystemMessageParam",
+ "ChatCompletionToolMessageParam",
+ "ChatCompletionUserMessageParam",
+ "ChatCompletionUserMessageParamContent",
+ "ChatCompletionUserMessageParamContentOneItem",
+ "ChatCompletionUserMessageParamContentOneItem_ImageUrl",
+ "ChatCompletionUserMessageParamContentOneItem_Text",
+ "ChatCompletionsIngestResponse",
+ "ChatMessageRole",
+ "ClavataRailConfig",
+ "ClavataRailConfigLabelMatchLogic",
+ "ClavataRailOptions",
+ "ComputeResourceSpec",
+ "ComputeResources",
+ "ConflictError",
+ "ContainerExecutorConfig",
+ "ContainerSpec",
+ "ContentSafetyConfig",
+ "CpuExecutionProviderInput",
+ "CpuExecutionProviderOutput",
+ "CreateFilesetRequestStorage",
+ "CreateFilesetRequestStorage_Huggingface",
+ "CreateFilesetRequestStorage_Local",
+ "CreateFilesetRequestStorage_Ngc",
+ "CreateFilesetRequestStorage_S3",
+ "CrowdStrikeAidrRailConfig",
+ "DatasetMetadataContent",
+ "DatasetMetadataContentSchema",
+ "DatasetMetadataContentSchemasByPathValue",
+ "DateRangeFilter",
+ "DatetimeFilter",
+ "DefaultAioHttpClient",
+ "DefaultAsyncHttpxClient",
+ "DeleteResponse",
+ "DialogRails",
+ "DistributedGpuExecutionProviderInput",
+ "DistributedGpuExecutionProviderOutput",
+ "DockerJobExecutionProfile",
+ "DockerJobExecutionProfileConfig",
+ "DockerJobNetworkConfig",
+ "DockerJobStorageConfig",
+ "DockerVolumeMount",
+ "DockerVolumeMountKind",
+ "E2EJobExecutionProfile",
+ "Engine",
+ "EntitiesPage",
+ "Entity",
+ "EvaluationContext",
+ "EvaluatorAggregate",
+ "EvaluatorResult",
+ "EvaluatorResultDataType",
+ "EvaluatorResultFilter",
+ "EvaluatorResultSortField",
+ "EvaluatorResultsPage",
+ "ExecutedAction",
+ "ExperimentContext",
+ "ExperimentFilter",
+ "ExperimentGroupFilter",
+ "ExperimentGroupRequest",
+ "ExperimentGroupResponse",
+ "ExperimentGroupResponsesPage",
+ "ExperimentRequest",
+ "ExperimentResponse",
+ "ExperimentResponsesPage",
+ "ExperimentSessionFilter",
+ "ExperimentSessionResponse",
+ "ExperimentSessionResponsesPage",
+ "FactCheckingRailConfig",
+ "FeedbackAnnotation",
+ "FeedbackAnnotationInput",
+ "FeedbackAnnotationInputValue",
+ "FeedbackAnnotationValue",
+ "FiddlerGuardrails",
+ "FileStorageType",
+ "FilesetFileOutput",
+ "FilesetFilter",
+ "FilesetFilterDescription",
+ "FilesetFilterName",
+ "FilesetMetadataInput",
+ "FilesetMetadataOutput",
+ "FilesetOutput",
+ "FilesetOutputStorage",
+ "FilesetOutputStorage_Huggingface",
+ "FilesetOutputStorage_Local",
+ "FilesetOutputStorage_Ngc",
+ "FilesetOutputStorage_S3",
+ "FilesetOutputsPage",
+ "FilesetPurpose",
+ "FinetuningType",
+ "FinetuningTypeFilter",
+ "FloatFilter",
+ "Function",
+ "FunctionCall",
+ "GLiNerDetection",
+ "GLiNerDetectionOptions",
+ "GenerationLog",
+ "GenerationLogOptions",
+ "GenerationOptions",
+ "GenerationOptionsOutputVars",
+ "GenerationRailsOptions",
+ "GenerationRailsOptionsInput",
+ "GenerationRailsOptionsOutput",
+ "GenerationRailsOptionsRetrieval",
+ "GenerationStats",
+ "GenericSortField",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob",
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode",
+ "GpuExecutionProviderInput",
+ "GpuExecutionProviderOutput",
+ "GuardrailCheckRequestFunctionCall",
+ "GuardrailCheckRequestMessagesItem",
+ "GuardrailCheckRequestMessagesItem_Assistant",
+ "GuardrailCheckRequestMessagesItem_Function",
+ "GuardrailCheckRequestMessagesItem_System",
+ "GuardrailCheckRequestMessagesItem_Tool",
+ "GuardrailCheckRequestMessagesItem_User",
+ "GuardrailCheckRequestStop",
+ "GuardrailCheckRequestToolChoice",
+ "GuardrailCheckResponse",
+ "GuardrailConfig",
+ "GuardrailConfigData",
+ "GuardrailConfigFilter",
+ "GuardrailConfigFilterDescription",
+ "GuardrailConfigFilterName",
+ "GuardrailConfigsPage",
+ "GuardrailsAiRailConfig",
+ "GuardrailsAiValidatorConfig",
+ "GuardrailsDataInput",
+ "GuardrailsDataInputConfig",
+ "GuardrailsDataOutput",
+ "HttpValidationError",
+ "HuggingfaceStorageConfig",
+ "HuggingfaceStorageConfigRepoType",
+ "ImagePullSecret",
+ "ImageUrl",
+ "ImageUrlDetail",
+ "InferenceParams",
+ "IngestResponse",
+ "InjectionDetection",
+ "InputRails",
+ "Instruction",
+ "InternalServerError",
+ "JailbreakDetectionConfig",
+ "JobExecutionProfileConfig",
+ "K8SNimOperatorConfig",
+ "KubernetesEmptyDirVolume",
+ "KubernetesJobExecutionProfile",
+ "KubernetesJobExecutionProfileConfig",
+ "KubernetesJobStorageConfig",
+ "KubernetesObjectMetadata",
+ "KubernetesPersistentVolumeClaim",
+ "KubernetesVolume",
+ "KubernetesVolumeMount",
+ "LabelAnnotation",
+ "LabelAnnotationInput",
+ "LabelAnnotationInputValue",
+ "LabelAnnotationInputValueType",
+ "LabelAnnotationValue",
+ "LabelAnnotationValueType",
+ "LinearLayerSpec",
+ "ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort",
+ "ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort",
+ "ListFilesetFilesResponse",
+ "ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode",
+ "LlmCallInfo",
+ "LocalStorageConfig",
+ "LogAdapterConfig",
+ "Lora",
+ "MambaConfig",
+ "MessageTemplate",
+ "MetadataAnnotation",
+ "MetadataAnnotationInput",
+ "MiddlewareCall",
+ "MoEConfig",
+ "Model",
+ "ModelCacheConfig",
+ "ModelDeployment",
+ "ModelDeploymentConfig",
+ "ModelDeploymentConfigFilter",
+ "ModelDeploymentConfigFilterDescription",
+ "ModelDeploymentConfigFilterName",
+ "ModelDeploymentConfigModelSpec",
+ "ModelDeploymentConfigsPage",
+ "ModelDeploymentFilter",
+ "ModelDeploymentFilterConfig",
+ "ModelDeploymentFilterName",
+ "ModelDeploymentFilterStatusMessage",
+ "ModelDeploymentStatus",
+ "ModelDeploymentStatusHistoryItem",
+ "ModelDeploymentsPage",
+ "ModelEntity",
+ "ModelEntityFilter",
+ "ModelEntityFilterAdapters",
+ "ModelEntityFilterBaseModel",
+ "ModelEntityFilterDescription",
+ "ModelEntityFilterFinetuningType",
+ "ModelEntityFilterName",
+ "ModelEntitySortField",
+ "ModelEntitysPage",
+ "ModelMetadataContent",
+ "ModelMode",
+ "ModelParameters",
+ "ModelProvider",
+ "ModelProviderFilter",
+ "ModelProviderFilterDescription",
+ "ModelProviderFilterHostUrl",
+ "ModelProviderFilterName",
+ "ModelProviderSort",
+ "ModelProviderStatus",
+ "ModelProvidersPage",
+ "ModelSpec",
+ "ModelType",
+ "MultilingualConfig",
+ "NgcStorageConfig",
+ "NgcStorageConfigTargetType",
+ "NotFoundError",
+ "NoteAnnotation",
+ "NoteAnnotationInput",
+ "NumericFilter",
+ "NvidiaApi",
+ "OidcDiscoveryResponse",
+ "OpenAiListModelsResp",
+ "OpenAiModelResp",
+ "OtelExportLogsPartialSuccess",
+ "OtelExportLogsServiceResponse",
+ "OutputRails",
+ "OutputRailsStreamingConfig",
+ "PaginationData",
+ "PangeaRailConfig",
+ "PangeaRailOptions",
+ "PatronusEvaluateApiParams",
+ "PatronusEvaluateConfigInput",
+ "PatronusEvaluateConfigOutput",
+ "PatronusEvaluationSuccessStrategy",
+ "PatronusRailConfigInput",
+ "PatronusRailConfigOutput",
+ "PlatformJobEnvironmentVariable",
+ "PlatformJobListResultResponse",
+ "PlatformJobListTaskResponse",
+ "PlatformJobLog",
+ "PlatformJobLogPage",
+ "PlatformJobResponse",
+ "PlatformJobResponsesPage",
+ "PlatformJobResultResponse",
+ "PlatformJobSecretEnvironmentVariableRef",
+ "PlatformJobSortField",
+ "PlatformJobSpecInput",
+ "PlatformJobSpecOutput",
+ "PlatformJobStatus",
+ "PlatformJobStatusResponse",
+ "PlatformJobStep",
+ "PlatformJobStepSpecInput",
+ "PlatformJobStepSpecInputExecutor",
+ "PlatformJobStepSpecInputExecutor_Cpu",
+ "PlatformJobStepSpecInputExecutor_Gpu",
+ "PlatformJobStepSpecInputExecutor_GpuDistributed",
+ "PlatformJobStepSpecInputExecutor_Subprocess",
+ "PlatformJobStepSpecOutput",
+ "PlatformJobStepSpecOutputExecutor",
+ "PlatformJobStepSpecOutputExecutor_Cpu",
+ "PlatformJobStepSpecOutputExecutor_Gpu",
+ "PlatformJobStepSpecOutputExecutor_GpuDistributed",
+ "PlatformJobStepSpecOutputExecutor_Subprocess",
+ "PlatformJobStepStatusResponse",
+ "PlatformJobStepWithContext",
+ "PlatformJobStepWithContextsPage",
+ "PlatformJobStepsListFilter",
+ "PlatformJobTask",
+ "PlatformJobTaskStatusResponse",
+ "PlatformJobsListFilter",
+ "PlatformJobsListFilterName",
+ "PlatformJobsListFilterSource",
+ "PlatformJobsListFilterStatus",
+ "PlatformSecretAccessResponse",
+ "PlatformSecretAdminRotationResponse",
+ "PlatformSecretResponse",
+ "PlatformSecretResponsesPage",
+ "PrivateAiDetection",
+ "PrivateAiDetectionOptions",
+ "Project",
+ "ProjectSortField",
+ "ProjectsPage",
+ "PromptData",
+ "RailStatus",
+ "RailsConfigDataInput",
+ "RailsConfigDataOutput",
+ "RailsConfigInput",
+ "RailsConfigOutput",
+ "RailsInput",
+ "RailsOutput",
+ "ReasoningConfig",
+ "RegexDetection",
+ "RegexDetectionOptions",
+ "RetrievalRails",
+ "RoleBinding",
+ "RoleBindingFilter",
+ "RoleBindingFilterGrantedBy",
+ "RoleBindingFilterPrincipal",
+ "RoleBindingFilterRole",
+ "RoleBindingsPage",
+ "S3StorageConfig",
+ "S3StorageConfigSignatureVersion",
+ "SecretRef",
+ "SensitiveDataDetection",
+ "SensitiveDataDetectionOptions",
+ "ServedModelMapping",
+ "ServiceUnavailableError",
+ "SingleCallConfig",
+ "SlidingWindowConfig",
+ "Span",
+ "SpanEvaluationContext",
+ "SpanFilter",
+ "SpanKind",
+ "SpanSortField",
+ "SpanStatus",
+ "SpansPage",
+ "StatusEnum",
+ "StepLifecycle",
+ "StorageConfigType",
+ "StringFilter",
+ "SubprocessExecutionProvider",
+ "SubprocessJobExecutionProfile",
+ "SubprocessJobExecutionProfileConfig",
+ "SubprocessJobExecutionProfileProvider",
+ "TaskPrompt",
+ "TaskPromptMessagesItem",
+ "ToolCallConfig",
+ "ToolCallingMetadataContent",
+ "ToolInputRails",
+ "ToolOutputRails",
+ "Trace",
+ "TraceFilter",
+ "TraceSortField",
+ "TracesPage",
+ "TracingConfig",
+ "TrendMicroRailConfig",
+ "UnprocessableEntityError",
+ "UpdateAdapterRequest",
+ "UserMessagesConfig",
+ "ValidationError",
+ "ValidationErrorLocItem",
+ "VirtualModel",
+ "VirtualModelInferenceConfig",
+ "VirtualModelsPage",
+ "VolcanoJobExecutionProfile",
+ "VolcanoJobExecutionProfileConfig",
+ "Workspace",
+ "WorkspaceMember",
+ "WorkspaceMemberListResponse",
+ "WorkspacesPage",
+ "adapters",
+ "annotations",
+ "discovery",
+ "entity_store",
+ "evaluator_results",
+ "experiment_groups",
+ "experiments",
+ "files",
+ "guardrails",
+ "iam",
+ "inference_gateway",
+ "ingest",
+ "jobs",
+ "model_deployment_configs",
+ "model_deployments",
+ "model_providers",
+ "models",
+ "otlp",
+ "secrets",
+ "secrets_admin",
+ "spans",
+ "traces",
+ "virtual_models",
+]
diff --git a/sdks/python/_default_clients.py b/sdks/python/_default_clients.py
new file mode 100644
index 0000000000..a11056075f
--- /dev/null
+++ b/sdks/python/_default_clients.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import httpx
+
+SDK_DEFAULT_TIMEOUT = 60
+
+try:
+ import httpx_aiohttp # type: ignore[import-not-found]
+except ImportError:
+
+ class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore
+ def __init__(self, **kwargs: typing.Any) -> None:
+ raise RuntimeError("To use the aiohttp client, install the aiohttp extra: pip install nvidia[aiohttp]")
+
+else:
+
+ class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
+ def __init__(self, **kwargs: typing.Any) -> None:
+ kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
+ kwargs.setdefault("follow_redirects", True)
+ super().__init__(**kwargs)
+
+
+class DefaultAsyncHttpxClient(httpx.AsyncClient):
+ def __init__(self, **kwargs: typing.Any) -> None:
+ kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
+ kwargs.setdefault("follow_redirects", True)
+ super().__init__(**kwargs)
diff --git a/sdks/python/adapters/__init__.py b/sdks/python/adapters/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/adapters/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/adapters/client.py b/sdks/python/adapters/client.py
new file mode 100644
index 0000000000..d8669e6822
--- /dev/null
+++ b/sdks/python/adapters/client.py
@@ -0,0 +1,577 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.adapter import Adapter
+from ..types.adapter_entity_filter import AdapterEntityFilter
+from ..types.adapters_page import AdaptersPage
+from ..types.finetuning_type import FinetuningType
+from ..types.lora import Lora
+from .raw_client import AsyncRawAdaptersClient, RawAdaptersClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class AdaptersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawAdaptersClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawAdaptersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawAdaptersClient
+ """
+ return self._raw_client
+
+ def list_adapters(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[AdapterEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AdaptersPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[AdapterEntityFilter]
+ Filter adapters by name, model (parent model ref string, stored on the adapter), description, fileset, finetuning_type, enabled, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AdaptersPage
+ List adapters in the workspace
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.adapters.list_adapters(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_adapters(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_adapter(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ model: str,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Create an adapter under a base model specified by the "model" field in the body.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ model : str
+ Base model entity.
+ Use `{workspace}/{model_name}` to reference a model in any workspace, or a single `{model_name}` resolved in the path workspace. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Create a new adapter for a model
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.adapters.create_adapter(
+ workspace="workspace",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+ model="llama-3-8b-instruct",
+ )
+ """
+ _response = self._raw_client.create_adapter(
+ workspace,
+ name=name,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ model=model,
+ description=description,
+ enabled=enabled,
+ lora_config=lora_config,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Adapter:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Get one adapter by name. Parent model is taken from the adapter's stored parent (entity `parent` field).
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.adapters.get_adapter(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_adapter(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.adapters.delete_adapter(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_adapter(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_adapter(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Update adapter metadata. Updates are applied to the row identified by the adapter's stored parent (entity `parent` field).
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.adapters.update_adapter(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_adapter(
+ workspace, name, description=description, enabled=enabled, fileset=fileset, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncAdaptersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawAdaptersClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawAdaptersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawAdaptersClient
+ """
+ return self._raw_client
+
+ async def list_adapters(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[AdapterEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AdaptersPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[AdapterEntityFilter]
+ Filter adapters by name, model (parent model ref string, stored on the adapter), description, fileset, finetuning_type, enabled, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AdaptersPage
+ List adapters in the workspace
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.adapters.list_adapters(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_adapters(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_adapter(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ model: str,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Create an adapter under a base model specified by the "model" field in the body.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ model : str
+ Base model entity.
+ Use `{workspace}/{model_name}` to reference a model in any workspace, or a single `{model_name}` resolved in the path workspace. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Create a new adapter for a model
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.adapters.create_adapter(
+ workspace="workspace",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+ model="llama-3-8b-instruct",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_adapter(
+ workspace,
+ name=name,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ model=model,
+ description=description,
+ enabled=enabled,
+ lora_config=lora_config,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Adapter:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Get one adapter by name. Parent model is taken from the adapter's stored parent (entity `parent` field).
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.adapters.get_adapter(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_adapter(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.adapters.delete_adapter(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_adapter(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_adapter(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Update adapter metadata. Updates are applied to the row identified by the adapter's stored parent (entity `parent` field).
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.adapters.update_adapter(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_adapter(
+ workspace, name, description=description, enabled=enabled, fileset=fileset, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/adapters/raw_client.py b/sdks/python/adapters/raw_client.py
new file mode 100644
index 0000000000..34b5790cab
--- /dev/null
+++ b/sdks/python/adapters/raw_client.py
@@ -0,0 +1,741 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.adapter import Adapter
+from ..types.adapter_entity_filter import AdapterEntityFilter
+from ..types.adapters_page import AdaptersPage
+from ..types.finetuning_type import FinetuningType
+from ..types.lora import Lora
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawAdaptersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_adapters(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[AdapterEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[AdaptersPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[AdapterEntityFilter]
+ Filter adapters by name, model (parent model ref string, stored on the adapter), description, fileset, finetuning_type, enabled, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[AdaptersPage]
+ List adapters in the workspace
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=AdapterEntityFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AdaptersPage,
+ parse_obj_as(
+ type_=AdaptersPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_adapter(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ model: str,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Adapter]:
+ """
+ Create an adapter under a base model specified by the "model" field in the body.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ model : str
+ Base model entity.
+ Use `{workspace}/{model_name}` to reference a model in any workspace, or a single `{model_name}` resolved in the path workspace. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Adapter]
+ Create a new adapter for a model
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "enabled": enabled,
+ "lora_config": convert_and_respect_annotation_metadata(
+ object_=lora_config, annotation=Lora, direction="write"
+ ),
+ "model": model,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Adapter]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Adapter]
+ Get one adapter by name. Parent model is taken from the adapter's stored parent (entity `parent` field).
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_adapter(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Adapter]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Adapter]
+ Update adapter metadata. Updates are applied to the row identified by the adapter's stored parent (entity `parent` field).
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "enabled": enabled,
+ "fileset": fileset,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawAdaptersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_adapters(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[AdapterEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[AdaptersPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[AdapterEntityFilter]
+ Filter adapters by name, model (parent model ref string, stored on the adapter), description, fileset, finetuning_type, enabled, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[AdaptersPage]
+ List adapters in the workspace
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=AdapterEntityFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AdaptersPage,
+ parse_obj_as(
+ type_=AdaptersPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_adapter(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ model: str,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Adapter]:
+ """
+ Create an adapter under a base model specified by the "model" field in the body.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ model : str
+ Base model entity.
+ Use `{workspace}/{model_name}` to reference a model in any workspace, or a single `{model_name}` resolved in the path workspace. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Adapter]
+ Create a new adapter for a model
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "enabled": enabled,
+ "lora_config": convert_and_respect_annotation_metadata(
+ object_=lora_config, annotation=Lora, direction="write"
+ ),
+ "model": model,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Adapter]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Adapter]
+ Get one adapter by name. Parent model is taken from the adapter's stored parent (entity `parent` field).
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_adapter(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_adapter(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Adapter]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Adapter]
+ Update adapter metadata. Updates are applied to the row identified by the adapter's stored parent (entity `parent` field).
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/adapters/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "enabled": enabled,
+ "fileset": fileset,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/annotations/__init__.py b/sdks/python/annotations/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/annotations/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/annotations/client.py b/sdks/python/annotations/client.py
new file mode 100644
index 0000000000..c760002fba
--- /dev/null
+++ b/sdks/python/annotations/client.py
@@ -0,0 +1,383 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.annotation import Annotation
+from ..types.annotation_filter import AnnotationFilter
+from ..types.annotation_input import AnnotationInput
+from ..types.annotation_sort_field import AnnotationSortField
+from ..types.annotations_page import AnnotationsPage
+from .raw_client import AsyncRawAnnotationsClient, RawAnnotationsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class AnnotationsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawAnnotationsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawAnnotationsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawAnnotationsClient
+ """
+ return self._raw_client
+
+ def list_annotations(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[AnnotationSortField] = None,
+ filter: typing.Optional[AnnotationFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AnnotationsPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[AnnotationSortField]
+
+ filter : typing.Optional[AnnotationFilter]
+ Filter annotations by span_id, session_id, kind, name, created_by, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AnnotationsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.annotations.list_annotations(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_annotations(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_annotation(
+ self, workspace: str, *, request: AnnotationInput, request_options: typing.Optional[RequestOptions] = None
+ ) -> Annotation:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : AnnotationInput
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Annotation
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import AnnotationInput_Feedback, NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.annotations.create_annotation(
+ workspace="workspace",
+ request=AnnotationInput_Feedback(
+ session_id="session_id",
+ value="positive",
+ ),
+ )
+ """
+ _response = self._raw_client.create_annotation(workspace, request=request, request_options=request_options)
+ return _response.data
+
+ def get_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Annotation:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Annotation
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.annotations.get_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+ )
+ """
+ _response = self._raw_client.get_annotation(workspace, annotation_id, request_options=request_options)
+ return _response.data
+
+ def delete_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.annotations.delete_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+ )
+ """
+ _response = self._raw_client.delete_annotation(workspace, annotation_id, request_options=request_options)
+ return _response.data
+
+
+class AsyncAnnotationsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawAnnotationsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawAnnotationsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawAnnotationsClient
+ """
+ return self._raw_client
+
+ async def list_annotations(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[AnnotationSortField] = None,
+ filter: typing.Optional[AnnotationFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AnnotationsPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[AnnotationSortField]
+
+ filter : typing.Optional[AnnotationFilter]
+ Filter annotations by span_id, session_id, kind, name, created_by, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AnnotationsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.annotations.list_annotations(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_annotations(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_annotation(
+ self, workspace: str, *, request: AnnotationInput, request_options: typing.Optional[RequestOptions] = None
+ ) -> Annotation:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : AnnotationInput
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Annotation
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AnnotationInput_Feedback, AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.annotations.create_annotation(
+ workspace="workspace",
+ request=AnnotationInput_Feedback(
+ session_id="session_id",
+ value="positive",
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_annotation(
+ workspace, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def get_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Annotation:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Annotation
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.annotations.get_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_annotation(workspace, annotation_id, request_options=request_options)
+ return _response.data
+
+ async def delete_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.annotations.delete_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_annotation(workspace, annotation_id, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/annotations/raw_client.py b/sdks/python/annotations/raw_client.py
new file mode 100644
index 0000000000..add3586131
--- /dev/null
+++ b/sdks/python/annotations/raw_client.py
@@ -0,0 +1,548 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.annotation import Annotation
+from ..types.annotation_filter import AnnotationFilter
+from ..types.annotation_input import AnnotationInput
+from ..types.annotation_sort_field import AnnotationSortField
+from ..types.annotations_page import AnnotationsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawAnnotationsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_annotations(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[AnnotationSortField] = None,
+ filter: typing.Optional[AnnotationFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[AnnotationsPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[AnnotationSortField]
+
+ filter : typing.Optional[AnnotationFilter]
+ Filter annotations by span_id, session_id, kind, name, created_by, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[AnnotationsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=AnnotationFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AnnotationsPage,
+ parse_obj_as(
+ type_=AnnotationsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_annotation(
+ self, workspace: str, *, request: AnnotationInput, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Annotation]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : AnnotationInput
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Annotation]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations",
+ method="POST",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=AnnotationInput, direction="write"
+ ),
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Annotation,
+ parse_obj_as(
+ type_=Annotation, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Annotation]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Annotation]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations/{encode_path_param(annotation_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Annotation,
+ parse_obj_as(
+ type_=Annotation, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations/{encode_path_param(annotation_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawAnnotationsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_annotations(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[AnnotationSortField] = None,
+ filter: typing.Optional[AnnotationFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[AnnotationsPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[AnnotationSortField]
+
+ filter : typing.Optional[AnnotationFilter]
+ Filter annotations by span_id, session_id, kind, name, created_by, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[AnnotationsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=AnnotationFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AnnotationsPage,
+ parse_obj_as(
+ type_=AnnotationsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_annotation(
+ self, workspace: str, *, request: AnnotationInput, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Annotation]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : AnnotationInput
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Annotation]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations",
+ method="POST",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=AnnotationInput, direction="write"
+ ),
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Annotation,
+ parse_obj_as(
+ type_=Annotation, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Annotation]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Annotation]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations/{encode_path_param(annotation_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Annotation,
+ parse_obj_as(
+ type_=Annotation, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_annotation(
+ self, workspace: str, annotation_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ annotation_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/annotations/{encode_path_param(annotation_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/client.py b/sdks/python/client.py
new file mode 100644
index 0000000000..0606417f55
--- /dev/null
+++ b/sdks/python/client.py
@@ -0,0 +1,594 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import httpx
+from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from .core.logging import LogConfig, Logger
+
+if typing.TYPE_CHECKING:
+ from .adapters.client import AdaptersClient, AsyncAdaptersClient
+ from .annotations.client import AnnotationsClient, AsyncAnnotationsClient
+ from .discovery.client import AsyncDiscoveryClient, DiscoveryClient
+ from .entity_store.client import AsyncEntityStoreClient, EntityStoreClient
+ from .evaluator_results.client import AsyncEvaluatorResultsClient, EvaluatorResultsClient
+ from .experiment_groups.client import AsyncExperimentGroupsClient, ExperimentGroupsClient
+ from .experiments.client import AsyncExperimentsClient, ExperimentsClient
+ from .files.client import AsyncFilesClient, FilesClient
+ from .guardrails.client import AsyncGuardrailsClient, GuardrailsClient
+ from .iam.client import AsyncIamClient, IamClient
+ from .inference_gateway.client import AsyncInferenceGatewayClient, InferenceGatewayClient
+ from .ingest.client import AsyncIngestClient, IngestClient
+ from .jobs.client import AsyncJobsClient, JobsClient
+ from .model_deployment_configs.client import AsyncModelDeploymentConfigsClient, ModelDeploymentConfigsClient
+ from .model_deployments.client import AsyncModelDeploymentsClient, ModelDeploymentsClient
+ from .model_providers.client import AsyncModelProvidersClient, ModelProvidersClient
+ from .models.client import AsyncModelsClient, ModelsClient
+ from .otlp.client import AsyncOtlpClient, OtlpClient
+ from .secrets.client import AsyncSecretsClient, SecretsClient
+ from .secrets_admin.client import AsyncSecretsAdminClient, SecretsAdminClient
+ from .spans.client import AsyncSpansClient, SpansClient
+ from .traces.client import AsyncTracesClient, TracesClient
+ from .virtual_models.client import AsyncVirtualModelsClient, VirtualModelsClient
+
+
+class NvidiaApi:
+ """
+ Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
+
+ Parameters
+ ----------
+ base_url : str
+ The base url to use for requests from the client.
+
+ headers : typing.Optional[typing.Dict[str, str]]
+ Additional headers to send with every request.
+
+ timeout : typing.Optional[float]
+ The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
+
+ max_retries : typing.Optional[int]
+ The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value.
+
+ follow_redirects : typing.Optional[bool]
+ Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
+
+ httpx_client : typing.Optional[httpx.Client]
+ The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
+
+ logging : typing.Optional[typing.Union[LogConfig, Logger]]
+ Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance.
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ """
+
+ def __init__(
+ self,
+ *,
+ base_url: str,
+ headers: typing.Optional[typing.Dict[str, str]] = None,
+ timeout: typing.Optional[float] = None,
+ max_retries: typing.Optional[int] = None,
+ follow_redirects: typing.Optional[bool] = True,
+ httpx_client: typing.Optional[httpx.Client] = None,
+ logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ ):
+ _defaulted_timeout = (
+ timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
+ )
+ _defaulted_max_retries = max_retries if max_retries is not None else 2
+ self._client_wrapper = SyncClientWrapper(
+ base_url=base_url,
+ headers=headers,
+ httpx_client=httpx_client
+ if httpx_client is not None
+ else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
+ if follow_redirects is not None
+ else httpx.Client(timeout=_defaulted_timeout),
+ timeout=_defaulted_timeout,
+ max_retries=_defaulted_max_retries,
+ logging=logging,
+ )
+ self._discovery: typing.Optional[DiscoveryClient] = None
+ self._iam: typing.Optional[IamClient] = None
+ self._entity_store: typing.Optional[EntityStoreClient] = None
+ self._files: typing.Optional[FilesClient] = None
+ self._otlp: typing.Optional[OtlpClient] = None
+ self._guardrails: typing.Optional[GuardrailsClient] = None
+ self._inference_gateway: typing.Optional[InferenceGatewayClient] = None
+ self._virtual_models: typing.Optional[VirtualModelsClient] = None
+ self._annotations: typing.Optional[AnnotationsClient] = None
+ self._evaluator_results: typing.Optional[EvaluatorResultsClient] = None
+ self._experiment_groups: typing.Optional[ExperimentGroupsClient] = None
+ self._experiments: typing.Optional[ExperimentsClient] = None
+ self._ingest: typing.Optional[IngestClient] = None
+ self._spans: typing.Optional[SpansClient] = None
+ self._traces: typing.Optional[TracesClient] = None
+ self._jobs: typing.Optional[JobsClient] = None
+ self._adapters: typing.Optional[AdaptersClient] = None
+ self._model_deployment_configs: typing.Optional[ModelDeploymentConfigsClient] = None
+ self._model_deployments: typing.Optional[ModelDeploymentsClient] = None
+ self._models: typing.Optional[ModelsClient] = None
+ self._model_providers: typing.Optional[ModelProvidersClient] = None
+ self._secrets_admin: typing.Optional[SecretsAdminClient] = None
+ self._secrets: typing.Optional[SecretsClient] = None
+
+ @property
+ def discovery(self):
+ if self._discovery is None:
+ from .discovery.client import DiscoveryClient # noqa: E402
+
+ self._discovery = DiscoveryClient(client_wrapper=self._client_wrapper)
+ return self._discovery
+
+ @property
+ def iam(self):
+ if self._iam is None:
+ from .iam.client import IamClient # noqa: E402
+
+ self._iam = IamClient(client_wrapper=self._client_wrapper)
+ return self._iam
+
+ @property
+ def entity_store(self):
+ if self._entity_store is None:
+ from .entity_store.client import EntityStoreClient # noqa: E402
+
+ self._entity_store = EntityStoreClient(client_wrapper=self._client_wrapper)
+ return self._entity_store
+
+ @property
+ def files(self):
+ if self._files is None:
+ from .files.client import FilesClient # noqa: E402
+
+ self._files = FilesClient(client_wrapper=self._client_wrapper)
+ return self._files
+
+ @property
+ def otlp(self):
+ if self._otlp is None:
+ from .otlp.client import OtlpClient # noqa: E402
+
+ self._otlp = OtlpClient(client_wrapper=self._client_wrapper)
+ return self._otlp
+
+ @property
+ def guardrails(self):
+ if self._guardrails is None:
+ from .guardrails.client import GuardrailsClient # noqa: E402
+
+ self._guardrails = GuardrailsClient(client_wrapper=self._client_wrapper)
+ return self._guardrails
+
+ @property
+ def inference_gateway(self):
+ if self._inference_gateway is None:
+ from .inference_gateway.client import InferenceGatewayClient # noqa: E402
+
+ self._inference_gateway = InferenceGatewayClient(client_wrapper=self._client_wrapper)
+ return self._inference_gateway
+
+ @property
+ def virtual_models(self):
+ if self._virtual_models is None:
+ from .virtual_models.client import VirtualModelsClient # noqa: E402
+
+ self._virtual_models = VirtualModelsClient(client_wrapper=self._client_wrapper)
+ return self._virtual_models
+
+ @property
+ def annotations(self):
+ if self._annotations is None:
+ from .annotations.client import AnnotationsClient # noqa: E402
+
+ self._annotations = AnnotationsClient(client_wrapper=self._client_wrapper)
+ return self._annotations
+
+ @property
+ def evaluator_results(self):
+ if self._evaluator_results is None:
+ from .evaluator_results.client import EvaluatorResultsClient # noqa: E402
+
+ self._evaluator_results = EvaluatorResultsClient(client_wrapper=self._client_wrapper)
+ return self._evaluator_results
+
+ @property
+ def experiment_groups(self):
+ if self._experiment_groups is None:
+ from .experiment_groups.client import ExperimentGroupsClient # noqa: E402
+
+ self._experiment_groups = ExperimentGroupsClient(client_wrapper=self._client_wrapper)
+ return self._experiment_groups
+
+ @property
+ def experiments(self):
+ if self._experiments is None:
+ from .experiments.client import ExperimentsClient # noqa: E402
+
+ self._experiments = ExperimentsClient(client_wrapper=self._client_wrapper)
+ return self._experiments
+
+ @property
+ def ingest(self):
+ if self._ingest is None:
+ from .ingest.client import IngestClient # noqa: E402
+
+ self._ingest = IngestClient(client_wrapper=self._client_wrapper)
+ return self._ingest
+
+ @property
+ def spans(self):
+ if self._spans is None:
+ from .spans.client import SpansClient # noqa: E402
+
+ self._spans = SpansClient(client_wrapper=self._client_wrapper)
+ return self._spans
+
+ @property
+ def traces(self):
+ if self._traces is None:
+ from .traces.client import TracesClient # noqa: E402
+
+ self._traces = TracesClient(client_wrapper=self._client_wrapper)
+ return self._traces
+
+ @property
+ def jobs(self):
+ if self._jobs is None:
+ from .jobs.client import JobsClient # noqa: E402
+
+ self._jobs = JobsClient(client_wrapper=self._client_wrapper)
+ return self._jobs
+
+ @property
+ def adapters(self):
+ if self._adapters is None:
+ from .adapters.client import AdaptersClient # noqa: E402
+
+ self._adapters = AdaptersClient(client_wrapper=self._client_wrapper)
+ return self._adapters
+
+ @property
+ def model_deployment_configs(self):
+ if self._model_deployment_configs is None:
+ from .model_deployment_configs.client import ModelDeploymentConfigsClient # noqa: E402
+
+ self._model_deployment_configs = ModelDeploymentConfigsClient(client_wrapper=self._client_wrapper)
+ return self._model_deployment_configs
+
+ @property
+ def model_deployments(self):
+ if self._model_deployments is None:
+ from .model_deployments.client import ModelDeploymentsClient # noqa: E402
+
+ self._model_deployments = ModelDeploymentsClient(client_wrapper=self._client_wrapper)
+ return self._model_deployments
+
+ @property
+ def models(self):
+ if self._models is None:
+ from .models.client import ModelsClient # noqa: E402
+
+ self._models = ModelsClient(client_wrapper=self._client_wrapper)
+ return self._models
+
+ @property
+ def model_providers(self):
+ if self._model_providers is None:
+ from .model_providers.client import ModelProvidersClient # noqa: E402
+
+ self._model_providers = ModelProvidersClient(client_wrapper=self._client_wrapper)
+ return self._model_providers
+
+ @property
+ def secrets_admin(self):
+ if self._secrets_admin is None:
+ from .secrets_admin.client import SecretsAdminClient # noqa: E402
+
+ self._secrets_admin = SecretsAdminClient(client_wrapper=self._client_wrapper)
+ return self._secrets_admin
+
+ @property
+ def secrets(self):
+ if self._secrets is None:
+ from .secrets.client import SecretsClient # noqa: E402
+
+ self._secrets = SecretsClient(client_wrapper=self._client_wrapper)
+ return self._secrets
+
+
+def _make_default_async_client(
+ timeout: typing.Optional[float],
+ follow_redirects: typing.Optional[bool],
+) -> httpx.AsyncClient:
+ try:
+ import httpx_aiohttp # type: ignore[import-not-found]
+ except ImportError:
+ pass
+ else:
+ if follow_redirects is not None:
+ return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects)
+ return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout)
+
+ if follow_redirects is not None:
+ return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects)
+ return httpx.AsyncClient(timeout=timeout)
+
+
+class AsyncNvidiaApi:
+ """
+ Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
+
+ Parameters
+ ----------
+ base_url : str
+ The base url to use for requests from the client.
+
+ headers : typing.Optional[typing.Dict[str, str]]
+ Additional headers to send with every request.
+
+ timeout : typing.Optional[float]
+ The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
+
+ max_retries : typing.Optional[int]
+ The default maximum number of retries for failed requests. Defaults to 2. Per-request `max_retries` in `request_options` takes precedence over this value.
+
+ follow_redirects : typing.Optional[bool]
+ Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.
+
+ httpx_client : typing.Optional[httpx.AsyncClient]
+ The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
+
+ logging : typing.Optional[typing.Union[LogConfig, Logger]]
+ Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance.
+
+ Examples
+ --------
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ """
+
+ def __init__(
+ self,
+ *,
+ base_url: str,
+ headers: typing.Optional[typing.Dict[str, str]] = None,
+ timeout: typing.Optional[float] = None,
+ max_retries: typing.Optional[int] = None,
+ follow_redirects: typing.Optional[bool] = True,
+ httpx_client: typing.Optional[httpx.AsyncClient] = None,
+ logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ ):
+ _defaulted_timeout = (
+ timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
+ )
+ _defaulted_max_retries = max_retries if max_retries is not None else 2
+ self._client_wrapper = AsyncClientWrapper(
+ base_url=base_url,
+ headers=headers,
+ httpx_client=httpx_client
+ if httpx_client is not None
+ else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects),
+ timeout=_defaulted_timeout,
+ max_retries=_defaulted_max_retries,
+ logging=logging,
+ )
+ self._discovery: typing.Optional[AsyncDiscoveryClient] = None
+ self._iam: typing.Optional[AsyncIamClient] = None
+ self._entity_store: typing.Optional[AsyncEntityStoreClient] = None
+ self._files: typing.Optional[AsyncFilesClient] = None
+ self._otlp: typing.Optional[AsyncOtlpClient] = None
+ self._guardrails: typing.Optional[AsyncGuardrailsClient] = None
+ self._inference_gateway: typing.Optional[AsyncInferenceGatewayClient] = None
+ self._virtual_models: typing.Optional[AsyncVirtualModelsClient] = None
+ self._annotations: typing.Optional[AsyncAnnotationsClient] = None
+ self._evaluator_results: typing.Optional[AsyncEvaluatorResultsClient] = None
+ self._experiment_groups: typing.Optional[AsyncExperimentGroupsClient] = None
+ self._experiments: typing.Optional[AsyncExperimentsClient] = None
+ self._ingest: typing.Optional[AsyncIngestClient] = None
+ self._spans: typing.Optional[AsyncSpansClient] = None
+ self._traces: typing.Optional[AsyncTracesClient] = None
+ self._jobs: typing.Optional[AsyncJobsClient] = None
+ self._adapters: typing.Optional[AsyncAdaptersClient] = None
+ self._model_deployment_configs: typing.Optional[AsyncModelDeploymentConfigsClient] = None
+ self._model_deployments: typing.Optional[AsyncModelDeploymentsClient] = None
+ self._models: typing.Optional[AsyncModelsClient] = None
+ self._model_providers: typing.Optional[AsyncModelProvidersClient] = None
+ self._secrets_admin: typing.Optional[AsyncSecretsAdminClient] = None
+ self._secrets: typing.Optional[AsyncSecretsClient] = None
+
+ @property
+ def discovery(self):
+ if self._discovery is None:
+ from .discovery.client import AsyncDiscoveryClient # noqa: E402
+
+ self._discovery = AsyncDiscoveryClient(client_wrapper=self._client_wrapper)
+ return self._discovery
+
+ @property
+ def iam(self):
+ if self._iam is None:
+ from .iam.client import AsyncIamClient # noqa: E402
+
+ self._iam = AsyncIamClient(client_wrapper=self._client_wrapper)
+ return self._iam
+
+ @property
+ def entity_store(self):
+ if self._entity_store is None:
+ from .entity_store.client import AsyncEntityStoreClient # noqa: E402
+
+ self._entity_store = AsyncEntityStoreClient(client_wrapper=self._client_wrapper)
+ return self._entity_store
+
+ @property
+ def files(self):
+ if self._files is None:
+ from .files.client import AsyncFilesClient # noqa: E402
+
+ self._files = AsyncFilesClient(client_wrapper=self._client_wrapper)
+ return self._files
+
+ @property
+ def otlp(self):
+ if self._otlp is None:
+ from .otlp.client import AsyncOtlpClient # noqa: E402
+
+ self._otlp = AsyncOtlpClient(client_wrapper=self._client_wrapper)
+ return self._otlp
+
+ @property
+ def guardrails(self):
+ if self._guardrails is None:
+ from .guardrails.client import AsyncGuardrailsClient # noqa: E402
+
+ self._guardrails = AsyncGuardrailsClient(client_wrapper=self._client_wrapper)
+ return self._guardrails
+
+ @property
+ def inference_gateway(self):
+ if self._inference_gateway is None:
+ from .inference_gateway.client import AsyncInferenceGatewayClient # noqa: E402
+
+ self._inference_gateway = AsyncInferenceGatewayClient(client_wrapper=self._client_wrapper)
+ return self._inference_gateway
+
+ @property
+ def virtual_models(self):
+ if self._virtual_models is None:
+ from .virtual_models.client import AsyncVirtualModelsClient # noqa: E402
+
+ self._virtual_models = AsyncVirtualModelsClient(client_wrapper=self._client_wrapper)
+ return self._virtual_models
+
+ @property
+ def annotations(self):
+ if self._annotations is None:
+ from .annotations.client import AsyncAnnotationsClient # noqa: E402
+
+ self._annotations = AsyncAnnotationsClient(client_wrapper=self._client_wrapper)
+ return self._annotations
+
+ @property
+ def evaluator_results(self):
+ if self._evaluator_results is None:
+ from .evaluator_results.client import AsyncEvaluatorResultsClient # noqa: E402
+
+ self._evaluator_results = AsyncEvaluatorResultsClient(client_wrapper=self._client_wrapper)
+ return self._evaluator_results
+
+ @property
+ def experiment_groups(self):
+ if self._experiment_groups is None:
+ from .experiment_groups.client import AsyncExperimentGroupsClient # noqa: E402
+
+ self._experiment_groups = AsyncExperimentGroupsClient(client_wrapper=self._client_wrapper)
+ return self._experiment_groups
+
+ @property
+ def experiments(self):
+ if self._experiments is None:
+ from .experiments.client import AsyncExperimentsClient # noqa: E402
+
+ self._experiments = AsyncExperimentsClient(client_wrapper=self._client_wrapper)
+ return self._experiments
+
+ @property
+ def ingest(self):
+ if self._ingest is None:
+ from .ingest.client import AsyncIngestClient # noqa: E402
+
+ self._ingest = AsyncIngestClient(client_wrapper=self._client_wrapper)
+ return self._ingest
+
+ @property
+ def spans(self):
+ if self._spans is None:
+ from .spans.client import AsyncSpansClient # noqa: E402
+
+ self._spans = AsyncSpansClient(client_wrapper=self._client_wrapper)
+ return self._spans
+
+ @property
+ def traces(self):
+ if self._traces is None:
+ from .traces.client import AsyncTracesClient # noqa: E402
+
+ self._traces = AsyncTracesClient(client_wrapper=self._client_wrapper)
+ return self._traces
+
+ @property
+ def jobs(self):
+ if self._jobs is None:
+ from .jobs.client import AsyncJobsClient # noqa: E402
+
+ self._jobs = AsyncJobsClient(client_wrapper=self._client_wrapper)
+ return self._jobs
+
+ @property
+ def adapters(self):
+ if self._adapters is None:
+ from .adapters.client import AsyncAdaptersClient # noqa: E402
+
+ self._adapters = AsyncAdaptersClient(client_wrapper=self._client_wrapper)
+ return self._adapters
+
+ @property
+ def model_deployment_configs(self):
+ if self._model_deployment_configs is None:
+ from .model_deployment_configs.client import AsyncModelDeploymentConfigsClient # noqa: E402
+
+ self._model_deployment_configs = AsyncModelDeploymentConfigsClient(client_wrapper=self._client_wrapper)
+ return self._model_deployment_configs
+
+ @property
+ def model_deployments(self):
+ if self._model_deployments is None:
+ from .model_deployments.client import AsyncModelDeploymentsClient # noqa: E402
+
+ self._model_deployments = AsyncModelDeploymentsClient(client_wrapper=self._client_wrapper)
+ return self._model_deployments
+
+ @property
+ def models(self):
+ if self._models is None:
+ from .models.client import AsyncModelsClient # noqa: E402
+
+ self._models = AsyncModelsClient(client_wrapper=self._client_wrapper)
+ return self._models
+
+ @property
+ def model_providers(self):
+ if self._model_providers is None:
+ from .model_providers.client import AsyncModelProvidersClient # noqa: E402
+
+ self._model_providers = AsyncModelProvidersClient(client_wrapper=self._client_wrapper)
+ return self._model_providers
+
+ @property
+ def secrets_admin(self):
+ if self._secrets_admin is None:
+ from .secrets_admin.client import AsyncSecretsAdminClient # noqa: E402
+
+ self._secrets_admin = AsyncSecretsAdminClient(client_wrapper=self._client_wrapper)
+ return self._secrets_admin
+
+ @property
+ def secrets(self):
+ if self._secrets is None:
+ from .secrets.client import AsyncSecretsClient # noqa: E402
+
+ self._secrets = AsyncSecretsClient(client_wrapper=self._client_wrapper)
+ return self._secrets
diff --git a/sdks/python/core/__init__.py b/sdks/python/core/__init__.py
new file mode 100644
index 0000000000..5bc159a110
--- /dev/null
+++ b/sdks/python/core/__init__.py
@@ -0,0 +1,127 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .api_error import ApiError
+ from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
+ from .datetime_utils import Rfc2822DateTime, parse_rfc2822_datetime, serialize_datetime
+ from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
+ from .http_client import AsyncHttpClient, HttpClient
+ from .http_response import AsyncHttpResponse, HttpResponse
+ from .jsonable_encoder import encode_path_param, jsonable_encoder
+ from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger
+ from .parse_error import ParsingError
+ from .pydantic_utilities import (
+ IS_PYDANTIC_V2,
+ UniversalBaseModel,
+ UniversalRootModel,
+ parse_obj_as,
+ universal_field_validator,
+ universal_root_validator,
+ update_forward_refs,
+ )
+ from .query_encoder import encode_query
+ from .remove_none_from_dict import remove_none_from_dict
+ from .request_options import RequestOptions
+ from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
+_dynamic_imports: typing.Dict[str, str] = {
+ "ApiError": ".api_error",
+ "AsyncClientWrapper": ".client_wrapper",
+ "AsyncHttpClient": ".http_client",
+ "AsyncHttpResponse": ".http_response",
+ "BaseClientWrapper": ".client_wrapper",
+ "ConsoleLogger": ".logging",
+ "FieldMetadata": ".serialization",
+ "File": ".file",
+ "HttpClient": ".http_client",
+ "HttpResponse": ".http_response",
+ "ILogger": ".logging",
+ "IS_PYDANTIC_V2": ".pydantic_utilities",
+ "LogConfig": ".logging",
+ "LogLevel": ".logging",
+ "Logger": ".logging",
+ "ParsingError": ".parse_error",
+ "RequestOptions": ".request_options",
+ "Rfc2822DateTime": ".datetime_utils",
+ "SyncClientWrapper": ".client_wrapper",
+ "UniversalBaseModel": ".pydantic_utilities",
+ "UniversalRootModel": ".pydantic_utilities",
+ "convert_and_respect_annotation_metadata": ".serialization",
+ "convert_file_dict_to_httpx_tuples": ".file",
+ "create_logger": ".logging",
+ "encode_path_param": ".jsonable_encoder",
+ "encode_query": ".query_encoder",
+ "jsonable_encoder": ".jsonable_encoder",
+ "parse_obj_as": ".pydantic_utilities",
+ "parse_rfc2822_datetime": ".datetime_utils",
+ "remove_none_from_dict": ".remove_none_from_dict",
+ "serialize_datetime": ".datetime_utils",
+ "universal_field_validator": ".pydantic_utilities",
+ "universal_root_validator": ".pydantic_utilities",
+ "update_forward_refs": ".pydantic_utilities",
+ "with_content_type": ".file",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "ApiError",
+ "AsyncClientWrapper",
+ "AsyncHttpClient",
+ "AsyncHttpResponse",
+ "BaseClientWrapper",
+ "ConsoleLogger",
+ "FieldMetadata",
+ "File",
+ "HttpClient",
+ "HttpResponse",
+ "ILogger",
+ "IS_PYDANTIC_V2",
+ "LogConfig",
+ "LogLevel",
+ "Logger",
+ "ParsingError",
+ "RequestOptions",
+ "Rfc2822DateTime",
+ "SyncClientWrapper",
+ "UniversalBaseModel",
+ "UniversalRootModel",
+ "convert_and_respect_annotation_metadata",
+ "convert_file_dict_to_httpx_tuples",
+ "create_logger",
+ "encode_path_param",
+ "encode_query",
+ "jsonable_encoder",
+ "parse_obj_as",
+ "parse_rfc2822_datetime",
+ "remove_none_from_dict",
+ "serialize_datetime",
+ "universal_field_validator",
+ "universal_root_validator",
+ "update_forward_refs",
+ "with_content_type",
+]
diff --git a/sdks/python/core/api_error.py b/sdks/python/core/api_error.py
new file mode 100644
index 0000000000..6f850a60cb
--- /dev/null
+++ b/sdks/python/core/api_error.py
@@ -0,0 +1,23 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Any, Dict, Optional
+
+
+class ApiError(Exception):
+ headers: Optional[Dict[str, str]]
+ status_code: Optional[int]
+ body: Any
+
+ def __init__(
+ self,
+ *,
+ headers: Optional[Dict[str, str]] = None,
+ status_code: Optional[int] = None,
+ body: Any = None,
+ ) -> None:
+ self.headers = headers
+ self.status_code = status_code
+ self.body = body
+
+ def __str__(self) -> str:
+ return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}"
diff --git a/sdks/python/core/client_wrapper.py b/sdks/python/core/client_wrapper.py
new file mode 100644
index 0000000000..217123f9cb
--- /dev/null
+++ b/sdks/python/core/client_wrapper.py
@@ -0,0 +1,101 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import httpx
+from .http_client import AsyncHttpClient, HttpClient
+from .logging import LogConfig, Logger
+
+
+class BaseClientWrapper:
+ def __init__(
+ self,
+ *,
+ headers: typing.Optional[typing.Dict[str, str]] = None,
+ base_url: str,
+ timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
+ logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ ):
+ self._headers = headers
+ self._base_url = base_url
+ self._timeout = timeout
+ self._max_retries = max_retries
+ self._logging = logging
+
+ def get_headers(self) -> typing.Dict[str, str]:
+ import platform
+
+ headers: typing.Dict[str, str] = {
+ "X-Fern-Language": "Python",
+ "X-Fern-Runtime": f"python/{platform.python_version()}",
+ "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
+ **(self.get_custom_headers() or {}),
+ }
+ return headers
+
+ def get_custom_headers(self) -> typing.Optional[typing.Dict[str, str]]:
+ return self._headers
+
+ def get_base_url(self) -> str:
+ return self._base_url
+
+ def get_timeout(self) -> typing.Optional[float]:
+ return self._timeout
+
+ def get_max_retries(self) -> int:
+ return self._max_retries
+
+
+class SyncClientWrapper(BaseClientWrapper):
+ def __init__(
+ self,
+ *,
+ headers: typing.Optional[typing.Dict[str, str]] = None,
+ base_url: str,
+ timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
+ logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ httpx_client: httpx.Client,
+ ):
+ super().__init__(headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries, logging=logging)
+ self.httpx_client = HttpClient(
+ httpx_client=httpx_client,
+ base_headers=self.get_headers,
+ base_timeout=self.get_timeout,
+ base_url=self.get_base_url,
+ base_max_retries=self.get_max_retries(),
+ logging_config=self._logging,
+ )
+
+
+class AsyncClientWrapper(BaseClientWrapper):
+ def __init__(
+ self,
+ *,
+ headers: typing.Optional[typing.Dict[str, str]] = None,
+ base_url: str,
+ timeout: typing.Optional[float] = None,
+ max_retries: int = 2,
+ logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
+ httpx_client: httpx.AsyncClient,
+ ):
+ super().__init__(headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries, logging=logging)
+ self._async_token = async_token
+ self.httpx_client = AsyncHttpClient(
+ httpx_client=httpx_client,
+ base_headers=self.get_headers,
+ base_timeout=self.get_timeout,
+ base_url=self.get_base_url,
+ base_max_retries=self.get_max_retries(),
+ async_base_headers=self.async_get_headers,
+ logging_config=self._logging,
+ )
+
+ async def async_get_headers(self) -> typing.Dict[str, str]:
+ headers = self.get_headers()
+ if self._async_token is not None:
+ token = await self._async_token()
+ headers["Authorization"] = f"Bearer {token}"
+ return headers
diff --git a/sdks/python/core/datetime_utils.py b/sdks/python/core/datetime_utils.py
new file mode 100644
index 0000000000..a12b2ad03c
--- /dev/null
+++ b/sdks/python/core/datetime_utils.py
@@ -0,0 +1,70 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+from email.utils import parsedate_to_datetime
+from typing import Any
+
+import pydantic
+
+IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
+
+
+def parse_rfc2822_datetime(v: Any) -> dt.datetime:
+ """
+ Parse an RFC 2822 datetime string (e.g., "Wed, 02 Oct 2002 13:00:00 GMT")
+ into a datetime object. If the value is already a datetime, return it as-is.
+ Falls back to ISO 8601 parsing if RFC 2822 parsing fails.
+ """
+ if isinstance(v, dt.datetime):
+ return v
+ if isinstance(v, str):
+ try:
+ return parsedate_to_datetime(v)
+ except Exception:
+ pass
+ # Fallback to ISO 8601 parsing
+ return dt.datetime.fromisoformat(v.replace("Z", "+00:00"))
+ raise ValueError(f"Expected str or datetime, got {type(v)}")
+
+
+class Rfc2822DateTime(dt.datetime):
+ """A datetime subclass that parses RFC 2822 date strings.
+
+ On Pydantic V1, uses __get_validators__ for pre-validation.
+ On Pydantic V2, uses __get_pydantic_core_schema__ for BeforeValidator-style parsing.
+ """
+
+ @classmethod
+ def __get_validators__(cls): # type: ignore[no-untyped-def]
+ yield parse_rfc2822_datetime
+
+ @classmethod
+ def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> Any: # type: ignore[override]
+ from pydantic_core import core_schema
+
+ return core_schema.no_info_before_validator_function(parse_rfc2822_datetime, core_schema.datetime_schema())
+
+
+def serialize_datetime(v: dt.datetime) -> str:
+ """
+ Serialize a datetime including timezone info.
+
+ Uses the timezone info provided if present, otherwise uses the current runtime's timezone info.
+
+ UTC datetimes end in "Z" while all other timezones are represented as offset from UTC, e.g. +05:00.
+ """
+
+ def _serialize_zoned_datetime(v: dt.datetime) -> str:
+ if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(None):
+ # UTC is a special case where we use "Z" at the end instead of "+00:00"
+ return v.isoformat().replace("+00:00", "Z")
+ else:
+ # Delegate to the typical +/- offset format
+ return v.isoformat()
+
+ if v.tzinfo is not None:
+ return _serialize_zoned_datetime(v)
+ else:
+ local_tz = dt.datetime.now().astimezone().tzinfo
+ localized_dt = v.replace(tzinfo=local_tz)
+ return _serialize_zoned_datetime(localized_dt)
diff --git a/sdks/python/core/file.py b/sdks/python/core/file.py
new file mode 100644
index 0000000000..44b0d27c08
--- /dev/null
+++ b/sdks/python/core/file.py
@@ -0,0 +1,67 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import IO, Dict, List, Mapping, Optional, Tuple, Union, cast
+
+# File typing inspired by the flexibility of types within the httpx library
+# https://github.com/encode/httpx/blob/master/httpx/_types.py
+FileContent = Union[IO[bytes], bytes, str]
+File = Union[
+ # file (or bytes)
+ FileContent,
+ # (filename, file (or bytes))
+ Tuple[Optional[str], FileContent],
+ # (filename, file (or bytes), content_type)
+ Tuple[Optional[str], FileContent, Optional[str]],
+ # (filename, file (or bytes), content_type, headers)
+ Tuple[
+ Optional[str],
+ FileContent,
+ Optional[str],
+ Mapping[str, str],
+ ],
+]
+
+
+def convert_file_dict_to_httpx_tuples(
+ d: Dict[str, Union[File, List[File]]],
+) -> List[Tuple[str, File]]:
+ """
+ The format we use is a list of tuples, where the first element is the
+ name of the file and the second is the file object. Typically HTTPX wants
+ a dict, but to be able to send lists of files, you have to use the list
+ approach (which also works for non-lists)
+ https://github.com/encode/httpx/pull/1032
+ """
+
+ httpx_tuples = []
+ for key, file_like in d.items():
+ if isinstance(file_like, list):
+ for file_like_item in file_like:
+ httpx_tuples.append((key, file_like_item))
+ else:
+ httpx_tuples.append((key, file_like))
+ return httpx_tuples
+
+
+def with_content_type(*, file: File, default_content_type: str) -> File:
+ """
+ This function resolves to the file's content type, if provided, and defaults
+ to the default_content_type value if not.
+ """
+ if isinstance(file, tuple):
+ if len(file) == 2:
+ filename, content = cast(Tuple[Optional[str], FileContent], file) # type: ignore
+ return (filename, content, default_content_type)
+ elif len(file) == 3:
+ filename, content, file_content_type = cast(Tuple[Optional[str], FileContent, Optional[str]], file) # type: ignore
+ out_content_type = file_content_type or default_content_type
+ return (filename, content, out_content_type)
+ elif len(file) == 4:
+ filename, content, file_content_type, headers = cast( # type: ignore
+ Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], file
+ )
+ out_content_type = file_content_type or default_content_type
+ return (filename, content, out_content_type, headers)
+ else:
+ raise ValueError(f"Unexpected tuple length: {len(file)}")
+ return (None, file, default_content_type)
diff --git a/sdks/python/core/force_multipart.py b/sdks/python/core/force_multipart.py
new file mode 100644
index 0000000000..5440913fd4
--- /dev/null
+++ b/sdks/python/core/force_multipart.py
@@ -0,0 +1,18 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Any, Dict
+
+
+class ForceMultipartDict(Dict[str, Any]):
+ """
+ A dictionary subclass that always evaluates to True in boolean contexts.
+
+ This is used to force multipart/form-data encoding in HTTP requests even when
+ the dictionary is empty, which would normally evaluate to False.
+ """
+
+ def __bool__(self) -> bool:
+ return True
+
+
+FORCE_MULTIPART = ForceMultipartDict()
diff --git a/sdks/python/core/http_client.py b/sdks/python/core/http_client.py
new file mode 100644
index 0000000000..f686c5710d
--- /dev/null
+++ b/sdks/python/core/http_client.py
@@ -0,0 +1,839 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import asyncio
+import email.utils
+import re
+import time
+import typing
+from contextlib import asynccontextmanager, contextmanager
+from random import random
+
+import httpx
+from .file import File, convert_file_dict_to_httpx_tuples
+from .force_multipart import FORCE_MULTIPART
+from .jsonable_encoder import jsonable_encoder
+from .logging import LogConfig, Logger, create_logger
+from .query_encoder import encode_query
+from .remove_none_from_dict import remove_none_from_dict as remove_none_from_dict
+from .request_options import RequestOptions
+from httpx._types import RequestFiles
+
+INITIAL_RETRY_DELAY_SECONDS = 1.0
+MAX_RETRY_DELAY_SECONDS = 60.0
+JITTER_FACTOR = 0.2 # 20% random jitter
+
+
+def _parse_retry_after(response_headers: httpx.Headers) -> typing.Optional[float]:
+ """
+ This function parses the `Retry-After` header in a HTTP response and returns the number of seconds to wait.
+
+ Inspired by the urllib3 retry implementation.
+ """
+ retry_after_ms = response_headers.get("retry-after-ms")
+ if retry_after_ms is not None:
+ try:
+ return int(retry_after_ms) / 1000 if retry_after_ms > 0 else 0
+ except Exception:
+ pass
+
+ retry_after = response_headers.get("retry-after")
+ if retry_after is None:
+ return None
+
+ # Attempt to parse the header as an int.
+ if re.match(r"^\s*[0-9]+\s*$", retry_after):
+ seconds = float(retry_after)
+ # Fallback to parsing it as a date.
+ else:
+ retry_date_tuple = email.utils.parsedate_tz(retry_after)
+ if retry_date_tuple is None:
+ return None
+ if retry_date_tuple[9] is None: # Python 2
+ # Assume UTC if no timezone was specified
+ # On Python2.7, parsedate_tz returns None for a timezone offset
+ # instead of 0 if no timezone is given, where mktime_tz treats
+ # a None timezone offset as local time.
+ retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:]
+
+ retry_date = email.utils.mktime_tz(retry_date_tuple)
+ seconds = retry_date - time.time()
+
+ if seconds < 0:
+ seconds = 0
+
+ return seconds
+
+
+def _add_positive_jitter(delay: float) -> float:
+ """Add positive jitter (0-20%) to prevent thundering herd."""
+ jitter_multiplier = 1 + random() * JITTER_FACTOR
+ return delay * jitter_multiplier
+
+
+def _add_symmetric_jitter(delay: float) -> float:
+ """Add symmetric jitter (±10%) for exponential backoff."""
+ jitter_multiplier = 1 + (random() - 0.5) * JITTER_FACTOR
+ return delay * jitter_multiplier
+
+
+def _parse_x_ratelimit_reset(response_headers: httpx.Headers) -> typing.Optional[float]:
+ """
+ Parse the X-RateLimit-Reset header (Unix timestamp in seconds).
+ Returns seconds to wait, or None if header is missing/invalid.
+ """
+ reset_time_str = response_headers.get("x-ratelimit-reset")
+ if reset_time_str is None:
+ return None
+
+ try:
+ reset_time = int(reset_time_str)
+ delay = reset_time - time.time()
+ if delay > 0:
+ return delay
+ except (ValueError, TypeError):
+ pass
+
+ return None
+
+
+def _retry_timeout(response: httpx.Response, retries: int) -> float:
+ """
+ Determine the amount of time to wait before retrying a request.
+ This function begins by trying to parse a retry-after header from the response, and then proceeds to use exponential backoff
+ with a jitter to determine the number of seconds to wait.
+ """
+
+ # 1. Check Retry-After header first
+ retry_after = _parse_retry_after(response.headers)
+ if retry_after is not None and retry_after > 0:
+ return min(retry_after, MAX_RETRY_DELAY_SECONDS)
+
+ # 2. Check X-RateLimit-Reset header (with positive jitter)
+ ratelimit_reset = _parse_x_ratelimit_reset(response.headers)
+ if ratelimit_reset is not None:
+ return _add_positive_jitter(min(ratelimit_reset, MAX_RETRY_DELAY_SECONDS))
+
+ # 3. Fall back to exponential backoff (with symmetric jitter)
+ backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS)
+ return _add_symmetric_jitter(backoff)
+
+
+def _retry_timeout_from_retries(retries: int) -> float:
+ """Determine retry timeout using exponential backoff when no response is available."""
+ backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS)
+ return _add_symmetric_jitter(backoff)
+
+
+def _should_retry(response: httpx.Response) -> bool:
+ return response.status_code >= 500 or response.status_code in [429, 408, 409]
+
+
+_SENSITIVE_HEADERS = frozenset(
+ {
+ "authorization",
+ "www-authenticate",
+ "x-api-key",
+ "api-key",
+ "apikey",
+ "x-api-token",
+ "x-auth-token",
+ "auth-token",
+ "cookie",
+ "set-cookie",
+ "proxy-authorization",
+ "proxy-authenticate",
+ "x-csrf-token",
+ "x-xsrf-token",
+ "x-session-token",
+ "x-access-token",
+ }
+)
+
+
+def _redact_headers(headers: typing.Dict[str, str]) -> typing.Dict[str, str]:
+ return {k: ("[REDACTED]" if k.lower() in _SENSITIVE_HEADERS else v) for k, v in headers.items()}
+
+
+def _build_url(base_url: str, path: typing.Optional[str]) -> str:
+ """
+ Build a full URL by joining a base URL with a path.
+
+ This function correctly handles base URLs that contain path prefixes (e.g., tenant-based URLs)
+ by using string concatenation instead of urllib.parse.urljoin(), which would incorrectly
+ strip path components when the path starts with '/'.
+
+ Example:
+ >>> _build_url("https://cloud.example.com/org/tenant/api", "/users")
+ 'https://cloud.example.com/org/tenant/api/users'
+
+ Args:
+ base_url: The base URL, which may contain path prefixes.
+ path: The path to append. Can be None or empty string.
+
+ Returns:
+ The full URL with base_url and path properly joined.
+ """
+ if not path:
+ return base_url
+ return f"{base_url.rstrip('/')}/{path.lstrip('/')}"
+
+
+def _maybe_filter_none_from_multipart_data(
+ data: typing.Optional[typing.Any],
+ request_files: typing.Optional[RequestFiles],
+ force_multipart: typing.Optional[bool],
+) -> typing.Optional[typing.Any]:
+ """
+ Filter None values from data body for multipart/form requests.
+ This prevents httpx from converting None to empty strings in multipart encoding.
+ Only applies when files are present or force_multipart is True.
+ """
+ if data is not None and isinstance(data, typing.Mapping) and (request_files or force_multipart):
+ return remove_none_from_dict(data)
+ return data
+
+
+def remove_omit_from_dict(
+ original: typing.Dict[str, typing.Optional[typing.Any]],
+ omit: typing.Optional[typing.Any],
+) -> typing.Dict[str, typing.Any]:
+ if omit is None:
+ return original
+ new: typing.Dict[str, typing.Any] = {}
+ for key, value in original.items():
+ if value is not omit:
+ new[key] = value
+ return new
+
+
+def maybe_filter_request_body(
+ data: typing.Optional[typing.Any],
+ request_options: typing.Optional[RequestOptions],
+ omit: typing.Optional[typing.Any],
+) -> typing.Optional[typing.Any]:
+ if data is None:
+ return (
+ jsonable_encoder(request_options.get("additional_body_parameters", {})) or {}
+ if request_options is not None
+ else None
+ )
+ elif not isinstance(data, typing.Mapping):
+ data_content = jsonable_encoder(data)
+ else:
+ data_content = {
+ **(jsonable_encoder(remove_omit_from_dict(data, omit))), # type: ignore
+ **(
+ jsonable_encoder(request_options.get("additional_body_parameters", {})) or {}
+ if request_options is not None
+ else {}
+ ),
+ }
+ return data_content
+
+
+# Abstracted out for testing purposes
+def get_request_body(
+ *,
+ json: typing.Optional[typing.Any],
+ data: typing.Optional[typing.Any],
+ request_options: typing.Optional[RequestOptions],
+ omit: typing.Optional[typing.Any],
+) -> typing.Tuple[typing.Optional[typing.Any], typing.Optional[typing.Any]]:
+ json_body = None
+ data_body = None
+ if data is not None:
+ data_body = maybe_filter_request_body(data, request_options, omit)
+ else:
+ # If both data and json are None, we send json data in the event extra properties are specified
+ json_body = maybe_filter_request_body(json, request_options, omit)
+
+ has_additional_body_parameters = bool(
+ request_options is not None and request_options.get("additional_body_parameters")
+ )
+
+ # Only collapse empty dict to None when the body was not explicitly provided
+ # and there are no additional body parameters. This preserves explicit empty
+ # bodies (e.g., when an endpoint has a request body type but all fields are optional).
+ if json_body == {} and json is None and not has_additional_body_parameters:
+ json_body = None
+ if data_body == {} and data is None and not has_additional_body_parameters:
+ data_body = None
+
+ return json_body, data_body
+
+
+class HttpClient:
+ def __init__(
+ self,
+ *,
+ httpx_client: httpx.Client,
+ base_timeout: typing.Callable[[], typing.Optional[float]],
+ base_headers: typing.Callable[[], typing.Dict[str, str]],
+ base_url: typing.Optional[typing.Callable[[], str]] = None,
+ base_max_retries: int = 2,
+ logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ ):
+ self.base_url = base_url
+ self.base_timeout = base_timeout
+ self.base_headers = base_headers
+ self.base_max_retries = base_max_retries
+ self.httpx_client = httpx_client
+ self.logger = create_logger(logging_config)
+
+ def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
+ base_url = maybe_base_url
+ if self.base_url is not None and base_url is None:
+ base_url = self.base_url()
+
+ if base_url is None:
+ raise ValueError("A base_url is required to make this request, please provide one and try again.")
+ return base_url
+
+ def request(
+ self,
+ path: typing.Optional[str] = None,
+ *,
+ method: str,
+ base_url: typing.Optional[str] = None,
+ params: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ json: typing.Optional[typing.Any] = None,
+ data: typing.Optional[typing.Any] = None,
+ content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None,
+ files: typing.Optional[
+ typing.Union[
+ typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]],
+ typing.List[typing.Tuple[str, File]],
+ ]
+ ] = None,
+ headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ retries: int = 0,
+ omit: typing.Optional[typing.Any] = None,
+ force_multipart: typing.Optional[bool] = None,
+ ) -> httpx.Response:
+ base_url = self.get_base_url(base_url)
+ timeout = (
+ request_options.get("timeout_in_seconds")
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
+ else self.base_timeout()
+ )
+
+ json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
+
+ request_files: typing.Optional[RequestFiles] = (
+ convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit))
+ if (files is not None and files is not omit and isinstance(files, dict))
+ else None
+ )
+
+ if (request_files is None or len(request_files) == 0) and force_multipart:
+ request_files = FORCE_MULTIPART
+
+ data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart)
+
+ # Compute encoded params separately to avoid passing empty list to httpx
+ # (httpx strips existing query params from URL when params=[] is passed)
+ _encoded_params = encode_query(
+ jsonable_encoder(
+ remove_none_from_dict(
+ remove_omit_from_dict(
+ {
+ **(params if params is not None else {}),
+ **(
+ request_options.get("additional_query_parameters", {}) or {}
+ if request_options is not None
+ else {}
+ ),
+ },
+ omit,
+ )
+ )
+ )
+ )
+
+ _request_url = _build_url(base_url, path)
+ _request_headers = jsonable_encoder(
+ remove_none_from_dict(
+ {
+ **self.base_headers(),
+ **(headers if headers is not None else {}),
+ **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
+ }
+ )
+ )
+
+ if self.logger.is_debug():
+ self.logger.debug(
+ "Making HTTP request",
+ method=method,
+ url=_request_url,
+ headers=_redact_headers(_request_headers),
+ has_body=json_body is not None or data_body is not None,
+ )
+
+ max_retries: int = (
+ request_options.get("max_retries", self.base_max_retries)
+ if request_options is not None
+ else self.base_max_retries
+ )
+
+ try:
+ response = self.httpx_client.request(
+ method=method,
+ url=_request_url,
+ headers=_request_headers,
+ params=_encoded_params if _encoded_params else None,
+ json=json_body,
+ data=data_body,
+ content=content,
+ files=request_files,
+ timeout=timeout,
+ )
+ except (httpx.ConnectError, httpx.RemoteProtocolError):
+ if retries < max_retries:
+ time.sleep(_retry_timeout_from_retries(retries=retries))
+ return self.request(
+ path=path,
+ method=method,
+ base_url=base_url,
+ params=params,
+ json=json,
+ data=data,
+ content=content,
+ files=files,
+ headers=headers,
+ request_options=request_options,
+ retries=retries + 1,
+ omit=omit,
+ force_multipart=force_multipart,
+ )
+ raise
+
+ if _should_retry(response=response):
+ if retries < max_retries:
+ time.sleep(_retry_timeout(response=response, retries=retries))
+ return self.request(
+ path=path,
+ method=method,
+ base_url=base_url,
+ params=params,
+ json=json,
+ data=data,
+ content=content,
+ files=files,
+ headers=headers,
+ request_options=request_options,
+ retries=retries + 1,
+ omit=omit,
+ force_multipart=force_multipart,
+ )
+
+ if self.logger.is_debug():
+ if 200 <= response.status_code < 400:
+ self.logger.debug(
+ "HTTP request succeeded",
+ method=method,
+ url=_request_url,
+ status_code=response.status_code,
+ )
+
+ if self.logger.is_error():
+ if response.status_code >= 400:
+ self.logger.error(
+ "HTTP request failed with error status",
+ method=method,
+ url=_request_url,
+ status_code=response.status_code,
+ )
+
+ return response
+
+ @contextmanager
+ def stream(
+ self,
+ path: typing.Optional[str] = None,
+ *,
+ method: str,
+ base_url: typing.Optional[str] = None,
+ params: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ json: typing.Optional[typing.Any] = None,
+ data: typing.Optional[typing.Any] = None,
+ content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None,
+ files: typing.Optional[
+ typing.Union[
+ typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]],
+ typing.List[typing.Tuple[str, File]],
+ ]
+ ] = None,
+ headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ retries: int = 0,
+ omit: typing.Optional[typing.Any] = None,
+ force_multipart: typing.Optional[bool] = None,
+ ) -> typing.Iterator[httpx.Response]:
+ base_url = self.get_base_url(base_url)
+ timeout = (
+ request_options.get("timeout_in_seconds")
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
+ else self.base_timeout()
+ )
+
+ request_files: typing.Optional[RequestFiles] = (
+ convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit))
+ if (files is not None and files is not omit and isinstance(files, dict))
+ else None
+ )
+
+ if (request_files is None or len(request_files) == 0) and force_multipart:
+ request_files = FORCE_MULTIPART
+
+ json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
+
+ data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart)
+
+ # Compute encoded params separately to avoid passing empty list to httpx
+ # (httpx strips existing query params from URL when params=[] is passed)
+ _encoded_params = encode_query(
+ jsonable_encoder(
+ remove_none_from_dict(
+ remove_omit_from_dict(
+ {
+ **(params if params is not None else {}),
+ **(
+ request_options.get("additional_query_parameters", {})
+ if request_options is not None
+ else {}
+ ),
+ },
+ omit,
+ )
+ )
+ )
+ )
+
+ _request_url = _build_url(base_url, path)
+ _request_headers = jsonable_encoder(
+ remove_none_from_dict(
+ {
+ **self.base_headers(),
+ **(headers if headers is not None else {}),
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
+ }
+ )
+ )
+
+ if self.logger.is_debug():
+ self.logger.debug(
+ "Making streaming HTTP request",
+ method=method,
+ url=_request_url,
+ headers=_redact_headers(_request_headers),
+ )
+
+ with self.httpx_client.stream(
+ method=method,
+ url=_request_url,
+ headers=_request_headers,
+ params=_encoded_params if _encoded_params else None,
+ json=json_body,
+ data=data_body,
+ content=content,
+ files=request_files,
+ timeout=timeout,
+ ) as stream:
+ yield stream
+
+
+class AsyncHttpClient:
+ def __init__(
+ self,
+ *,
+ httpx_client: httpx.AsyncClient,
+ base_timeout: typing.Callable[[], typing.Optional[float]],
+ base_headers: typing.Callable[[], typing.Dict[str, str]],
+ base_url: typing.Optional[typing.Callable[[], str]] = None,
+ base_max_retries: int = 2,
+ async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None,
+ logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None,
+ ):
+ self.base_url = base_url
+ self.base_timeout = base_timeout
+ self.base_headers = base_headers
+ self.base_max_retries = base_max_retries
+ self.async_base_headers = async_base_headers
+ self.httpx_client = httpx_client
+ self.logger = create_logger(logging_config)
+
+ async def _get_headers(self) -> typing.Dict[str, str]:
+ if self.async_base_headers is not None:
+ return await self.async_base_headers()
+ return self.base_headers()
+
+ def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str:
+ base_url = maybe_base_url
+ if self.base_url is not None and base_url is None:
+ base_url = self.base_url()
+
+ if base_url is None:
+ raise ValueError("A base_url is required to make this request, please provide one and try again.")
+ return base_url
+
+ async def request(
+ self,
+ path: typing.Optional[str] = None,
+ *,
+ method: str,
+ base_url: typing.Optional[str] = None,
+ params: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ json: typing.Optional[typing.Any] = None,
+ data: typing.Optional[typing.Any] = None,
+ content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None,
+ files: typing.Optional[
+ typing.Union[
+ typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]],
+ typing.List[typing.Tuple[str, File]],
+ ]
+ ] = None,
+ headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ retries: int = 0,
+ omit: typing.Optional[typing.Any] = None,
+ force_multipart: typing.Optional[bool] = None,
+ ) -> httpx.Response:
+ base_url = self.get_base_url(base_url)
+ timeout = (
+ request_options.get("timeout_in_seconds")
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
+ else self.base_timeout()
+ )
+
+ request_files: typing.Optional[RequestFiles] = (
+ convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit))
+ if (files is not None and files is not omit and isinstance(files, dict))
+ else None
+ )
+
+ if (request_files is None or len(request_files) == 0) and force_multipart:
+ request_files = FORCE_MULTIPART
+
+ json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
+
+ data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart)
+
+ # Get headers (supports async token providers)
+ _headers = await self._get_headers()
+
+ # Compute encoded params separately to avoid passing empty list to httpx
+ # (httpx strips existing query params from URL when params=[] is passed)
+ _encoded_params = encode_query(
+ jsonable_encoder(
+ remove_none_from_dict(
+ remove_omit_from_dict(
+ {
+ **(params if params is not None else {}),
+ **(
+ request_options.get("additional_query_parameters", {}) or {}
+ if request_options is not None
+ else {}
+ ),
+ },
+ omit,
+ )
+ )
+ )
+ )
+
+ _request_url = _build_url(base_url, path)
+ _request_headers = jsonable_encoder(
+ remove_none_from_dict(
+ {
+ **_headers,
+ **(headers if headers is not None else {}),
+ **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}),
+ }
+ )
+ )
+
+ if self.logger.is_debug():
+ self.logger.debug(
+ "Making HTTP request",
+ method=method,
+ url=_request_url,
+ headers=_redact_headers(_request_headers),
+ has_body=json_body is not None or data_body is not None,
+ )
+
+ max_retries: int = (
+ request_options.get("max_retries", self.base_max_retries)
+ if request_options is not None
+ else self.base_max_retries
+ )
+
+ try:
+ response = await self.httpx_client.request(
+ method=method,
+ url=_request_url,
+ headers=_request_headers,
+ params=_encoded_params if _encoded_params else None,
+ json=json_body,
+ data=data_body,
+ content=content,
+ files=request_files,
+ timeout=timeout,
+ )
+ except (httpx.ConnectError, httpx.RemoteProtocolError):
+ if retries < max_retries:
+ await asyncio.sleep(_retry_timeout_from_retries(retries=retries))
+ return await self.request(
+ path=path,
+ method=method,
+ base_url=base_url,
+ params=params,
+ json=json,
+ data=data,
+ content=content,
+ files=files,
+ headers=headers,
+ request_options=request_options,
+ retries=retries + 1,
+ omit=omit,
+ force_multipart=force_multipart,
+ )
+ raise
+
+ if _should_retry(response=response):
+ if retries < max_retries:
+ await asyncio.sleep(_retry_timeout(response=response, retries=retries))
+ return await self.request(
+ path=path,
+ method=method,
+ base_url=base_url,
+ params=params,
+ json=json,
+ data=data,
+ content=content,
+ files=files,
+ headers=headers,
+ request_options=request_options,
+ retries=retries + 1,
+ omit=omit,
+ force_multipart=force_multipart,
+ )
+
+ if self.logger.is_debug():
+ if 200 <= response.status_code < 400:
+ self.logger.debug(
+ "HTTP request succeeded",
+ method=method,
+ url=_request_url,
+ status_code=response.status_code,
+ )
+
+ if self.logger.is_error():
+ if response.status_code >= 400:
+ self.logger.error(
+ "HTTP request failed with error status",
+ method=method,
+ url=_request_url,
+ status_code=response.status_code,
+ )
+
+ return response
+
+ @asynccontextmanager
+ async def stream(
+ self,
+ path: typing.Optional[str] = None,
+ *,
+ method: str,
+ base_url: typing.Optional[str] = None,
+ params: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ json: typing.Optional[typing.Any] = None,
+ data: typing.Optional[typing.Any] = None,
+ content: typing.Optional[typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]] = None,
+ files: typing.Optional[
+ typing.Union[
+ typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]],
+ typing.List[typing.Tuple[str, File]],
+ ]
+ ] = None,
+ headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ retries: int = 0,
+ omit: typing.Optional[typing.Any] = None,
+ force_multipart: typing.Optional[bool] = None,
+ ) -> typing.AsyncIterator[httpx.Response]:
+ base_url = self.get_base_url(base_url)
+ timeout = (
+ request_options.get("timeout_in_seconds")
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
+ else self.base_timeout()
+ )
+
+ request_files: typing.Optional[RequestFiles] = (
+ convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit))
+ if (files is not None and files is not omit and isinstance(files, dict))
+ else None
+ )
+
+ if (request_files is None or len(request_files) == 0) and force_multipart:
+ request_files = FORCE_MULTIPART
+
+ json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit)
+
+ data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart)
+
+ # Get headers (supports async token providers)
+ _headers = await self._get_headers()
+
+ # Compute encoded params separately to avoid passing empty list to httpx
+ # (httpx strips existing query params from URL when params=[] is passed)
+ _encoded_params = encode_query(
+ jsonable_encoder(
+ remove_none_from_dict(
+ remove_omit_from_dict(
+ {
+ **(params if params is not None else {}),
+ **(
+ request_options.get("additional_query_parameters", {})
+ if request_options is not None
+ else {}
+ ),
+ },
+ omit=omit,
+ )
+ )
+ )
+ )
+
+ _request_url = _build_url(base_url, path)
+ _request_headers = jsonable_encoder(
+ remove_none_from_dict(
+ {
+ **_headers,
+ **(headers if headers is not None else {}),
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
+ }
+ )
+ )
+
+ if self.logger.is_debug():
+ self.logger.debug(
+ "Making streaming HTTP request",
+ method=method,
+ url=_request_url,
+ headers=_redact_headers(_request_headers),
+ )
+
+ async with self.httpx_client.stream(
+ method=method,
+ url=_request_url,
+ headers=_request_headers,
+ params=_encoded_params if _encoded_params else None,
+ json=json_body,
+ data=data_body,
+ content=content,
+ files=request_files,
+ timeout=timeout,
+ ) as stream:
+ yield stream
diff --git a/sdks/python/core/http_response.py b/sdks/python/core/http_response.py
new file mode 100644
index 0000000000..00bb1096d2
--- /dev/null
+++ b/sdks/python/core/http_response.py
@@ -0,0 +1,59 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Dict, Generic, TypeVar
+
+import httpx
+
+# Generic to represent the underlying type of the data wrapped by the HTTP response.
+T = TypeVar("T")
+
+
+class BaseHttpResponse:
+ """Minimalist HTTP response wrapper that exposes response headers and status code."""
+
+ _response: httpx.Response
+
+ def __init__(self, response: httpx.Response):
+ self._response = response
+
+ @property
+ def headers(self) -> Dict[str, str]:
+ return dict(self._response.headers)
+
+ @property
+ def status_code(self) -> int:
+ return self._response.status_code
+
+
+class HttpResponse(Generic[T], BaseHttpResponse):
+ """HTTP response wrapper that exposes response headers and data."""
+
+ _data: T
+
+ def __init__(self, response: httpx.Response, data: T):
+ super().__init__(response)
+ self._data = data
+
+ @property
+ def data(self) -> T:
+ return self._data
+
+ def close(self) -> None:
+ self._response.close()
+
+
+class AsyncHttpResponse(Generic[T], BaseHttpResponse):
+ """HTTP response wrapper that exposes response headers and data."""
+
+ _data: T
+
+ def __init__(self, response: httpx.Response, data: T):
+ super().__init__(response)
+ self._data = data
+
+ @property
+ def data(self) -> T:
+ return self._data
+
+ async def close(self) -> None:
+ await self._response.aclose()
diff --git a/sdks/python/core/http_sse/__init__.py b/sdks/python/core/http_sse/__init__.py
new file mode 100644
index 0000000000..730e5a3382
--- /dev/null
+++ b/sdks/python/core/http_sse/__init__.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from ._api import EventSource, aconnect_sse, connect_sse
+ from ._exceptions import SSEError
+ from ._models import ServerSentEvent
+_dynamic_imports: typing.Dict[str, str] = {
+ "EventSource": "._api",
+ "SSEError": "._exceptions",
+ "ServerSentEvent": "._models",
+ "aconnect_sse": "._api",
+ "connect_sse": "._api",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["EventSource", "SSEError", "ServerSentEvent", "aconnect_sse", "connect_sse"]
diff --git a/sdks/python/core/http_sse/_api.py b/sdks/python/core/http_sse/_api.py
new file mode 100644
index 0000000000..fd137301b9
--- /dev/null
+++ b/sdks/python/core/http_sse/_api.py
@@ -0,0 +1,170 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import codecs
+import re
+from contextlib import asynccontextmanager, contextmanager
+from typing import Any, AsyncGenerator, AsyncIterator, Iterator
+
+import httpx
+from ._decoders import SSEDecoder
+from ._exceptions import SSEError
+from ._models import ServerSentEvent
+
+MAX_LINE_SIZE: int = 1_048_576 # 1 MiB
+
+
+class EventSource:
+ def __init__(self, response: httpx.Response) -> None:
+ self._response = response
+
+ def _check_content_type(self) -> None:
+ content_type = self._response.headers.get("content-type", "").partition(";")[0]
+ if "text/event-stream" not in content_type:
+ raise SSEError(
+ f"Expected response header Content-Type to contain 'text/event-stream', got {content_type!r}"
+ )
+
+ def _get_charset(self) -> str:
+ """Extract charset from Content-Type header, fallback to UTF-8."""
+ content_type = self._response.headers.get("content-type", "")
+
+ # Parse charset parameter using regex
+ charset_match = re.search(r"charset=([^;\s]+)", content_type, re.IGNORECASE)
+ if charset_match:
+ charset = charset_match.group(1).strip("\"'")
+ # Validate that it's a known encoding
+ try:
+ # Test if the charset is valid by trying to encode/decode
+ "test".encode(charset).decode(charset)
+ return charset
+ except (LookupError, UnicodeError):
+ # If charset is invalid, fall back to UTF-8
+ pass
+
+ # Default to UTF-8 if no charset specified or invalid charset
+ return "utf-8"
+
+ @property
+ def response(self) -> httpx.Response:
+ return self._response
+
+ @staticmethod
+ def _normalize_sse_line_endings(buf: str) -> str:
+ """Normalize line endings per the SSE spec (\\r\\n → \\n, bare \\r → \\n).
+
+ A trailing \\r is preserved because it may pair with a leading \\n in
+ the next chunk to form a single \\r\\n terminator.
+ """
+ buf = buf.replace("\r\n", "\n")
+ if buf.endswith("\r"):
+ return buf[:-1].replace("\r", "\n") + "\r"
+ return buf.replace("\r", "\n")
+
+ def iter_sse(self) -> Iterator[ServerSentEvent]:
+ self._check_content_type()
+ decoder = SSEDecoder()
+ charset = self._get_charset()
+ text_decoder = codecs.getincrementaldecoder(charset)(errors="replace")
+
+ buf = ""
+ for chunk in self._response.iter_bytes():
+ buf += text_decoder.decode(chunk)
+ buf = self._normalize_sse_line_endings(buf)
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
+ sse = decoder.decode(line)
+ if sse is not None:
+ yield sse
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ # Flush any remaining bytes from the incremental decoder
+ buf += text_decoder.decode(b"", final=True)
+ buf = buf.replace("\r\n", "\n").replace("\r", "\n")
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
+ sse = decoder.decode(line)
+ if sse is not None:
+ yield sse
+
+ if buf.strip():
+ sse = decoder.decode(buf)
+ if sse is not None:
+ yield sse
+
+ async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]:
+ self._check_content_type()
+ decoder = SSEDecoder()
+ charset = self._get_charset()
+ text_decoder = codecs.getincrementaldecoder(charset)(errors="replace")
+
+ buf = ""
+ async for chunk in self._response.aiter_bytes():
+ buf += text_decoder.decode(chunk)
+ buf = self._normalize_sse_line_endings(buf)
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
+ sse = decoder.decode(line)
+ if sse is not None:
+ yield sse
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ # Flush any remaining bytes from the incremental decoder
+ buf += text_decoder.decode(b"", final=True)
+ buf = buf.replace("\r\n", "\n").replace("\r", "\n")
+
+ if len(buf) > MAX_LINE_SIZE:
+ raise SSEError(
+ f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline"
+ )
+
+ while "\n" in buf:
+ line, buf = buf.split("\n", 1)
+ sse = decoder.decode(line)
+ if sse is not None:
+ yield sse
+
+ if buf.strip():
+ sse = decoder.decode(buf)
+ if sse is not None:
+ yield sse
+
+
+@contextmanager
+def connect_sse(client: httpx.Client, method: str, url: str, **kwargs: Any) -> Iterator[EventSource]:
+ headers = kwargs.pop("headers", {})
+ headers["Accept"] = "text/event-stream"
+ headers["Cache-Control"] = "no-store"
+
+ with client.stream(method, url, headers=headers, **kwargs) as response:
+ yield EventSource(response)
+
+
+@asynccontextmanager
+async def aconnect_sse(
+ client: httpx.AsyncClient,
+ method: str,
+ url: str,
+ **kwargs: Any,
+) -> AsyncIterator[EventSource]:
+ headers = kwargs.pop("headers", {})
+ headers["Accept"] = "text/event-stream"
+ headers["Cache-Control"] = "no-store"
+
+ async with client.stream(method, url, headers=headers, **kwargs) as response:
+ yield EventSource(response)
diff --git a/sdks/python/core/http_sse/_decoders.py b/sdks/python/core/http_sse/_decoders.py
new file mode 100644
index 0000000000..339b089013
--- /dev/null
+++ b/sdks/python/core/http_sse/_decoders.py
@@ -0,0 +1,61 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import List, Optional
+
+from ._models import ServerSentEvent
+
+
+class SSEDecoder:
+ def __init__(self) -> None:
+ self._event = ""
+ self._data: List[str] = []
+ self._last_event_id = ""
+ self._retry: Optional[int] = None
+
+ def decode(self, line: str) -> Optional[ServerSentEvent]:
+ # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501
+
+ if not line:
+ if not self._event and not self._data and not self._last_event_id and self._retry is None:
+ return None
+
+ sse = ServerSentEvent(
+ event=self._event,
+ data="\n".join(self._data),
+ id=self._last_event_id,
+ retry=self._retry,
+ )
+
+ # NOTE: as per the SSE spec, do not reset last_event_id.
+ self._event = ""
+ self._data = []
+ self._retry = None
+
+ return sse
+
+ if line.startswith(":"):
+ return None
+
+ fieldname, _, value = line.partition(":")
+
+ if value.startswith(" "):
+ value = value[1:]
+
+ if fieldname == "event":
+ self._event = value
+ elif fieldname == "data":
+ self._data.append(value)
+ elif fieldname == "id":
+ if "\0" in value:
+ pass
+ else:
+ self._last_event_id = value
+ elif fieldname == "retry":
+ try:
+ self._retry = int(value)
+ except (TypeError, ValueError):
+ pass
+ else:
+ pass # Field is ignored.
+
+ return None
diff --git a/sdks/python/core/http_sse/_exceptions.py b/sdks/python/core/http_sse/_exceptions.py
new file mode 100644
index 0000000000..81605a8a65
--- /dev/null
+++ b/sdks/python/core/http_sse/_exceptions.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import httpx
+
+
+class SSEError(httpx.TransportError):
+ pass
diff --git a/sdks/python/core/http_sse/_models.py b/sdks/python/core/http_sse/_models.py
new file mode 100644
index 0000000000..1af57f8fd0
--- /dev/null
+++ b/sdks/python/core/http_sse/_models.py
@@ -0,0 +1,17 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import json
+from dataclasses import dataclass
+from typing import Any, Optional
+
+
+@dataclass(frozen=True)
+class ServerSentEvent:
+ event: str = "message"
+ data: str = ""
+ id: str = ""
+ retry: Optional[int] = None
+
+ def json(self) -> Any:
+ """Parse the data field as JSON."""
+ return json.loads(self.data)
diff --git a/sdks/python/core/jsonable_encoder.py b/sdks/python/core/jsonable_encoder.py
new file mode 100644
index 0000000000..5b0902ebcd
--- /dev/null
+++ b/sdks/python/core/jsonable_encoder.py
@@ -0,0 +1,120 @@
+# This file was auto-generated by Fern from our API Definition.
+
+"""
+jsonable_encoder converts a Python object to a JSON-friendly dict
+(e.g. datetimes to strings, Pydantic models to dicts).
+
+Taken from FastAPI, and made a bit simpler
+https://github.com/tiangolo/fastapi/blob/master/fastapi/encoders.py
+"""
+
+import base64
+import dataclasses
+import datetime as dt
+from enum import Enum
+from pathlib import PurePath
+from types import GeneratorType
+from typing import Any, Callable, Dict, List, Optional, Set, Union
+
+import pydantic
+from .datetime_utils import serialize_datetime
+from .pydantic_utilities import (
+ IS_PYDANTIC_V2,
+ encode_by_type,
+ to_jsonable_with_fallback,
+)
+
+SetIntStr = Set[Union[int, str]]
+DictIntStrAny = Dict[Union[int, str], Any]
+
+
+def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None) -> Any:
+ custom_encoder = custom_encoder or {}
+ # Generated SDKs use Ellipsis (`...`) as the sentinel value for "OMIT".
+ # OMIT values should be excluded from serialized payloads.
+ if obj is Ellipsis:
+ return None
+ if custom_encoder:
+ if type(obj) in custom_encoder:
+ return custom_encoder[type(obj)](obj)
+ else:
+ for encoder_type, encoder_instance in custom_encoder.items():
+ if isinstance(obj, encoder_type):
+ return encoder_instance(obj)
+ if isinstance(obj, pydantic.BaseModel):
+ if IS_PYDANTIC_V2:
+ encoder = getattr(obj.model_config, "json_encoders", {}) # type: ignore # Pydantic v2
+ else:
+ encoder = getattr(obj.__config__, "json_encoders", {}) # type: ignore # Pydantic v1
+ if custom_encoder:
+ encoder.update(custom_encoder)
+ obj_dict = obj.dict(by_alias=True)
+ if "__root__" in obj_dict:
+ obj_dict = obj_dict["__root__"]
+ if "root" in obj_dict:
+ obj_dict = obj_dict["root"]
+ return jsonable_encoder(obj_dict, custom_encoder=encoder)
+ if dataclasses.is_dataclass(obj):
+ obj_dict = dataclasses.asdict(obj) # type: ignore
+ return jsonable_encoder(obj_dict, custom_encoder=custom_encoder)
+ if isinstance(obj, bytes):
+ return base64.b64encode(obj).decode("utf-8")
+ if isinstance(obj, Enum):
+ return obj.value
+ if isinstance(obj, PurePath):
+ return str(obj)
+ if isinstance(obj, (str, int, float, type(None))):
+ return obj
+ if isinstance(obj, dt.datetime):
+ return serialize_datetime(obj)
+ if isinstance(obj, dt.date):
+ return str(obj)
+ if isinstance(obj, dict):
+ encoded_dict = {}
+ allowed_keys = set(obj.keys())
+ for key, value in obj.items():
+ if key in allowed_keys:
+ if value is Ellipsis:
+ continue
+ encoded_key = jsonable_encoder(key, custom_encoder=custom_encoder)
+ encoded_value = jsonable_encoder(value, custom_encoder=custom_encoder)
+ encoded_dict[encoded_key] = encoded_value
+ return encoded_dict
+ if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)):
+ encoded_list = []
+ for item in obj:
+ if item is Ellipsis:
+ continue
+ encoded_list.append(jsonable_encoder(item, custom_encoder=custom_encoder))
+ return encoded_list
+
+ def fallback_serializer(o: Any) -> Any:
+ attempt_encode = encode_by_type(o)
+ if attempt_encode is not None:
+ return attempt_encode
+
+ try:
+ data = dict(o)
+ except Exception as e:
+ errors: List[Exception] = []
+ errors.append(e)
+ try:
+ data = vars(o)
+ except Exception as e:
+ errors.append(e)
+ raise ValueError(errors) from e
+ return jsonable_encoder(data, custom_encoder=custom_encoder)
+
+ return to_jsonable_with_fallback(obj, fallback_serializer)
+
+
+def encode_path_param(obj: Any) -> str:
+ """Encode a value for use in a URL path segment.
+
+ Ensures proper string conversion for all types, including
+ booleans which need lowercase 'true'/'false' rather than
+ Python's 'True'/'False'.
+ """
+ if isinstance(obj, bool):
+ return "true" if obj else "false"
+ return str(jsonable_encoder(obj))
diff --git a/sdks/python/core/logging.py b/sdks/python/core/logging.py
new file mode 100644
index 0000000000..e5e572458b
--- /dev/null
+++ b/sdks/python/core/logging.py
@@ -0,0 +1,107 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import logging
+import typing
+
+LogLevel = typing.Literal["debug", "info", "warn", "error"]
+
+_LOG_LEVEL_MAP: typing.Dict[LogLevel, int] = {
+ "debug": 1,
+ "info": 2,
+ "warn": 3,
+ "error": 4,
+}
+
+
+class ILogger(typing.Protocol):
+ def debug(self, message: str, **kwargs: typing.Any) -> None: ...
+ def info(self, message: str, **kwargs: typing.Any) -> None: ...
+ def warn(self, message: str, **kwargs: typing.Any) -> None: ...
+ def error(self, message: str, **kwargs: typing.Any) -> None: ...
+
+
+class ConsoleLogger:
+ _logger: logging.Logger
+
+ def __init__(self) -> None:
+ self._logger = logging.getLogger("fern")
+ if not self._logger.handlers:
+ handler = logging.StreamHandler()
+ handler.setFormatter(logging.Formatter("%(levelname)s - %(message)s"))
+ self._logger.addHandler(handler)
+ self._logger.setLevel(logging.DEBUG)
+
+ def debug(self, message: str, **kwargs: typing.Any) -> None:
+ self._logger.debug(message, extra=kwargs)
+
+ def info(self, message: str, **kwargs: typing.Any) -> None:
+ self._logger.info(message, extra=kwargs)
+
+ def warn(self, message: str, **kwargs: typing.Any) -> None:
+ self._logger.warning(message, extra=kwargs)
+
+ def error(self, message: str, **kwargs: typing.Any) -> None:
+ self._logger.error(message, extra=kwargs)
+
+
+class LogConfig(typing.TypedDict, total=False):
+ level: LogLevel
+ logger: ILogger
+ silent: bool
+
+
+class Logger:
+ _level: int
+ _logger: ILogger
+ _silent: bool
+
+ def __init__(self, *, level: LogLevel, logger: ILogger, silent: bool) -> None:
+ self._level = _LOG_LEVEL_MAP[level]
+ self._logger = logger
+ self._silent = silent
+
+ def _should_log(self, level: LogLevel) -> bool:
+ return not self._silent and self._level <= _LOG_LEVEL_MAP[level]
+
+ def is_debug(self) -> bool:
+ return self._should_log("debug")
+
+ def is_info(self) -> bool:
+ return self._should_log("info")
+
+ def is_warn(self) -> bool:
+ return self._should_log("warn")
+
+ def is_error(self) -> bool:
+ return self._should_log("error")
+
+ def debug(self, message: str, **kwargs: typing.Any) -> None:
+ if self.is_debug():
+ self._logger.debug(message, **kwargs)
+
+ def info(self, message: str, **kwargs: typing.Any) -> None:
+ if self.is_info():
+ self._logger.info(message, **kwargs)
+
+ def warn(self, message: str, **kwargs: typing.Any) -> None:
+ if self.is_warn():
+ self._logger.warn(message, **kwargs)
+
+ def error(self, message: str, **kwargs: typing.Any) -> None:
+ if self.is_error():
+ self._logger.error(message, **kwargs)
+
+
+_default_logger: Logger = Logger(level="info", logger=ConsoleLogger(), silent=True)
+
+
+def create_logger(config: typing.Optional[typing.Union[LogConfig, Logger]] = None) -> Logger:
+ if config is None:
+ return _default_logger
+ if isinstance(config, Logger):
+ return config
+ return Logger(
+ level=config.get("level", "info"),
+ logger=config.get("logger", ConsoleLogger()),
+ silent=config.get("silent", True),
+ )
diff --git a/sdks/python/core/parse_error.py b/sdks/python/core/parse_error.py
new file mode 100644
index 0000000000..4527c6a8ad
--- /dev/null
+++ b/sdks/python/core/parse_error.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Any, Dict, Optional
+
+
+class ParsingError(Exception):
+ """
+ Raised when the SDK fails to parse/validate a response from the server.
+ This typically indicates that the server returned a response whose shape
+ does not match the expected schema.
+ """
+
+ headers: Optional[Dict[str, str]]
+ status_code: Optional[int]
+ body: Any
+ cause: Optional[Exception]
+
+ def __init__(
+ self,
+ *,
+ headers: Optional[Dict[str, str]] = None,
+ status_code: Optional[int] = None,
+ body: Any = None,
+ cause: Optional[Exception] = None,
+ ) -> None:
+ self.headers = headers
+ self.status_code = status_code
+ self.body = body
+ self.cause = cause
+ super().__init__()
+ if cause is not None:
+ self.__cause__ = cause
+
+ def __str__(self) -> str:
+ cause_str = f", cause: {self.cause}" if self.cause is not None else ""
+ return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}{cause_str}"
diff --git a/sdks/python/core/pydantic_utilities.py b/sdks/python/core/pydantic_utilities.py
new file mode 100644
index 0000000000..6587f5e182
--- /dev/null
+++ b/sdks/python/core/pydantic_utilities.py
@@ -0,0 +1,508 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# nopycln: file
+import datetime as dt
+import inspect
+import json
+import logging
+from collections import defaultdict
+from dataclasses import asdict
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Callable,
+ ClassVar,
+ Dict,
+ List,
+ Mapping,
+ Optional,
+ Set,
+ Tuple,
+ Type,
+ TypeVar,
+ Union,
+ cast,
+)
+
+import pydantic
+import typing_extensions
+from pydantic.fields import FieldInfo as _FieldInfo
+
+_logger = logging.getLogger(__name__)
+
+if TYPE_CHECKING:
+ from .http_sse._models import ServerSentEvent
+
+IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
+
+if IS_PYDANTIC_V2:
+ _datetime_adapter = pydantic.TypeAdapter(dt.datetime) # type: ignore[attr-defined]
+ _date_adapter = pydantic.TypeAdapter(dt.date) # type: ignore[attr-defined]
+
+ def parse_datetime(value: Any) -> dt.datetime: # type: ignore[misc]
+ if isinstance(value, dt.datetime):
+ return value
+ return _datetime_adapter.validate_python(value)
+
+ def parse_date(value: Any) -> dt.date: # type: ignore[misc]
+ if isinstance(value, dt.datetime):
+ return value.date()
+ if isinstance(value, dt.date):
+ return value
+ return _date_adapter.validate_python(value)
+
+ # Avoid importing from pydantic.v1 to maintain Python 3.14 compatibility.
+ from typing import get_args as get_args # type: ignore[assignment]
+ from typing import get_origin as get_origin # type: ignore[assignment]
+
+ def is_literal_type(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc]
+ return typing_extensions.get_origin(tp) is typing_extensions.Literal
+
+ def is_union(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc]
+ return tp is Union or typing_extensions.get_origin(tp) is Union # type: ignore[comparison-overlap]
+
+ # Inline encoders_by_type to avoid importing from pydantic.v1.json
+ import re as _re
+ from collections import deque as _deque
+ from decimal import Decimal as _Decimal
+ from enum import Enum as _Enum
+ from ipaddress import (
+ IPv4Address as _IPv4Address,
+ )
+ from ipaddress import (
+ IPv4Interface as _IPv4Interface,
+ )
+ from ipaddress import (
+ IPv4Network as _IPv4Network,
+ )
+ from ipaddress import (
+ IPv6Address as _IPv6Address,
+ )
+ from ipaddress import (
+ IPv6Interface as _IPv6Interface,
+ )
+ from ipaddress import (
+ IPv6Network as _IPv6Network,
+ )
+ from pathlib import Path as _Path
+ from types import GeneratorType as _GeneratorType
+ from uuid import UUID as _UUID
+
+ from pydantic.fields import FieldInfo as ModelField # type: ignore[no-redef, assignment]
+
+ def _decimal_encoder(dec_value: Any) -> Any:
+ if dec_value.as_tuple().exponent >= 0:
+ return int(dec_value)
+ return float(dec_value)
+
+ encoders_by_type: Dict[Type[Any], Callable[[Any], Any]] = { # type: ignore[no-redef]
+ bytes: lambda o: o.decode(),
+ dt.date: lambda o: o.isoformat(),
+ dt.datetime: lambda o: o.isoformat(),
+ dt.time: lambda o: o.isoformat(),
+ dt.timedelta: lambda td: td.total_seconds(),
+ _Decimal: _decimal_encoder,
+ _Enum: lambda o: o.value,
+ frozenset: list,
+ _deque: list,
+ _GeneratorType: list,
+ _IPv4Address: str,
+ _IPv4Interface: str,
+ _IPv4Network: str,
+ _IPv6Address: str,
+ _IPv6Interface: str,
+ _IPv6Network: str,
+ _Path: str,
+ _re.Pattern: lambda o: o.pattern,
+ set: list,
+ _UUID: str,
+ }
+else:
+ from pydantic.datetime_parse import parse_date as parse_date # type: ignore[no-redef]
+ from pydantic.datetime_parse import parse_datetime as parse_datetime # type: ignore[no-redef]
+ from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef, assignment]
+ from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[no-redef]
+ from pydantic.typing import get_args as get_args # type: ignore[no-redef]
+ from pydantic.typing import get_origin as get_origin # type: ignore[no-redef]
+ from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef, assignment]
+ from pydantic.typing import is_union as is_union # type: ignore[no-redef]
+
+from .datetime_utils import serialize_datetime
+from .serialization import convert_and_respect_annotation_metadata
+from typing_extensions import TypeAlias
+
+T = TypeVar("T")
+Model = TypeVar("Model", bound=pydantic.BaseModel)
+
+
+def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T:
+ """
+ Parse a ServerSentEvent into the appropriate type.
+
+ This function handles data-level discrimination where the discriminator
+ (e.g., 'type') is inside the 'data' payload. It parses the SSE data field
+ as JSON and deserializes it into the target type.
+
+ Note: Protocol-level discrimination (where the discriminator comes from
+ the SSE event: field) is handled at code-generation time and does not
+ use this function.
+
+ Args:
+ sse: The ServerSentEvent object to parse
+ type_: The target type to deserialize into
+
+ Returns:
+ The parsed object of type T
+
+ Note:
+ This function is only available in SDK contexts where http_sse module exists.
+ """
+ sse_event = asdict(sse)
+ data_value = sse_event.get("data")
+ if isinstance(data_value, str) and data_value:
+ try:
+ parsed_data = json.loads(data_value)
+ return parse_obj_as(type_, parsed_data)
+ except json.JSONDecodeError as e:
+ _logger.warning(
+ "Failed to parse SSE data field as JSON: %s, data: %s",
+ e,
+ data_value[:100] if len(data_value) > 100 else data_value,
+ )
+ return parse_obj_as(type_, sse_event)
+
+
+_type_adapter_cache: Dict[int, Any] = {}
+
+
+def _get_type_adapter(type_: Type[Any]) -> Any:
+ key = id(type_)
+ adapter = _type_adapter_cache.get(key)
+ if adapter is None:
+ adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined]
+ _type_adapter_cache[key] = adapter
+ return adapter
+
+
+def parse_obj_as(type_: Type[T], object_: Any) -> T:
+ # convert_and_respect_annotation_metadata is required for TypedDict aliasing.
+ #
+ # For Pydantic models, whether we should pre-dealias depends on how the model encodes aliasing:
+ # - If the model uses real Pydantic aliases (pydantic.Field(alias=...)), then we must pass wire keys through
+ # unchanged so Pydantic can validate them.
+ # - If the model encodes aliasing only via FieldMetadata annotations, then we MUST pre-dealias because Pydantic
+ # will not recognize those aliases during validation.
+ if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel):
+ has_pydantic_aliases = False
+ if IS_PYDANTIC_V2:
+ for field_name, field_info in getattr(type_, "model_fields", {}).items(): # type: ignore[attr-defined]
+ alias = getattr(field_info, "alias", None)
+ if alias is not None and alias != field_name:
+ has_pydantic_aliases = True
+ break
+ else:
+ for field in getattr(type_, "__fields__", {}).values():
+ alias = getattr(field, "alias", None)
+ name = getattr(field, "name", None)
+ if alias is not None and name is not None and alias != name:
+ has_pydantic_aliases = True
+ break
+
+ dealiased_object = (
+ object_
+ if has_pydantic_aliases
+ else convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
+ )
+ else:
+ dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
+ if IS_PYDANTIC_V2:
+ adapter = _get_type_adapter(type_)
+ return adapter.validate_python(dealiased_object) # type: ignore[no-any-return]
+ return pydantic.parse_obj_as(type_, dealiased_object)
+
+
+def to_jsonable_with_fallback(obj: Any, fallback_serializer: Callable[[Any], Any]) -> Any:
+ if IS_PYDANTIC_V2:
+ from pydantic_core import to_jsonable_python
+
+ return to_jsonable_python(obj, fallback=fallback_serializer)
+ return fallback_serializer(obj)
+
+
+class UniversalBaseModel(pydantic.BaseModel):
+ if IS_PYDANTIC_V2:
+ model_config: ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( # type: ignore[typeddict-unknown-key]
+ # Allow fields beginning with `model_` to be used in the model
+ protected_namespaces=(),
+ )
+
+ @pydantic.model_validator(mode="before") # type: ignore[attr-defined]
+ @classmethod
+ def _coerce_field_names_to_aliases(cls, data: Any) -> Any:
+ """
+ Accept Python field names in input by rewriting them to their Pydantic aliases,
+ while avoiding silent collisions when a key could refer to multiple fields.
+ """
+ if not isinstance(data, Mapping):
+ return data
+
+ fields = getattr(cls, "model_fields", {}) # type: ignore[attr-defined]
+ name_to_alias: Dict[str, str] = {}
+ alias_to_name: Dict[str, str] = {}
+
+ for name, field_info in fields.items():
+ alias = getattr(field_info, "alias", None) or name
+ name_to_alias[name] = alias
+ if alias != name:
+ alias_to_name[alias] = name
+
+ # Detect ambiguous keys: a key that is an alias for one field and a name for another.
+ ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys()))
+ for key in ambiguous_keys:
+ if key in data and name_to_alias[key] not in data:
+ raise ValueError(
+ f"Ambiguous input key '{key}': it is both a field name and an alias. "
+ "Provide the explicit alias key to disambiguate."
+ )
+
+ original_keys = set(data.keys())
+ rewritten: Dict[str, Any] = dict(data)
+ for name, alias in name_to_alias.items():
+ if alias != name and name in original_keys and alias not in rewritten:
+ rewritten[alias] = rewritten.pop(name)
+
+ return rewritten
+
+ @pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined]
+ def serialize_model(self) -> Any: # type: ignore[name-defined]
+ serialized = self.dict() # type: ignore[attr-defined]
+ data = {k: serialize_datetime(v) if isinstance(v, dt.datetime) else v for k, v in serialized.items()}
+ return data
+
+ else:
+
+ class Config:
+ smart_union = True
+ json_encoders = {dt.datetime: serialize_datetime}
+
+ @pydantic.root_validator(pre=True)
+ def _coerce_field_names_to_aliases(cls, values: Any) -> Any:
+ """
+ Pydantic v1 equivalent of _coerce_field_names_to_aliases.
+ """
+ if not isinstance(values, Mapping):
+ return values
+
+ fields = getattr(cls, "__fields__", {})
+ name_to_alias: Dict[str, str] = {}
+ alias_to_name: Dict[str, str] = {}
+
+ for name, field in fields.items():
+ alias = getattr(field, "alias", None) or name
+ name_to_alias[name] = alias
+ if alias != name:
+ alias_to_name[alias] = name
+
+ ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys()))
+ for key in ambiguous_keys:
+ if key in values and name_to_alias[key] not in values:
+ raise ValueError(
+ f"Ambiguous input key '{key}': it is both a field name and an alias. "
+ "Provide the explicit alias key to disambiguate."
+ )
+
+ original_keys = set(values.keys())
+ rewritten: Dict[str, Any] = dict(values)
+ for name, alias in name_to_alias.items():
+ if alias != name and name in original_keys and alias not in rewritten:
+ rewritten[alias] = rewritten.pop(name)
+
+ return rewritten
+
+ @classmethod
+ def model_construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model":
+ dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read")
+ return cls.construct(_fields_set, **dealiased_object)
+
+ @classmethod
+ def construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model":
+ dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read")
+ if IS_PYDANTIC_V2:
+ return super().model_construct(_fields_set, **dealiased_object) # type: ignore[misc]
+ return super().construct(_fields_set, **dealiased_object)
+
+ def json(self, **kwargs: Any) -> str:
+ kwargs_with_defaults = {
+ "by_alias": True,
+ "exclude_unset": True,
+ **kwargs,
+ }
+ if IS_PYDANTIC_V2:
+ return super().model_dump_json(**kwargs_with_defaults) # type: ignore[misc]
+ return super().json(**kwargs_with_defaults)
+
+ def dict(self, **kwargs: Any) -> Dict[str, Any]:
+ """
+ Override the default dict method to `exclude_unset` by default. This function patches
+ `exclude_unset` to work include fields within non-None default values.
+ """
+ # Note: the logic here is multiplexed given the levers exposed in Pydantic V1 vs V2
+ # Pydantic V1's .dict can be extremely slow, so we do not want to call it twice.
+ #
+ # We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
+ # that we have less control over, and this is less intrusive than custom serializers for now.
+ if IS_PYDANTIC_V2:
+ kwargs_with_defaults_exclude_unset = {
+ **kwargs,
+ "by_alias": True,
+ "exclude_unset": True,
+ "exclude_none": False,
+ }
+ kwargs_with_defaults_exclude_none = {
+ **kwargs,
+ "by_alias": True,
+ "exclude_none": True,
+ "exclude_unset": False,
+ }
+ dict_dump = deep_union_pydantic_dicts(
+ super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore[misc]
+ super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore[misc]
+ )
+
+ else:
+ _fields_set = self.__fields_set__.copy()
+
+ fields = _get_model_fields(self.__class__)
+ for name, field in fields.items():
+ if name not in _fields_set:
+ default = _get_field_default(field)
+
+ # If the default values are non-null act like they've been set
+ # This effectively allows exclude_unset to work like exclude_none where
+ # the latter passes through intentionally set none values.
+ if default is not None or ("exclude_unset" in kwargs and not kwargs["exclude_unset"]):
+ _fields_set.add(name)
+
+ if default is not None:
+ self.__fields_set__.add(name)
+
+ kwargs_with_defaults_exclude_unset_include_fields = {
+ "by_alias": True,
+ "exclude_unset": True,
+ "include": _fields_set,
+ **kwargs,
+ }
+
+ dict_dump = super().dict(**kwargs_with_defaults_exclude_unset_include_fields)
+
+ return cast(
+ Dict[str, Any],
+ convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write"),
+ )
+
+
+def _union_list_of_pydantic_dicts(source: List[Any], destination: List[Any]) -> List[Any]:
+ converted_list: List[Any] = []
+ for i, item in enumerate(source):
+ destination_value = destination[i]
+ if isinstance(item, dict):
+ converted_list.append(deep_union_pydantic_dicts(item, destination_value))
+ elif isinstance(item, list):
+ converted_list.append(_union_list_of_pydantic_dicts(item, destination_value))
+ else:
+ converted_list.append(item)
+ return converted_list
+
+
+def deep_union_pydantic_dicts(source: Dict[str, Any], destination: Dict[str, Any]) -> Dict[str, Any]:
+ for key, value in source.items():
+ node = destination.setdefault(key, {})
+ if isinstance(value, dict):
+ deep_union_pydantic_dicts(value, node)
+ # Note: we do not do this same processing for sets given we do not have sets of models
+ # and given the sets are unordered, the processing of the set and matching objects would
+ # be non-trivial.
+ elif isinstance(value, list):
+ destination[key] = _union_list_of_pydantic_dicts(value, node)
+ else:
+ destination[key] = value
+
+ return destination
+
+
+if IS_PYDANTIC_V2:
+
+ class V2RootModel(UniversalBaseModel, pydantic.RootModel): # type: ignore[misc, name-defined, type-arg]
+ pass
+
+ UniversalRootModel: TypeAlias = V2RootModel # type: ignore[misc]
+else:
+ UniversalRootModel: TypeAlias = UniversalBaseModel # type: ignore[misc, no-redef]
+
+
+def encode_by_type(o: Any) -> Any:
+ encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(tuple)
+ for type_, encoder in encoders_by_type.items():
+ encoders_by_class_tuples[encoder] += (type_,)
+
+ if type(o) in encoders_by_type:
+ return encoders_by_type[type(o)](o)
+ for encoder, classes_tuple in encoders_by_class_tuples.items():
+ if isinstance(o, classes_tuple):
+ return encoder(o)
+
+
+def update_forward_refs(model: Type["Model"], **localns: Any) -> None:
+ if IS_PYDANTIC_V2:
+ model.model_rebuild(raise_errors=False) # type: ignore[attr-defined]
+ else:
+ model.update_forward_refs(**localns)
+
+
+# Mirrors Pydantic's internal typing
+AnyCallable = Callable[..., Any]
+
+
+def universal_root_validator(
+ pre: bool = False,
+) -> Callable[[AnyCallable], AnyCallable]:
+ def decorator(func: AnyCallable) -> AnyCallable:
+ if IS_PYDANTIC_V2:
+ # In Pydantic v2, for RootModel we always use "before" mode
+ # The custom validators transform the input value before the model is created
+ return cast(AnyCallable, pydantic.model_validator(mode="before")(func)) # type: ignore[attr-defined]
+ return cast(AnyCallable, pydantic.root_validator(pre=pre)(func)) # type: ignore[call-overload]
+
+ return decorator
+
+
+def universal_field_validator(field_name: str, pre: bool = False) -> Callable[[AnyCallable], AnyCallable]:
+ def decorator(func: AnyCallable) -> AnyCallable:
+ if IS_PYDANTIC_V2:
+ return cast(AnyCallable, pydantic.field_validator(field_name, mode="before" if pre else "after")(func)) # type: ignore[attr-defined]
+ return cast(AnyCallable, pydantic.validator(field_name, pre=pre)(func))
+
+ return decorator
+
+
+PydanticField = Union[ModelField, _FieldInfo]
+
+
+def _get_model_fields(model: Type["Model"]) -> Mapping[str, PydanticField]:
+ if IS_PYDANTIC_V2:
+ return cast(Mapping[str, PydanticField], model.model_fields) # type: ignore[attr-defined]
+ return cast(Mapping[str, PydanticField], model.__fields__)
+
+
+def _get_field_default(field: PydanticField) -> Any:
+ try:
+ value = field.get_default() # type: ignore[union-attr]
+ except:
+ value = field.default
+ if IS_PYDANTIC_V2:
+ from pydantic_core import PydanticUndefined
+
+ if value == PydanticUndefined:
+ return None
+ return value
+ return value
diff --git a/sdks/python/core/query_encoder.py b/sdks/python/core/query_encoder.py
new file mode 100644
index 0000000000..3183001d40
--- /dev/null
+++ b/sdks/python/core/query_encoder.py
@@ -0,0 +1,58 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Any, Dict, List, Optional, Tuple
+
+import pydantic
+
+
+# Flattens dicts to be of the form {"key[subkey][subkey2]": value} where value is not a dict
+def traverse_query_dict(dict_flat: Dict[str, Any], key_prefix: Optional[str] = None) -> List[Tuple[str, Any]]:
+ result = []
+ for k, v in dict_flat.items():
+ key = f"{key_prefix}[{k}]" if key_prefix is not None else k
+ if isinstance(v, dict):
+ result.extend(traverse_query_dict(v, key))
+ elif isinstance(v, list):
+ for arr_v in v:
+ if isinstance(arr_v, dict):
+ result.extend(traverse_query_dict(arr_v, key))
+ else:
+ result.append((key, arr_v))
+ else:
+ result.append((key, v))
+ return result
+
+
+def single_query_encoder(query_key: str, query_value: Any) -> List[Tuple[str, Any]]:
+ if isinstance(query_value, pydantic.BaseModel) or isinstance(query_value, dict):
+ if isinstance(query_value, pydantic.BaseModel):
+ obj_dict = query_value.dict(by_alias=True)
+ else:
+ obj_dict = query_value
+ return traverse_query_dict(obj_dict, query_key)
+ elif isinstance(query_value, list):
+ encoded_values: List[Tuple[str, Any]] = []
+ for value in query_value:
+ if isinstance(value, pydantic.BaseModel) or isinstance(value, dict):
+ if isinstance(value, pydantic.BaseModel):
+ obj_dict = value.dict(by_alias=True)
+ elif isinstance(value, dict):
+ obj_dict = value
+
+ encoded_values.extend(single_query_encoder(query_key, obj_dict))
+ else:
+ encoded_values.append((query_key, value))
+
+ return encoded_values
+
+ return [(query_key, query_value)]
+
+
+def encode_query(query: Optional[Dict[str, Any]]) -> Optional[List[Tuple[str, Any]]]:
+ if query is None:
+ return None
+
+ encoded_query = []
+ for k, v in query.items():
+ encoded_query.extend(single_query_encoder(k, v))
+ return encoded_query
diff --git a/sdks/python/core/remove_none_from_dict.py b/sdks/python/core/remove_none_from_dict.py
new file mode 100644
index 0000000000..c2298143f1
--- /dev/null
+++ b/sdks/python/core/remove_none_from_dict.py
@@ -0,0 +1,11 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from typing import Any, Dict, Mapping, Optional
+
+
+def remove_none_from_dict(original: Mapping[str, Optional[Any]]) -> Dict[str, Any]:
+ new: Dict[str, Any] = {}
+ for key, value in original.items():
+ if value is not None:
+ new[key] = value
+ return new
diff --git a/sdks/python/core/request_options.py b/sdks/python/core/request_options.py
new file mode 100644
index 0000000000..1b38804432
--- /dev/null
+++ b/sdks/python/core/request_options.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+try:
+ from typing import NotRequired # type: ignore
+except ImportError:
+ from typing_extensions import NotRequired
+
+
+class RequestOptions(typing.TypedDict, total=False):
+ """
+ Additional options for request-specific configuration when calling APIs via the SDK.
+ This is used primarily as an optional final parameter for service functions.
+
+ Attributes:
+ - timeout_in_seconds: int. The number of seconds to await an API call before timing out.
+
+ - max_retries: int. The max number of retries to attempt if the API call fails.
+
+ - additional_headers: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's header dict
+
+ - additional_query_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's query parameters dict
+
+ - additional_body_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's body parameters dict
+
+ - chunk_size: int. The size, in bytes, to process each chunk of data being streamed back within the response. This equates to leveraging `chunk_size` within `requests` or `httpx`, and is only leveraged for file downloads.
+ """
+
+ timeout_in_seconds: NotRequired[int]
+ max_retries: NotRequired[int]
+ additional_headers: NotRequired[typing.Dict[str, typing.Any]]
+ additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]]
+ additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]]
+ chunk_size: NotRequired[int]
diff --git a/sdks/python/core/serialization.py b/sdks/python/core/serialization.py
new file mode 100644
index 0000000000..1d753e26f7
--- /dev/null
+++ b/sdks/python/core/serialization.py
@@ -0,0 +1,347 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import collections
+import inspect
+import typing
+
+import pydantic
+import typing_extensions
+
+
+class FieldMetadata:
+ """
+ Metadata class used to annotate fields to provide additional information.
+
+ Example:
+ class MyDict(TypedDict):
+ field: typing.Annotated[str, FieldMetadata(alias="field_name")]
+
+ Will serialize: `{"field": "value"}`
+ To: `{"field_name": "value"}`
+ """
+
+ alias: str
+
+ def __init__(self, *, alias: str) -> None:
+ self.alias = alias
+
+
+# Resolving type hints (typing.get_type_hints) is expensive because it eval/compiles
+# forward-reference annotations. The result is constant for a given type, so we cache it.
+# This is critical for hot paths like SSE event parsing, where the same (often large
+# discriminated-union) type is converted on every single event.
+_type_hints_cache: typing.Dict[typing.Any, typing.Dict[str, typing.Any]] = {}
+
+
+def _get_cached_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
+ try:
+ cached = _type_hints_cache.get(expected_type)
+ except TypeError:
+ # Unhashable type; resolve without caching.
+ return _resolve_type_hints(expected_type)
+ if cached is None:
+ cached = _resolve_type_hints(expected_type)
+ _type_hints_cache[expected_type] = cached
+ return cached
+
+
+def _resolve_type_hints(expected_type: typing.Any) -> typing.Dict[str, typing.Any]:
+ try:
+ return typing_extensions.get_type_hints(expected_type, include_extras=True)
+ except NameError:
+ # The type contains a circular reference, so we use the __annotations__ attribute directly.
+ return getattr(expected_type, "__annotations__", {})
+
+
+# Whether convert_and_respect_annotation_metadata can possibly rewrite anything for a given
+# annotation, i.e. whether any reachable model/TypedDict field carries a FieldMetadata alias.
+# This is constant per type, so we cache it and use it to short-circuit the recursive walk.
+_requires_conversion_cache: typing.Dict[typing.Any, bool] = {}
+
+
+def _requires_conversion(type_: typing.Any) -> bool:
+ try:
+ cached = _requires_conversion_cache.get(type_)
+ except TypeError:
+ # Unhashable annotation; compute without caching.
+ return _compute_requires_conversion(type_, set())
+ if cached is None:
+ cached = _compute_requires_conversion(type_, set())
+ _requires_conversion_cache[type_] = cached
+ return cached
+
+
+def _compute_requires_conversion(type_: typing.Any, seen: typing.Set[typing.Any]) -> bool:
+ clean_type = _remove_annotations(type_)
+
+ try:
+ if clean_type in seen:
+ return False
+ seen = seen | {clean_type}
+ except TypeError:
+ # Unhashable type; skip cycle tracking (the type graph is finite in practice).
+ pass
+
+ # Models / TypedDicts: a field alias here means we must dealias; otherwise recurse into fields.
+ if (inspect.isclass(clean_type) and issubclass(clean_type, pydantic.BaseModel)) or typing_extensions.is_typeddict(
+ clean_type
+ ):
+ annotations = _get_cached_type_hints(clean_type)
+ if _get_alias_to_field_name(annotations):
+ return True
+ return any(_compute_requires_conversion(hint, seen) for hint in annotations.values())
+
+ # Containers / unions: recurse into the type arguments (List/Set/Sequence/Dict/Union/etc.).
+ return any(_compute_requires_conversion(arg, seen) for arg in typing_extensions.get_args(clean_type))
+
+
+def convert_and_respect_annotation_metadata(
+ *,
+ object_: typing.Any,
+ annotation: typing.Any,
+ inner_type: typing.Optional[typing.Any] = None,
+ direction: typing.Literal["read", "write"],
+) -> typing.Any:
+ """
+ Respect the metadata annotations on a field, such as aliasing. This function effectively
+ manipulates the dict-form of an object to respect the metadata annotations. This is primarily used for
+ TypedDicts, which cannot support aliasing out of the box, and can be extended for additional
+ utilities, such as defaults.
+
+ Parameters
+ ----------
+ object_ : typing.Any
+
+ annotation : type
+ The type we're looking to apply typing annotations from
+
+ inner_type : typing.Optional[type]
+
+ Returns
+ -------
+ typing.Any
+ """
+
+ if object_ is None:
+ return None
+ if inner_type is None:
+ inner_type = annotation
+ # The only thing this function ever rewrites is keys that carry a FieldMetadata
+ # alias. If nothing in the (cached) type graph has such an alias, the conversion is
+ # a content-identity transform, so we can skip the entire recursive walk. This is
+ # the hot path for SSE streaming, where a large discriminated union would otherwise
+ # be traversed on every single event.
+ if not _requires_conversion(annotation):
+ return object_
+
+ clean_type = _remove_annotations(inner_type)
+ # Pydantic models
+ if (
+ inspect.isclass(clean_type)
+ and issubclass(clean_type, pydantic.BaseModel)
+ and isinstance(object_, typing.Mapping)
+ ):
+ return _convert_mapping(object_, clean_type, direction)
+ # TypedDicts
+ if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
+ return _convert_mapping(object_, clean_type, direction)
+
+ if (
+ typing_extensions.get_origin(clean_type) == typing.Dict
+ or typing_extensions.get_origin(clean_type) == dict
+ or clean_type == typing.Dict
+ ) and isinstance(object_, typing.Dict):
+ key_type = typing_extensions.get_args(clean_type)[0]
+ value_type = typing_extensions.get_args(clean_type)[1]
+
+ return {
+ key: convert_and_respect_annotation_metadata(
+ object_=value,
+ annotation=annotation,
+ inner_type=value_type,
+ direction=direction,
+ )
+ for key, value in object_.items()
+ }
+
+ # If you're iterating on a string, do not bother to coerce it to a sequence.
+ if not isinstance(object_, str):
+ if (
+ typing_extensions.get_origin(clean_type) == typing.Set
+ or typing_extensions.get_origin(clean_type) == set
+ or clean_type == typing.Set
+ ) and isinstance(object_, typing.Set):
+ inner_type = typing_extensions.get_args(clean_type)[0]
+ return {
+ convert_and_respect_annotation_metadata(
+ object_=item,
+ annotation=annotation,
+ inner_type=inner_type,
+ direction=direction,
+ )
+ for item in object_
+ }
+ elif (
+ (
+ typing_extensions.get_origin(clean_type) == typing.List
+ or typing_extensions.get_origin(clean_type) == list
+ or clean_type == typing.List
+ )
+ and isinstance(object_, typing.List)
+ ) or (
+ (
+ typing_extensions.get_origin(clean_type) == typing.Sequence
+ or typing_extensions.get_origin(clean_type) == collections.abc.Sequence
+ or clean_type == typing.Sequence
+ )
+ and isinstance(object_, typing.Sequence)
+ ):
+ inner_type = typing_extensions.get_args(clean_type)[0]
+ return [
+ convert_and_respect_annotation_metadata(
+ object_=item,
+ annotation=annotation,
+ inner_type=inner_type,
+ direction=direction,
+ )
+ for item in object_
+ ]
+
+ if typing_extensions.get_origin(clean_type) == typing.Union:
+ # We should be able to ~relatively~ safely try to convert keys against all
+ # member types in the union, the edge case here is if one member aliases a field
+ # of the same name to a different name from another member
+ # Or if another member aliases a field of the same name that another member does not.
+ for member in typing_extensions.get_args(clean_type):
+ object_ = convert_and_respect_annotation_metadata(
+ object_=object_,
+ annotation=annotation,
+ inner_type=member,
+ direction=direction,
+ )
+ return object_
+
+ annotated_type = _get_annotation(annotation)
+ if annotated_type is None:
+ return object_
+
+ # If the object is not a TypedDict, a Union, or other container (list, set, sequence, etc.)
+ # Then we can safely call it on the recursive conversion.
+ return object_
+
+
+def _convert_mapping(
+ object_: typing.Mapping[str, object],
+ expected_type: typing.Any,
+ direction: typing.Literal["read", "write"],
+) -> typing.Mapping[str, object]:
+ converted_object: typing.Dict[str, object] = {}
+ annotations = _get_cached_type_hints(expected_type)
+ aliases_to_field_names = _get_alias_to_field_name(annotations)
+ for key, value in object_.items():
+ if direction == "read" and key in aliases_to_field_names:
+ dealiased_key = aliases_to_field_names.get(key)
+ if dealiased_key is not None:
+ type_ = annotations.get(dealiased_key)
+ else:
+ type_ = annotations.get(key)
+ # Note you can't get the annotation by the field name if you're in read mode, so you must check the aliases map
+ #
+ # So this is effectively saying if we're in write mode, and we don't have a type, or if we're in read mode and we don't have an alias
+ # then we can just pass the value through as is
+ if type_ is None:
+ converted_object[key] = value
+ elif direction == "read" and key not in aliases_to_field_names:
+ converted_object[key] = convert_and_respect_annotation_metadata(
+ object_=value, annotation=type_, direction=direction
+ )
+ else:
+ converted_object[_alias_key(key, type_, direction, aliases_to_field_names)] = (
+ convert_and_respect_annotation_metadata(object_=value, annotation=type_, direction=direction)
+ )
+ return converted_object
+
+
+def _get_annotation(type_: typing.Any) -> typing.Optional[typing.Any]:
+ maybe_annotated_type = typing_extensions.get_origin(type_)
+ if maybe_annotated_type is None:
+ return None
+
+ if maybe_annotated_type == typing_extensions.NotRequired:
+ type_ = typing_extensions.get_args(type_)[0]
+ maybe_annotated_type = typing_extensions.get_origin(type_)
+
+ if maybe_annotated_type == typing_extensions.Annotated:
+ return type_
+
+ return None
+
+
+def _remove_annotations(type_: typing.Any) -> typing.Any:
+ maybe_annotated_type = typing_extensions.get_origin(type_)
+ if maybe_annotated_type is None:
+ return type_
+
+ if maybe_annotated_type == typing_extensions.NotRequired:
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
+
+ if maybe_annotated_type == typing_extensions.Annotated:
+ return _remove_annotations(typing_extensions.get_args(type_)[0])
+
+ return type_
+
+
+def get_alias_to_field_mapping(type_: typing.Any) -> typing.Dict[str, str]:
+ annotations = _get_cached_type_hints(type_)
+ return _get_alias_to_field_name(annotations)
+
+
+def get_field_to_alias_mapping(type_: typing.Any) -> typing.Dict[str, str]:
+ annotations = _get_cached_type_hints(type_)
+ return _get_field_to_alias_name(annotations)
+
+
+def _get_alias_to_field_name(
+ field_to_hint: typing.Dict[str, typing.Any],
+) -> typing.Dict[str, str]:
+ aliases = {}
+ for field, hint in field_to_hint.items():
+ maybe_alias = _get_alias_from_type(hint)
+ if maybe_alias is not None:
+ aliases[maybe_alias] = field
+ return aliases
+
+
+def _get_field_to_alias_name(
+ field_to_hint: typing.Dict[str, typing.Any],
+) -> typing.Dict[str, str]:
+ aliases = {}
+ for field, hint in field_to_hint.items():
+ maybe_alias = _get_alias_from_type(hint)
+ if maybe_alias is not None:
+ aliases[field] = maybe_alias
+ return aliases
+
+
+def _get_alias_from_type(type_: typing.Any) -> typing.Optional[str]:
+ maybe_annotated_type = _get_annotation(type_)
+
+ if maybe_annotated_type is not None:
+ # The actual annotations are 1 onward, the first is the annotated type
+ annotations = typing_extensions.get_args(maybe_annotated_type)[1:]
+
+ for annotation in annotations:
+ if isinstance(annotation, FieldMetadata) and annotation.alias is not None:
+ return annotation.alias
+ return None
+
+
+def _alias_key(
+ key: str,
+ type_: typing.Any,
+ direction: typing.Literal["read", "write"],
+ aliases_to_field_names: typing.Dict[str, str],
+) -> str:
+ if direction == "read":
+ return aliases_to_field_names.get(key, key)
+ return _get_alias_from_type(type_=type_) or key
diff --git a/sdks/python/discovery/__init__.py b/sdks/python/discovery/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/discovery/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/discovery/client.py b/sdks/python/discovery/client.py
new file mode 100644
index 0000000000..ed515d9857
--- /dev/null
+++ b/sdks/python/discovery/client.py
@@ -0,0 +1,134 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.auth_discovery_response import AuthDiscoveryResponse
+from .raw_client import AsyncRawDiscoveryClient, RawDiscoveryClient
+
+
+class DiscoveryClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawDiscoveryClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawDiscoveryClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawDiscoveryClient
+ """
+ return self._raw_client
+
+ def get_auth_discovery(self, *, request_options: typing.Optional[RequestOptions] = None) -> AuthDiscoveryResponse:
+ """
+ Return authentication configuration for CLI/SDK discovery.
+
+ This endpoint is unauthenticated and returns the information clients
+ need to authenticate with this NeMo Platform deployment.
+
+ **Response fields:**
+
+ - `auth_enabled`: Whether authentication is enabled on this cluster
+ - `oidc`: OIDC configuration (only present when OIDC is enabled)
+ - `issuer`: The OIDC issuer URL
+ - `authorization_endpoint`: Authorization endpoint for browser-based flows
+ - `token_endpoint`: Token exchange endpoint
+ - `device_authorization_endpoint`: Device flow authorization endpoint (for CLI)
+ - `userinfo_endpoint`: UserInfo endpoint
+ - `client_id`: OAuth client ID to use
+ - `default_scopes`: OAuth scopes to request during authentication
+ - `scope_prefix`: Prefix to prepend to custom scopes (those with ':' or '.default')
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AuthDiscoveryResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.discovery.get_auth_discovery()
+ """
+ _response = self._raw_client.get_auth_discovery(request_options=request_options)
+ return _response.data
+
+
+class AsyncDiscoveryClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawDiscoveryClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawDiscoveryClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawDiscoveryClient
+ """
+ return self._raw_client
+
+ async def get_auth_discovery(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AuthDiscoveryResponse:
+ """
+ Return authentication configuration for CLI/SDK discovery.
+
+ This endpoint is unauthenticated and returns the information clients
+ need to authenticate with this NeMo Platform deployment.
+
+ **Response fields:**
+
+ - `auth_enabled`: Whether authentication is enabled on this cluster
+ - `oidc`: OIDC configuration (only present when OIDC is enabled)
+ - `issuer`: The OIDC issuer URL
+ - `authorization_endpoint`: Authorization endpoint for browser-based flows
+ - `token_endpoint`: Token exchange endpoint
+ - `device_authorization_endpoint`: Device flow authorization endpoint (for CLI)
+ - `userinfo_endpoint`: UserInfo endpoint
+ - `client_id`: OAuth client ID to use
+ - `default_scopes`: OAuth scopes to request during authentication
+ - `scope_prefix`: Prefix to prepend to custom scopes (those with ':' or '.default')
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AuthDiscoveryResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.discovery.get_auth_discovery()
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_auth_discovery(request_options=request_options)
+ return _response.data
diff --git a/sdks/python/discovery/raw_client.py b/sdks/python/discovery/raw_client.py
new file mode 100644
index 0000000000..244863f8e0
--- /dev/null
+++ b/sdks/python/discovery/raw_client.py
@@ -0,0 +1,135 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..types.auth_discovery_response import AuthDiscoveryResponse
+from pydantic import ValidationError
+
+
+class RawDiscoveryClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def get_auth_discovery(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[AuthDiscoveryResponse]:
+ """
+ Return authentication configuration for CLI/SDK discovery.
+
+ This endpoint is unauthenticated and returns the information clients
+ need to authenticate with this NeMo Platform deployment.
+
+ **Response fields:**
+
+ - `auth_enabled`: Whether authentication is enabled on this cluster
+ - `oidc`: OIDC configuration (only present when OIDC is enabled)
+ - `issuer`: The OIDC issuer URL
+ - `authorization_endpoint`: Authorization endpoint for browser-based flows
+ - `token_endpoint`: Token exchange endpoint
+ - `device_authorization_endpoint`: Device flow authorization endpoint (for CLI)
+ - `userinfo_endpoint`: UserInfo endpoint
+ - `client_id`: OAuth client ID to use
+ - `default_scopes`: OAuth scopes to request during authentication
+ - `scope_prefix`: Prefix to prepend to custom scopes (those with ':' or '.default')
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[AuthDiscoveryResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/auth/discovery",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AuthDiscoveryResponse,
+ parse_obj_as(
+ type_=AuthDiscoveryResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawDiscoveryClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def get_auth_discovery(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[AuthDiscoveryResponse]:
+ """
+ Return authentication configuration for CLI/SDK discovery.
+
+ This endpoint is unauthenticated and returns the information clients
+ need to authenticate with this NeMo Platform deployment.
+
+ **Response fields:**
+
+ - `auth_enabled`: Whether authentication is enabled on this cluster
+ - `oidc`: OIDC configuration (only present when OIDC is enabled)
+ - `issuer`: The OIDC issuer URL
+ - `authorization_endpoint`: Authorization endpoint for browser-based flows
+ - `token_endpoint`: Token exchange endpoint
+ - `device_authorization_endpoint`: Device flow authorization endpoint (for CLI)
+ - `userinfo_endpoint`: UserInfo endpoint
+ - `client_id`: OAuth client ID to use
+ - `default_scopes`: OAuth scopes to request during authentication
+ - `scope_prefix`: Prefix to prepend to custom scopes (those with ':' or '.default')
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[AuthDiscoveryResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/auth/discovery",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ AuthDiscoveryResponse,
+ parse_obj_as(
+ type_=AuthDiscoveryResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/entity_store/__init__.py b/sdks/python/entity_store/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/entity_store/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/entity_store/client.py b/sdks/python/entity_store/client.py
new file mode 100644
index 0000000000..030e30c73d
--- /dev/null
+++ b/sdks/python/entity_store/client.py
@@ -0,0 +1,2457 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.delete_response import DeleteResponse
+from ..types.entities_page import EntitiesPage
+from ..types.entity import Entity
+from ..types.generic_sort_field import GenericSortField
+from ..types.project import Project
+from ..types.project_sort_field import ProjectSortField
+from ..types.projects_page import ProjectsPage
+from ..types.workspace import Workspace
+from ..types.workspace_member import WorkspaceMember
+from ..types.workspace_member_list_response import WorkspaceMemberListResponse
+from ..types.workspaces_page import WorkspacesPage
+from .raw_client import AsyncRawEntityStoreClient, RawEntityStoreClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class EntityStoreClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawEntityStoreClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawEntityStoreClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawEntityStoreClient
+ """
+ return self._raw_client
+
+ def get_entity_by_id(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Entity:
+ """
+ Get a specific entity by its unique identifier.
+ This endpoint is primarily for debugging and internal use.
+
+ Example:
+ ```
+ GET /apis/entities/v2/entities/customization-config-5Q2LoF8z8M9JZxZsHwJKNn
+ ```
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.get_entity_by_id(
+ id="id",
+ )
+ """
+ _response = self._raw_client.get_entity_by_id(id, request_options=request_options)
+ return _response.data
+
+ def list_workspaces(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspacesPage:
+ """
+ List all workspaces with pagination.
+
+ When authentication is enabled, only workspaces the principal has access to
+ are returned. Service principals and platform admins have access to all workspaces.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[GenericSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspacesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.list_workspaces()
+ """
+ _response = self._raw_client.list_workspaces(
+ page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_workspace(
+ self,
+ *,
+ name: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Workspace:
+ """
+ Create a new workspace.
+
+ The creator is automatically granted Admin role on the workspace.
+ By default, this endpoint waits for the Admin role to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces
+ {
+ "name": "ml-team",
+ "description": "Machine Learning Team workspace"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+ Workspace name (unique identifier). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for Admin role to propagate before returning (default: true). Set to false for bulk operations.
+
+ description : typing.Optional[str]
+ Optional description of the workspace
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.create_workspace(
+ name="ml-team",
+ )
+ """
+ _response = self._raw_client.create_workspace(
+ name=name,
+ wait_role_propagation=wait_role_propagation,
+ description=description,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_workspace(self, name: str, *, request_options: typing.Optional[RequestOptions] = None) -> Workspace:
+ """
+ Get a specific workspace by ID.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.get_workspace(
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_workspace(name, request_options=request_options)
+ return _response.data
+
+ def update_workspace(
+ self,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Workspace:
+ """
+ Update a workspace's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team
+ {
+ "description": "Updated description for ML Team"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.update_workspace(
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_workspace(name, description=description, request_options=request_options)
+ return _response.data
+
+ def delete_workspace(self, name: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeleteResponse:
+ """
+ Delete a workspace.
+
+ This marks the workspace for deletion and returns immediately. The workspace
+ will no longer be accessible via the API. An asynchronous cleanup controller
+ will handle deletion of all entities and external resources.
+
+ Role bindings are immediately deleted to revoke access.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.delete_workspace(
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_workspace(name, request_options=request_options)
+ return _response.data
+
+ def list_entities(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EntitiesPage:
+ """
+ List all entities of a specific type in the given workspace.
+
+ Use workspace="-" to list entities across all workspaces the principal has
+ access to.
+
+ Query Parameters:
+ - sort: Sort field
+ - page, page_size: Pagination
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Examples:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config?sort=-created_at
+ GET /apis/entities/v2/workspaces/-/entities/customization_config # Cross-workspace query
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[str]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EntitiesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.list_entities(
+ workspace="workspace",
+ entity_type="entity_type",
+ sort="-created_at",
+ )
+ """
+ _response = self._raw_client.list_entities(
+ workspace,
+ entity_type,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def create_entity(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ name: typing.Optional[str] = OMIT,
+ parent: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Create a new entity of the specified type in the given workspace.
+
+ If name is not provided, it will be auto-generated based on the entity type.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/entities/customization_config
+ {
+ "name": "my-config",
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.01}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ data : typing.Dict[str, typing.Any]
+ Entity-specific data (schema is opaque to entity store, validated by client SDK)
+
+ name : typing.Optional[str]
+ Entity name (optional - auto-generated if not provided). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.create_entity(
+ workspace="workspace",
+ entity_type="entity_type",
+ data={"key": "value"},
+ )
+ """
+ _response = self._raw_client.create_entity(
+ workspace,
+ entity_type,
+ data=data,
+ name=name,
+ parent=parent,
+ project=project,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Get a specific entity by its workspace, type, and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.get_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_entity_by_name(
+ workspace, entity_type, name, parent=parent, request_options=request_options
+ )
+ return _response.data
+
+ def update_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ parent: typing.Optional[str] = None,
+ new_name: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ expected_db_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Update an entity by its name. Optionally change the entity's name.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ {
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.02}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ data : typing.Dict[str, typing.Any]
+ Updated entity-specific data
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ new_name : typing.Optional[str]
+ Updated entity name (optional). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ expected_db_version : typing.Optional[int]
+ Optional database version for optimistic locking. Update only succeeds if current version matches.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.update_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ data={"key": "value"},
+ )
+ """
+ _response = self._raw_client.update_entity_by_name(
+ workspace,
+ entity_type,
+ name,
+ data=data,
+ parent=parent,
+ new_name=new_name,
+ project=project,
+ expected_db_version=expected_db_version,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def delete_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Delete an entity by its name.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.delete_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_entity_by_name(
+ workspace, entity_type, name, parent=parent, request_options=request_options
+ )
+ return _response.data
+
+ def list_workspace_members(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> WorkspaceMemberListResponse:
+ """
+ List all members of a workspace with their roles.
+
+ Returns a list of all principals with active role bindings in the workspace.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team/members
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMemberListResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.list_workspace_members(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_workspace_members(workspace, request_options=request_options)
+ return _response.data
+
+ def add_workspace_member(
+ self,
+ workspace: str,
+ *,
+ principal: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ roles: typing.Optional[typing.Sequence[str]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspaceMember:
+ """
+ Add a new member to the workspace with specified roles.
+
+ This creates role bindings for the specified principal with the given roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/ml-team/members
+ {
+ "principal": "user@example.com",
+ "roles": ["Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ roles : typing.Optional[typing.Sequence[str]]
+ List of roles to grant to the principal
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMember
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.add_workspace_member(
+ workspace="workspace",
+ principal="user@example.com",
+ )
+ """
+ _response = self._raw_client.add_workspace_member(
+ workspace,
+ principal=principal,
+ wait_role_propagation=wait_role_propagation,
+ roles=roles,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def update_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ roles: typing.Sequence[str],
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspaceMember:
+ """
+ Update the roles for a workspace member.
+
+ This will revoke existing roles not in the new list and add new roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ {
+ "roles": ["Viewer", "Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ roles : typing.Sequence[str]
+ Updated list of roles for the principal
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMember
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.update_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+ roles=["Viewer"],
+ )
+ """
+ _response = self._raw_client.update_workspace_member(
+ workspace,
+ principal_id,
+ roles=roles,
+ wait_role_propagation=wait_role_propagation,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def remove_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Remove a member from the workspace by revoking all their roles.
+
+ This revokes all active role bindings for the principal in the workspace.
+ By default, this endpoint waits for all roles to be revoked before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.remove_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+ )
+ """
+ _response = self._raw_client.remove_workspace_member(
+ workspace, principal_id, wait_role_propagation=wait_role_propagation, request_options=request_options
+ )
+ return _response.data
+
+ def list_projects(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ProjectSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ProjectsPage:
+ """
+ List all projects in a workspace with pagination.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[ProjectSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.list_projects(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_projects(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_project(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Project:
+ """
+ Create a new project in the given workspace.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/projects
+ {
+ "name": "ml-project",
+ "description": "Machine Learning project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Project name (unique within workspace). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ description : typing.Optional[str]
+ Optional description of the project
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.create_project(
+ workspace="workspace",
+ name="ml-project",
+ )
+ """
+ _response = self._raw_client.create_project(
+ workspace, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ def get_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Project:
+ """
+ Get a specific project by its workspace and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.get_project(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_project(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_project(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Project:
+ """
+ Update a project's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/projects/ml-project
+ {
+ "description": "Updated description for ML project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.update_project(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_project(
+ workspace, name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ def delete_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteResponse:
+ """
+ Delete a project.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.entity_store.delete_project(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_project(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncEntityStoreClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawEntityStoreClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawEntityStoreClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawEntityStoreClient
+ """
+ return self._raw_client
+
+ async def get_entity_by_id(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Entity:
+ """
+ Get a specific entity by its unique identifier.
+ This endpoint is primarily for debugging and internal use.
+
+ Example:
+ ```
+ GET /apis/entities/v2/entities/customization-config-5Q2LoF8z8M9JZxZsHwJKNn
+ ```
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.get_entity_by_id(
+ id="id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_entity_by_id(id, request_options=request_options)
+ return _response.data
+
+ async def list_workspaces(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspacesPage:
+ """
+ List all workspaces with pagination.
+
+ When authentication is enabled, only workspaces the principal has access to
+ are returned. Service principals and platform admins have access to all workspaces.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[GenericSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspacesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.list_workspaces()
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_workspaces(
+ page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_workspace(
+ self,
+ *,
+ name: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Workspace:
+ """
+ Create a new workspace.
+
+ The creator is automatically granted Admin role on the workspace.
+ By default, this endpoint waits for the Admin role to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces
+ {
+ "name": "ml-team",
+ "description": "Machine Learning Team workspace"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+ Workspace name (unique identifier). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for Admin role to propagate before returning (default: true). Set to false for bulk operations.
+
+ description : typing.Optional[str]
+ Optional description of the workspace
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.create_workspace(
+ name="ml-team",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_workspace(
+ name=name,
+ wait_role_propagation=wait_role_propagation,
+ description=description,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_workspace(self, name: str, *, request_options: typing.Optional[RequestOptions] = None) -> Workspace:
+ """
+ Get a specific workspace by ID.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.get_workspace(
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_workspace(name, request_options=request_options)
+ return _response.data
+
+ async def update_workspace(
+ self,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Workspace:
+ """
+ Update a workspace's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team
+ {
+ "description": "Updated description for ML Team"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Workspace
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.update_workspace(
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_workspace(
+ name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_workspace(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteResponse:
+ """
+ Delete a workspace.
+
+ This marks the workspace for deletion and returns immediately. The workspace
+ will no longer be accessible via the API. An asynchronous cleanup controller
+ will handle deletion of all entities and external resources.
+
+ Role bindings are immediately deleted to revoke access.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.delete_workspace(
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_workspace(name, request_options=request_options)
+ return _response.data
+
+ async def list_entities(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EntitiesPage:
+ """
+ List all entities of a specific type in the given workspace.
+
+ Use workspace="-" to list entities across all workspaces the principal has
+ access to.
+
+ Query Parameters:
+ - sort: Sort field
+ - page, page_size: Pagination
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Examples:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config?sort=-created_at
+ GET /apis/entities/v2/workspaces/-/entities/customization_config # Cross-workspace query
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[str]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EntitiesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.list_entities(
+ workspace="workspace",
+ entity_type="entity_type",
+ sort="-created_at",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_entities(
+ workspace,
+ entity_type,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def create_entity(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ name: typing.Optional[str] = OMIT,
+ parent: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Create a new entity of the specified type in the given workspace.
+
+ If name is not provided, it will be auto-generated based on the entity type.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/entities/customization_config
+ {
+ "name": "my-config",
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.01}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ data : typing.Dict[str, typing.Any]
+ Entity-specific data (schema is opaque to entity store, validated by client SDK)
+
+ name : typing.Optional[str]
+ Entity name (optional - auto-generated if not provided). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.create_entity(
+ workspace="workspace",
+ entity_type="entity_type",
+ data={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_entity(
+ workspace,
+ entity_type,
+ data=data,
+ name=name,
+ parent=parent,
+ project=project,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Get a specific entity by its workspace, type, and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.get_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_entity_by_name(
+ workspace, entity_type, name, parent=parent, request_options=request_options
+ )
+ return _response.data
+
+ async def update_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ parent: typing.Optional[str] = None,
+ new_name: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ expected_db_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Entity:
+ """
+ Update an entity by its name. Optionally change the entity's name.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ {
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.02}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ data : typing.Dict[str, typing.Any]
+ Updated entity-specific data
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ new_name : typing.Optional[str]
+ Updated entity name (optional). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ expected_db_version : typing.Optional[int]
+ Optional database version for optimistic locking. Update only succeeds if current version matches.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Entity
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.update_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ data={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_entity_by_name(
+ workspace,
+ entity_type,
+ name,
+ data=data,
+ parent=parent,
+ new_name=new_name,
+ project=project,
+ expected_db_version=expected_db_version,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def delete_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Delete an entity by its name.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.delete_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_entity_by_name(
+ workspace, entity_type, name, parent=parent, request_options=request_options
+ )
+ return _response.data
+
+ async def list_workspace_members(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> WorkspaceMemberListResponse:
+ """
+ List all members of a workspace with their roles.
+
+ Returns a list of all principals with active role bindings in the workspace.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team/members
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMemberListResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.list_workspace_members(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_workspace_members(workspace, request_options=request_options)
+ return _response.data
+
+ async def add_workspace_member(
+ self,
+ workspace: str,
+ *,
+ principal: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ roles: typing.Optional[typing.Sequence[str]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspaceMember:
+ """
+ Add a new member to the workspace with specified roles.
+
+ This creates role bindings for the specified principal with the given roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/ml-team/members
+ {
+ "principal": "user@example.com",
+ "roles": ["Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ roles : typing.Optional[typing.Sequence[str]]
+ List of roles to grant to the principal
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMember
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.add_workspace_member(
+ workspace="workspace",
+ principal="user@example.com",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.add_workspace_member(
+ workspace,
+ principal=principal,
+ wait_role_propagation=wait_role_propagation,
+ roles=roles,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def update_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ roles: typing.Sequence[str],
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> WorkspaceMember:
+ """
+ Update the roles for a workspace member.
+
+ This will revoke existing roles not in the new list and add new roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ {
+ "roles": ["Viewer", "Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ roles : typing.Sequence[str]
+ Updated list of roles for the principal
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ WorkspaceMember
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.update_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+ roles=["Viewer"],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_workspace_member(
+ workspace,
+ principal_id,
+ roles=roles,
+ wait_role_propagation=wait_role_propagation,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def remove_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Remove a member from the workspace by revoking all their roles.
+
+ This revokes all active role bindings for the principal in the workspace.
+ By default, this endpoint waits for all roles to be revoked before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.remove_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.remove_workspace_member(
+ workspace, principal_id, wait_role_propagation=wait_role_propagation, request_options=request_options
+ )
+ return _response.data
+
+ async def list_projects(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ProjectSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ProjectsPage:
+ """
+ List all projects in a workspace with pagination.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[ProjectSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.list_projects(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_projects(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_project(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Project:
+ """
+ Create a new project in the given workspace.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/projects
+ {
+ "name": "ml-project",
+ "description": "Machine Learning project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Project name (unique within workspace). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ description : typing.Optional[str]
+ Optional description of the project
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.create_project(
+ workspace="workspace",
+ name="ml-project",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_project(
+ workspace, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def get_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Project:
+ """
+ Get a specific project by its workspace and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.get_project(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_project(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_project(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Project:
+ """
+ Update a project's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/projects/ml-project
+ {
+ "description": "Updated description for ML project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Project
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.update_project(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_project(
+ workspace, name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteResponse:
+ """
+ Delete a project.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.entity_store.delete_project(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_project(workspace, name, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/entity_store/raw_client.py b/sdks/python/entity_store/raw_client.py
new file mode 100644
index 0000000000..6d37a1277e
--- /dev/null
+++ b/sdks/python/entity_store/raw_client.py
@@ -0,0 +1,3190 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.delete_response import DeleteResponse
+from ..types.entities_page import EntitiesPage
+from ..types.entity import Entity
+from ..types.generic_sort_field import GenericSortField
+from ..types.project import Project
+from ..types.project_sort_field import ProjectSortField
+from ..types.projects_page import ProjectsPage
+from ..types.workspace import Workspace
+from ..types.workspace_member import WorkspaceMember
+from ..types.workspace_member_list_response import WorkspaceMemberListResponse
+from ..types.workspaces_page import WorkspacesPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawEntityStoreClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def get_entity_by_id(
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Entity]:
+ """
+ Get a specific entity by its unique identifier.
+ This endpoint is primarily for debugging and internal use.
+
+ Example:
+ ```
+ GET /apis/entities/v2/entities/customization-config-5Q2LoF8z8M9JZxZsHwJKNn
+ ```
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Entity]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/entities/{encode_path_param(id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_workspaces(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[WorkspacesPage]:
+ """
+ List all workspaces with pagination.
+
+ When authentication is enabled, only workspaces the principal has access to
+ are returned. Service principals and platform admins have access to all workspaces.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[GenericSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[WorkspacesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/entities/v2/workspaces",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspacesPage,
+ parse_obj_as(
+ type_=WorkspacesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_workspace(
+ self,
+ *,
+ name: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Workspace]:
+ """
+ Create a new workspace.
+
+ The creator is automatically granted Admin role on the workspace.
+ By default, this endpoint waits for the Admin role to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces
+ {
+ "name": "ml-team",
+ "description": "Machine Learning Team workspace"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+ Workspace name (unique identifier). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for Admin role to propagate before returning (default: true). Set to false for bulk operations.
+
+ description : typing.Optional[str]
+ Optional description of the workspace
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Workspace]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/entities/v2/workspaces",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_workspace(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Workspace]:
+ """
+ Get a specific workspace by ID.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Workspace]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_workspace(
+ self,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Workspace]:
+ """
+ Update a workspace's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team
+ {
+ "description": "Updated description for ML Team"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Workspace]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_workspace(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Delete a workspace.
+
+ This marks the workspace for deletion and returns immediately. The workspace
+ will no longer be accessible via the API. An asynchronous cleanup controller
+ will handle deletion of all entities and external resources.
+
+ Role bindings are immediately deleted to revoke access.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_entities(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[EntitiesPage]:
+ """
+ List all entities of a specific type in the given workspace.
+
+ Use workspace="-" to list entities across all workspaces the principal has
+ access to.
+
+ Query Parameters:
+ - sort: Sort field
+ - page, page_size: Pagination
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Examples:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config?sort=-created_at
+ GET /apis/entities/v2/workspaces/-/entities/customization_config # Cross-workspace query
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[str]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[EntitiesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EntitiesPage,
+ parse_obj_as(
+ type_=EntitiesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_entity(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ name: typing.Optional[str] = OMIT,
+ parent: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Entity]:
+ """
+ Create a new entity of the specified type in the given workspace.
+
+ If name is not provided, it will be auto-generated based on the entity type.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/entities/customization_config
+ {
+ "name": "my-config",
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.01}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ data : typing.Dict[str, typing.Any]
+ Entity-specific data (schema is opaque to entity store, validated by client SDK)
+
+ name : typing.Optional[str]
+ Entity name (optional - auto-generated if not provided). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Entity]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}",
+ method="POST",
+ json={
+ "name": name,
+ "parent": parent,
+ "project": project,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Entity]:
+ """
+ Get a specific entity by its workspace, type, and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Entity]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="GET",
+ params={
+ "parent": parent,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ parent: typing.Optional[str] = None,
+ new_name: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ expected_db_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Entity]:
+ """
+ Update an entity by its name. Optionally change the entity's name.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ {
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.02}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ data : typing.Dict[str, typing.Any]
+ Updated entity-specific data
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ new_name : typing.Optional[str]
+ Updated entity name (optional). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ expected_db_version : typing.Optional[int]
+ Optional database version for optimistic locking. Update only succeeds if current version matches.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Entity]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="PUT",
+ params={
+ "parent": parent,
+ },
+ json={
+ "new_name": new_name,
+ "project": project,
+ "data": data,
+ "expected_db_version": expected_db_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Delete an entity by its name.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="DELETE",
+ params={
+ "parent": parent,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_workspace_members(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[WorkspaceMemberListResponse]:
+ """
+ List all members of a workspace with their roles.
+
+ Returns a list of all principals with active role bindings in the workspace.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team/members
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[WorkspaceMemberListResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMemberListResponse,
+ parse_obj_as(
+ type_=WorkspaceMemberListResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def add_workspace_member(
+ self,
+ workspace: str,
+ *,
+ principal: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ roles: typing.Optional[typing.Sequence[str]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[WorkspaceMember]:
+ """
+ Add a new member to the workspace with specified roles.
+
+ This creates role bindings for the specified principal with the given roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/ml-team/members
+ {
+ "principal": "user@example.com",
+ "roles": ["Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ roles : typing.Optional[typing.Sequence[str]]
+ List of roles to grant to the principal
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[WorkspaceMember]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "principal": principal,
+ "roles": roles,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMember,
+ parse_obj_as(
+ type_=WorkspaceMember, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ roles: typing.Sequence[str],
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[WorkspaceMember]:
+ """
+ Update the roles for a workspace member.
+
+ This will revoke existing roles not in the new list and add new roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ {
+ "roles": ["Viewer", "Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ roles : typing.Sequence[str]
+ Updated list of roles for the principal
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[WorkspaceMember]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members/{encode_path_param(principal_id)}",
+ method="PUT",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "roles": roles,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMember,
+ parse_obj_as(
+ type_=WorkspaceMember, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def remove_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Remove a member from the workspace by revoking all their roles.
+
+ This revokes all active role bindings for the principal in the workspace.
+ By default, this endpoint waits for all roles to be revoked before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members/{encode_path_param(principal_id)}",
+ method="DELETE",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_projects(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ProjectSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ProjectsPage]:
+ """
+ List all projects in a workspace with pagination.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[ProjectSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ProjectsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ProjectsPage,
+ parse_obj_as(
+ type_=ProjectsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_project(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Project]:
+ """
+ Create a new project in the given workspace.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/projects
+ {
+ "name": "ml-project",
+ "description": "Machine Learning project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Project name (unique within workspace). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ description : typing.Optional[str]
+ Optional description of the project
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Project]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Project]:
+ """
+ Get a specific project by its workspace and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Project]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_project(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Project]:
+ """
+ Update a project's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/projects/ml-project
+ {
+ "description": "Updated description for ML project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Project]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Delete a project.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawEntityStoreClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def get_entity_by_id(
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Entity]:
+ """
+ Get a specific entity by its unique identifier.
+ This endpoint is primarily for debugging and internal use.
+
+ Example:
+ ```
+ GET /apis/entities/v2/entities/customization-config-5Q2LoF8z8M9JZxZsHwJKNn
+ ```
+
+ Parameters
+ ----------
+ id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Entity]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/entities/{encode_path_param(id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_workspaces(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[WorkspacesPage]:
+ """
+ List all workspaces with pagination.
+
+ When authentication is enabled, only workspaces the principal has access to
+ are returned. Service principals and platform admins have access to all workspaces.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[GenericSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[WorkspacesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/entities/v2/workspaces",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspacesPage,
+ parse_obj_as(
+ type_=WorkspacesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_workspace(
+ self,
+ *,
+ name: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Workspace]:
+ """
+ Create a new workspace.
+
+ The creator is automatically granted Admin role on the workspace.
+ By default, this endpoint waits for the Admin role to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces
+ {
+ "name": "ml-team",
+ "description": "Machine Learning Team workspace"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+ Workspace name (unique identifier). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for Admin role to propagate before returning (default: true). Set to false for bulk operations.
+
+ description : typing.Optional[str]
+ Optional description of the workspace
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Workspace]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/entities/v2/workspaces",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_workspace(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Workspace]:
+ """
+ Get a specific workspace by ID.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Workspace]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_workspace(
+ self,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Workspace]:
+ """
+ Update a workspace's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team
+ {
+ "description": "Updated description for ML Team"
+ }
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Workspace]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Workspace,
+ parse_obj_as(
+ type_=Workspace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_workspace(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Delete a workspace.
+
+ This marks the workspace for deletion and returns immediately. The workspace
+ will no longer be accessible via the API. An asynchronous cleanup controller
+ will handle deletion of all entities and external resources.
+
+ Role bindings are immediately deleted to revoke access.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team
+ ```
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_entities(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[EntitiesPage]:
+ """
+ List all entities of a specific type in the given workspace.
+
+ Use workspace="-" to list entities across all workspaces the principal has
+ access to.
+
+ Query Parameters:
+ - sort: Sort field
+ - page, page_size: Pagination
+ - filter: Advanced filters (JSON, text, or bracket notation)
+
+ Examples:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config?sort=-created_at
+ GET /apis/entities/v2/workspaces/-/entities/customization_config # Cross-workspace query
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[str]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[EntitiesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EntitiesPage,
+ parse_obj_as(
+ type_=EntitiesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_entity(
+ self,
+ workspace: str,
+ entity_type: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ name: typing.Optional[str] = OMIT,
+ parent: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Entity]:
+ """
+ Create a new entity of the specified type in the given workspace.
+
+ If name is not provided, it will be auto-generated based on the entity type.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/entities/customization_config
+ {
+ "name": "my-config",
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.01}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ data : typing.Dict[str, typing.Any]
+ Entity-specific data (schema is opaque to entity store, validated by client SDK)
+
+ name : typing.Optional[str]
+ Entity name (optional - auto-generated if not provided). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Entity]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}",
+ method="POST",
+ json={
+ "name": name,
+ "parent": parent,
+ "project": project,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Entity]:
+ """
+ Get a specific entity by its workspace, type, and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Entity]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="GET",
+ params={
+ "parent": parent,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ data: typing.Dict[str, typing.Any],
+ parent: typing.Optional[str] = None,
+ new_name: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ expected_db_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Entity]:
+ """
+ Update an entity by its name. Optionally change the entity's name.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ {
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.02}
+ }
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ data : typing.Dict[str, typing.Any]
+ Updated entity-specific data
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ new_name : typing.Optional[str]
+ Updated entity name (optional). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ project : typing.Optional[str]
+ The name of the project associated with this entity
+
+ expected_db_version : typing.Optional[int]
+ Optional database version for optimistic locking. Update only succeeds if current version matches.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Entity]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="PUT",
+ params={
+ "parent": parent,
+ },
+ json={
+ "new_name": new_name,
+ "project": project,
+ "data": data,
+ "expected_db_version": expected_db_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Entity,
+ parse_obj_as(
+ type_=Entity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_entity_by_name(
+ self,
+ workspace: str,
+ entity_type: str,
+ name: str,
+ *,
+ parent: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Delete an entity by its name.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ entity_type : str
+
+ name : str
+
+ parent : typing.Optional[str]
+ Parent entity ID for nested entities
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/entities/{encode_path_param(entity_type)}/{encode_path_param(name)}",
+ method="DELETE",
+ params={
+ "parent": parent,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_workspace_members(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[WorkspaceMemberListResponse]:
+ """
+ List all members of a workspace with their roles.
+
+ Returns a list of all principals with active role bindings in the workspace.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/ml-team/members
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[WorkspaceMemberListResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMemberListResponse,
+ parse_obj_as(
+ type_=WorkspaceMemberListResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def add_workspace_member(
+ self,
+ workspace: str,
+ *,
+ principal: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ roles: typing.Optional[typing.Sequence[str]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[WorkspaceMember]:
+ """
+ Add a new member to the workspace with specified roles.
+
+ This creates role bindings for the specified principal with the given roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/ml-team/members
+ {
+ "principal": "user@example.com",
+ "roles": ["Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ roles : typing.Optional[typing.Sequence[str]]
+ List of roles to grant to the principal
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[WorkspaceMember]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "principal": principal,
+ "roles": roles,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMember,
+ parse_obj_as(
+ type_=WorkspaceMember, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ roles: typing.Sequence[str],
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[WorkspaceMember]:
+ """
+ Update the roles for a workspace member.
+
+ This will revoke existing roles not in the new list and add new roles.
+ By default, this endpoint waits for the roles to propagate before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ {
+ "roles": ["Viewer", "Editor"]
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ roles : typing.Sequence[str]
+ Updated list of roles for the principal
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[WorkspaceMember]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members/{encode_path_param(principal_id)}",
+ method="PUT",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "roles": roles,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ WorkspaceMember,
+ parse_obj_as(
+ type_=WorkspaceMember, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def remove_workspace_member(
+ self,
+ workspace: str,
+ principal_id: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Remove a member from the workspace by revoking all their roles.
+
+ This revokes all active role bindings for the principal in the workspace.
+ By default, this endpoint waits for all roles to be revoked before returning.
+ Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/ml-team/members/user@example.com
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ principal_id : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/members/{encode_path_param(principal_id)}",
+ method="DELETE",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_projects(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ProjectSortField] = None,
+ filter: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ProjectsPage]:
+ """
+ List all projects in a workspace with pagination.
+
+ Query Parameters:
+ - page, page_size: Pagination
+ - sort: Sort field
+ - filter: Advanced filters
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects?sort=-created_at&page=1&page_size=10
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number
+
+ page_size : typing.Optional[int]
+ Items per page
+
+ sort : typing.Optional[ProjectSortField]
+ Sort field
+
+ filter : typing.Optional[str]
+ Query filter expression. Supports text and JSON syntaxes:
+ - Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+ - Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+ - Bracket notation: ?filter[name][$like]=value
+ - Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ProjectsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": filter,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ProjectsPage,
+ parse_obj_as(
+ type_=ProjectsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_project(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Project]:
+ """
+ Create a new project in the given workspace.
+
+ Example:
+ ```
+ POST /apis/entities/v2/workspaces/default/projects
+ {
+ "name": "ml-project",
+ "description": "Machine Learning project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Project name (unique within workspace). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+ description : typing.Optional[str]
+ Optional description of the project
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Project]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Project]:
+ """
+ Get a specific project by its workspace and name.
+
+ Example:
+ ```
+ GET /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Project]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_project(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Project]:
+ """
+ Update a project's description.
+
+ Example:
+ ```
+ PUT /apis/entities/v2/workspaces/default/projects/ml-project
+ {
+ "description": "Updated description for ML project"
+ }
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Updated description
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Project]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Project,
+ parse_obj_as(
+ type_=Project, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_project(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Delete a project.
+
+ Example:
+ ```
+ DELETE /apis/entities/v2/workspaces/default/projects/ml-project
+ ```
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/entities/v2/workspaces/{encode_path_param(workspace)}/projects/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/errors/__init__.py b/sdks/python/errors/__init__.py
new file mode 100644
index 0000000000..6003ceb8b8
--- /dev/null
+++ b/sdks/python/errors/__init__.py
@@ -0,0 +1,53 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .bad_request_error import BadRequestError
+ from .conflict_error import ConflictError
+ from .internal_server_error import InternalServerError
+ from .not_found_error import NotFoundError
+ from .service_unavailable_error import ServiceUnavailableError
+ from .unprocessable_entity_error import UnprocessableEntityError
+_dynamic_imports: typing.Dict[str, str] = {
+ "BadRequestError": ".bad_request_error",
+ "ConflictError": ".conflict_error",
+ "InternalServerError": ".internal_server_error",
+ "NotFoundError": ".not_found_error",
+ "ServiceUnavailableError": ".service_unavailable_error",
+ "UnprocessableEntityError": ".unprocessable_entity_error",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "BadRequestError",
+ "ConflictError",
+ "InternalServerError",
+ "NotFoundError",
+ "ServiceUnavailableError",
+ "UnprocessableEntityError",
+]
diff --git a/sdks/python/errors/bad_request_error.py b/sdks/python/errors/bad_request_error.py
new file mode 100644
index 0000000000..ec78e2697a
--- /dev/null
+++ b/sdks/python/errors/bad_request_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class BadRequestError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=400, headers=headers, body=body)
diff --git a/sdks/python/errors/conflict_error.py b/sdks/python/errors/conflict_error.py
new file mode 100644
index 0000000000..be04e01aee
--- /dev/null
+++ b/sdks/python/errors/conflict_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class ConflictError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=409, headers=headers, body=body)
diff --git a/sdks/python/errors/internal_server_error.py b/sdks/python/errors/internal_server_error.py
new file mode 100644
index 0000000000..fabcc45cf7
--- /dev/null
+++ b/sdks/python/errors/internal_server_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class InternalServerError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=500, headers=headers, body=body)
diff --git a/sdks/python/errors/not_found_error.py b/sdks/python/errors/not_found_error.py
new file mode 100644
index 0000000000..75f557df64
--- /dev/null
+++ b/sdks/python/errors/not_found_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class NotFoundError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=404, headers=headers, body=body)
diff --git a/sdks/python/errors/service_unavailable_error.py b/sdks/python/errors/service_unavailable_error.py
new file mode 100644
index 0000000000..950c474028
--- /dev/null
+++ b/sdks/python/errors/service_unavailable_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class ServiceUnavailableError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=503, headers=headers, body=body)
diff --git a/sdks/python/errors/unprocessable_entity_error.py b/sdks/python/errors/unprocessable_entity_error.py
new file mode 100644
index 0000000000..1c801a4bc0
--- /dev/null
+++ b/sdks/python/errors/unprocessable_entity_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.api_error import ApiError
+
+
+class UnprocessableEntityError(ApiError):
+ def __init__(self, body: typing.Any, headers: typing.Optional[typing.Dict[str, str]] = None):
+ super().__init__(status_code=422, headers=headers, body=body)
diff --git a/sdks/python/evaluator_results/__init__.py b/sdks/python/evaluator_results/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/evaluator_results/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/evaluator_results/client.py b/sdks/python/evaluator_results/client.py
new file mode 100644
index 0000000000..8fb0814dec
--- /dev/null
+++ b/sdks/python/evaluator_results/client.py
@@ -0,0 +1,469 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.evaluator_result import EvaluatorResult
+from ..types.evaluator_result_data_type import EvaluatorResultDataType
+from ..types.evaluator_result_filter import EvaluatorResultFilter
+from ..types.evaluator_result_sort_field import EvaluatorResultSortField
+from ..types.evaluator_results_page import EvaluatorResultsPage
+from .raw_client import AsyncRawEvaluatorResultsClient, RawEvaluatorResultsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class EvaluatorResultsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawEvaluatorResultsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawEvaluatorResultsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawEvaluatorResultsClient
+ """
+ return self._raw_client
+
+ def list_evaluator_results(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[EvaluatorResultSortField] = None,
+ filter: typing.Optional[EvaluatorResultFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EvaluatorResultsPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[EvaluatorResultSortField]
+
+ filter : typing.Optional[EvaluatorResultFilter]
+ Filter evaluator results by span_id, session_id, name, data_type, created_by, value range, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResultsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.evaluator_results.list_evaluator_results(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_evaluator_results(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_evaluator_result(
+ self,
+ workspace: str,
+ *,
+ span_id: str,
+ session_id: str,
+ name: str,
+ data_type: EvaluatorResultDataType,
+ value: typing.Optional[float] = OMIT,
+ string_value: typing.Optional[str] = OMIT,
+ comment: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EvaluatorResult:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+ Target span id. Not validated against existing spans (loose target policy).
+
+ session_id : str
+ Session id the target span belongs to. Denormalized so session-scoped reads stay fast.
+
+ name : str
+ Evaluator / metric identity (e.g. 'faithfulness/v1').
+
+ data_type : EvaluatorResultDataType
+ Discriminator for which of value / string_value carries the payload.
+
+ value : typing.Optional[float]
+ Numeric value. Required when data_type is NUMERIC or BOOLEAN (0|1).
+
+ string_value : typing.Optional[str]
+ String value. Required when data_type is CATEGORICAL or TEXT.
+
+ comment : typing.Optional[str]
+ Free-text rationale or explanation.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResult
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.evaluator_results.create_evaluator_result(
+ workspace="workspace",
+ span_id="span_id",
+ session_id="session_id",
+ name="name",
+ data_type="NUMERIC",
+ )
+ """
+ _response = self._raw_client.create_evaluator_result(
+ workspace,
+ span_id=span_id,
+ session_id=session_id,
+ name=name,
+ data_type=data_type,
+ value=value,
+ string_value=string_value,
+ comment=comment,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_evaluator_result(
+ self, workspace: str, evaluator_result_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> EvaluatorResult:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ evaluator_result_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResult
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.evaluator_results.get_evaluator_result(
+ workspace="workspace",
+ evaluator_result_id="evaluator_result_id",
+ )
+ """
+ _response = self._raw_client.get_evaluator_result(
+ workspace, evaluator_result_id, request_options=request_options
+ )
+ return _response.data
+
+ def list_evaluator_results_for_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[EvaluatorResult]
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.evaluator_results.list_evaluator_results_for_span(
+ workspace="workspace",
+ span_id="span_id",
+ )
+ """
+ _response = self._raw_client.list_evaluator_results_for_span(
+ workspace, span_id, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncEvaluatorResultsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawEvaluatorResultsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawEvaluatorResultsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawEvaluatorResultsClient
+ """
+ return self._raw_client
+
+ async def list_evaluator_results(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[EvaluatorResultSortField] = None,
+ filter: typing.Optional[EvaluatorResultFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EvaluatorResultsPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[EvaluatorResultSortField]
+
+ filter : typing.Optional[EvaluatorResultFilter]
+ Filter evaluator results by span_id, session_id, name, data_type, created_by, value range, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResultsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.evaluator_results.list_evaluator_results(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_evaluator_results(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_evaluator_result(
+ self,
+ workspace: str,
+ *,
+ span_id: str,
+ session_id: str,
+ name: str,
+ data_type: EvaluatorResultDataType,
+ value: typing.Optional[float] = OMIT,
+ string_value: typing.Optional[str] = OMIT,
+ comment: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> EvaluatorResult:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+ Target span id. Not validated against existing spans (loose target policy).
+
+ session_id : str
+ Session id the target span belongs to. Denormalized so session-scoped reads stay fast.
+
+ name : str
+ Evaluator / metric identity (e.g. 'faithfulness/v1').
+
+ data_type : EvaluatorResultDataType
+ Discriminator for which of value / string_value carries the payload.
+
+ value : typing.Optional[float]
+ Numeric value. Required when data_type is NUMERIC or BOOLEAN (0|1).
+
+ string_value : typing.Optional[str]
+ String value. Required when data_type is CATEGORICAL or TEXT.
+
+ comment : typing.Optional[str]
+ Free-text rationale or explanation.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResult
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.evaluator_results.create_evaluator_result(
+ workspace="workspace",
+ span_id="span_id",
+ session_id="session_id",
+ name="name",
+ data_type="NUMERIC",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_evaluator_result(
+ workspace,
+ span_id=span_id,
+ session_id=session_id,
+ name=name,
+ data_type=data_type,
+ value=value,
+ string_value=string_value,
+ comment=comment,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_evaluator_result(
+ self, workspace: str, evaluator_result_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> EvaluatorResult:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ evaluator_result_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ EvaluatorResult
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.evaluator_results.get_evaluator_result(
+ workspace="workspace",
+ evaluator_result_id="evaluator_result_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_evaluator_result(
+ workspace, evaluator_result_id, request_options=request_options
+ )
+ return _response.data
+
+ async def list_evaluator_results_for_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[EvaluatorResult]
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.evaluator_results.list_evaluator_results_for_span(
+ workspace="workspace",
+ span_id="span_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_evaluator_results_for_span(
+ workspace, span_id, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/evaluator_results/raw_client.py b/sdks/python/evaluator_results/raw_client.py
new file mode 100644
index 0000000000..c4a64f6bb3
--- /dev/null
+++ b/sdks/python/evaluator_results/raw_client.py
@@ -0,0 +1,589 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.evaluator_result import EvaluatorResult
+from ..types.evaluator_result_data_type import EvaluatorResultDataType
+from ..types.evaluator_result_filter import EvaluatorResultFilter
+from ..types.evaluator_result_sort_field import EvaluatorResultSortField
+from ..types.evaluator_results_page import EvaluatorResultsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawEvaluatorResultsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_evaluator_results(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[EvaluatorResultSortField] = None,
+ filter: typing.Optional[EvaluatorResultFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[EvaluatorResultsPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[EvaluatorResultSortField]
+
+ filter : typing.Optional[EvaluatorResultFilter]
+ Filter evaluator results by span_id, session_id, name, data_type, created_by, value range, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[EvaluatorResultsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=EvaluatorResultFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResultsPage,
+ parse_obj_as(
+ type_=EvaluatorResultsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_evaluator_result(
+ self,
+ workspace: str,
+ *,
+ span_id: str,
+ session_id: str,
+ name: str,
+ data_type: EvaluatorResultDataType,
+ value: typing.Optional[float] = OMIT,
+ string_value: typing.Optional[str] = OMIT,
+ comment: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+ Target span id. Not validated against existing spans (loose target policy).
+
+ session_id : str
+ Session id the target span belongs to. Denormalized so session-scoped reads stay fast.
+
+ name : str
+ Evaluator / metric identity (e.g. 'faithfulness/v1').
+
+ data_type : EvaluatorResultDataType
+ Discriminator for which of value / string_value carries the payload.
+
+ value : typing.Optional[float]
+ Numeric value. Required when data_type is NUMERIC or BOOLEAN (0|1).
+
+ string_value : typing.Optional[str]
+ String value. Required when data_type is CATEGORICAL or TEXT.
+
+ comment : typing.Optional[str]
+ Free-text rationale or explanation.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[EvaluatorResult]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results",
+ method="POST",
+ json={
+ "span_id": span_id,
+ "session_id": session_id,
+ "name": name,
+ "value": value,
+ "string_value": string_value,
+ "data_type": data_type,
+ "comment": comment,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResult,
+ parse_obj_as(
+ type_=EvaluatorResult, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_evaluator_result(
+ self, workspace: str, evaluator_result_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ evaluator_result_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[EvaluatorResult]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results/{encode_path_param(evaluator_result_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResult,
+ parse_obj_as(
+ type_=EvaluatorResult, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_evaluator_results_for_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.List[EvaluatorResult]]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.List[EvaluatorResult]]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans/{encode_path_param(span_id)}/evaluator-results",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[EvaluatorResult],
+ parse_obj_as(
+ type_=typing.List[EvaluatorResult], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawEvaluatorResultsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_evaluator_results(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[EvaluatorResultSortField] = None,
+ filter: typing.Optional[EvaluatorResultFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[EvaluatorResultsPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[EvaluatorResultSortField]
+
+ filter : typing.Optional[EvaluatorResultFilter]
+ Filter evaluator results by span_id, session_id, name, data_type, created_by, value range, and created_at range.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[EvaluatorResultsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=EvaluatorResultFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResultsPage,
+ parse_obj_as(
+ type_=EvaluatorResultsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_evaluator_result(
+ self,
+ workspace: str,
+ *,
+ span_id: str,
+ session_id: str,
+ name: str,
+ data_type: EvaluatorResultDataType,
+ value: typing.Optional[float] = OMIT,
+ string_value: typing.Optional[str] = OMIT,
+ comment: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+ Target span id. Not validated against existing spans (loose target policy).
+
+ session_id : str
+ Session id the target span belongs to. Denormalized so session-scoped reads stay fast.
+
+ name : str
+ Evaluator / metric identity (e.g. 'faithfulness/v1').
+
+ data_type : EvaluatorResultDataType
+ Discriminator for which of value / string_value carries the payload.
+
+ value : typing.Optional[float]
+ Numeric value. Required when data_type is NUMERIC or BOOLEAN (0|1).
+
+ string_value : typing.Optional[str]
+ String value. Required when data_type is CATEGORICAL or TEXT.
+
+ comment : typing.Optional[str]
+ Free-text rationale or explanation.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[EvaluatorResult]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results",
+ method="POST",
+ json={
+ "span_id": span_id,
+ "session_id": session_id,
+ "name": name,
+ "value": value,
+ "string_value": string_value,
+ "data_type": data_type,
+ "comment": comment,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResult,
+ parse_obj_as(
+ type_=EvaluatorResult, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_evaluator_result(
+ self, workspace: str, evaluator_result_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[EvaluatorResult]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ evaluator_result_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[EvaluatorResult]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/evaluator-results/{encode_path_param(evaluator_result_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ EvaluatorResult,
+ parse_obj_as(
+ type_=EvaluatorResult, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_evaluator_results_for_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.List[EvaluatorResult]]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.List[EvaluatorResult]]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans/{encode_path_param(span_id)}/evaluator-results",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[EvaluatorResult],
+ parse_obj_as(
+ type_=typing.List[EvaluatorResult], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/experiment_groups/__init__.py b/sdks/python/experiment_groups/__init__.py
new file mode 100644
index 0000000000..2a2adb83a1
--- /dev/null
+++ b/sdks/python/experiment_groups/__init__.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort
+_dynamic_imports: typing.Dict[str, str] = {
+ "ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort": ".types"
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort"]
diff --git a/sdks/python/experiment_groups/client.py b/sdks/python/experiment_groups/client.py
new file mode 100644
index 0000000000..7c0e8dbf8f
--- /dev/null
+++ b/sdks/python/experiment_groups/client.py
@@ -0,0 +1,504 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.experiment_group_filter import ExperimentGroupFilter
+from ..types.experiment_group_response import ExperimentGroupResponse
+from ..types.experiment_group_responses_page import ExperimentGroupResponsesPage
+from .raw_client import AsyncRawExperimentGroupsClient, RawExperimentGroupsClient
+from .types.list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort import (
+ ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort,
+)
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ExperimentGroupsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawExperimentGroupsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawExperimentGroupsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawExperimentGroupsClient
+ """
+ return self._raw_client
+
+ def list_experiment_groups(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentGroupFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentGroupFilter]
+ Filter experiment groups by name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiment_groups.list_experiment_groups(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_experiment_groups(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_experiment_group(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiment_groups.create_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.create_experiment_group(
+ workspace, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ def get_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiment_groups.get_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_experiment_group(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_experiment_group(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiment_groups.update_experiment_group(
+ workspace="workspace",
+ name_="name",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_experiment_group(
+ workspace, name_, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ def delete_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiment_groups.delete_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_experiment_group(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncExperimentGroupsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawExperimentGroupsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawExperimentGroupsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawExperimentGroupsClient
+ """
+ return self._raw_client
+
+ async def list_experiment_groups(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentGroupFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentGroupFilter]
+ Filter experiment groups by name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiment_groups.list_experiment_groups(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_experiment_groups(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_experiment_group(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiment_groups.create_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_experiment_group(
+ workspace, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def get_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiment_groups.get_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_experiment_group(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_experiment_group(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentGroupResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentGroupResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiment_groups.update_experiment_group(
+ workspace="workspace",
+ name_="name",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_experiment_group(
+ workspace, name_, name=name, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiment_groups.delete_experiment_group(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_experiment_group(workspace, name, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/experiment_groups/raw_client.py b/sdks/python/experiment_groups/raw_client.py
new file mode 100644
index 0000000000..93f683b78a
--- /dev/null
+++ b/sdks/python/experiment_groups/raw_client.py
@@ -0,0 +1,784 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.conflict_error import ConflictError
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.experiment_group_filter import ExperimentGroupFilter
+from ..types.experiment_group_response import ExperimentGroupResponse
+from ..types.experiment_group_responses_page import ExperimentGroupResponsesPage
+from .types.list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort import (
+ ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort,
+)
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawExperimentGroupsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_experiment_groups(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentGroupFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentGroupResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentGroupFilter]
+ Filter experiment groups by name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentGroupResponsesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentGroupFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponsesPage,
+ parse_obj_as(
+ type_=ExperimentGroupResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_experiment_group(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_experiment_group(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name_)}",
+ method="PUT",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawExperimentGroupsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_experiment_groups(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentGroupFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentGroupResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentGroupFilter]
+ Filter experiment groups by name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentGroupResponsesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentGroupFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponsesPage,
+ parse_obj_as(
+ type_=ExperimentGroupResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_experiment_group(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_experiment_group(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentGroupResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Workspace-unique group name.
+
+ description : typing.Optional[str]
+ Human-readable purpose of the group.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentGroupResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name_)}",
+ method="PUT",
+ json={
+ "name": name,
+ "description": description,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentGroupResponse,
+ parse_obj_as(
+ type_=ExperimentGroupResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_experiment_group(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiment-groups/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/experiment_groups/types/__init__.py b/sdks/python/experiment_groups/types/__init__.py
new file mode 100644
index 0000000000..b96b5f8d6e
--- /dev/null
+++ b/sdks/python/experiment_groups/types/__init__.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort import (
+ ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort": ".list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort"
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort"]
diff --git a/sdks/python/experiment_groups/types/list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort.py b/sdks/python/experiment_groups/types/list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort.py
new file mode 100644
index 0000000000..b8589f6926
--- /dev/null
+++ b/sdks/python/experiment_groups/types/list_experiment_groups_apis_intake_v2workspaces_workspace_experiment_groups_get_request_sort.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort = typing.Union[
+ typing.Literal["-created_at", "created_at", "-updated_at", "updated_at", "-name"], typing.Any
+]
diff --git a/sdks/python/experiments/__init__.py b/sdks/python/experiments/__init__.py
new file mode 100644
index 0000000000..4a09452243
--- /dev/null
+++ b/sdks/python/experiments/__init__.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort
+_dynamic_imports: typing.Dict[str, str] = {
+ "ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort": ".types"
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort"]
diff --git a/sdks/python/experiments/client.py b/sdks/python/experiments/client.py
new file mode 100644
index 0000000000..86893bba78
--- /dev/null
+++ b/sdks/python/experiments/client.py
@@ -0,0 +1,802 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.experiment_filter import ExperimentFilter
+from ..types.experiment_response import ExperimentResponse
+from ..types.experiment_responses_page import ExperimentResponsesPage
+from ..types.experiment_session_filter import ExperimentSessionFilter
+from ..types.experiment_session_responses_page import ExperimentSessionResponsesPage
+from .raw_client import AsyncRawExperimentsClient, RawExperimentsClient
+from .types.list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort import (
+ ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort,
+)
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ExperimentsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawExperimentsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawExperimentsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawExperimentsClient
+ """
+ return self._raw_client
+
+ def list_experiments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentFilter]
+ Filter experiments by name, experiment_group_id, agent_name, agent_version, dataset_name, dataset_version, created_by, created_at, or updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.list_experiments(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_experiments(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_experiment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.create_experiment(
+ workspace="workspace",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+ )
+ """
+ _response = self._raw_client.create_experiment(
+ workspace,
+ name=name,
+ agent_name=agent_name,
+ agent_version=agent_version,
+ dataset_name=dataset_name,
+ experiment_group_id=experiment_group_id,
+ dataset_version=dataset_version,
+ source_link=source_link,
+ metadata=metadata,
+ description=description,
+ summary=summary,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.get_experiment(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_experiment(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_experiment(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.update_experiment(
+ workspace="workspace",
+ name_="name",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+ )
+ """
+ _response = self._raw_client.update_experiment(
+ workspace,
+ name_,
+ name=name,
+ agent_name=agent_name,
+ agent_version=agent_version,
+ dataset_name=dataset_name,
+ experiment_group_id=experiment_group_id,
+ dataset_version=dataset_version,
+ source_link=source_link,
+ metadata=metadata,
+ description=description,
+ summary=summary,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def delete_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.delete_experiment(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_experiment(workspace, name, request_options=request_options)
+ return _response.data
+
+ def list_experiment_sessions(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ filter: typing.Optional[ExperimentSessionFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentSessionResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ filter : typing.Optional[ExperimentSessionFilter]
+ Filter sessions by test_case_id and status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentSessionResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.experiments.list_experiment_sessions(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_experiment_sessions(
+ workspace, name, page=page, page_size=page_size, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncExperimentsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawExperimentsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawExperimentsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawExperimentsClient
+ """
+ return self._raw_client
+
+ async def list_experiments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentFilter]
+ Filter experiments by name, experiment_group_id, agent_name, agent_version, dataset_name, dataset_version, created_by, created_at, or updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.list_experiments(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_experiments(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_experiment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.create_experiment(
+ workspace="workspace",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_experiment(
+ workspace,
+ name=name,
+ agent_name=agent_name,
+ agent_version=agent_version,
+ dataset_name=dataset_name,
+ experiment_group_id=experiment_group_id,
+ dataset_version=dataset_version,
+ source_link=source_link,
+ metadata=metadata,
+ description=description,
+ summary=summary,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.get_experiment(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_experiment(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_experiment(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.update_experiment(
+ workspace="workspace",
+ name_="name",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_experiment(
+ workspace,
+ name_,
+ name=name,
+ agent_name=agent_name,
+ agent_version=agent_version,
+ dataset_name=dataset_name,
+ experiment_group_id=experiment_group_id,
+ dataset_version=dataset_version,
+ source_link=source_link,
+ metadata=metadata,
+ description=description,
+ summary=summary,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def delete_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.delete_experiment(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_experiment(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def list_experiment_sessions(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ filter: typing.Optional[ExperimentSessionFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ExperimentSessionResponsesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ filter : typing.Optional[ExperimentSessionFilter]
+ Filter sessions by test_case_id and status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ExperimentSessionResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.experiments.list_experiment_sessions(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_experiment_sessions(
+ workspace, name, page=page, page_size=page_size, filter=filter, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/experiments/raw_client.py b/sdks/python/experiments/raw_client.py
new file mode 100644
index 0000000000..2be5e9fa37
--- /dev/null
+++ b/sdks/python/experiments/raw_client.py
@@ -0,0 +1,1143 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.conflict_error import ConflictError
+from ..errors.not_found_error import NotFoundError
+from ..errors.service_unavailable_error import ServiceUnavailableError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.experiment_filter import ExperimentFilter
+from ..types.experiment_response import ExperimentResponse
+from ..types.experiment_responses_page import ExperimentResponsesPage
+from ..types.experiment_session_filter import ExperimentSessionFilter
+from ..types.experiment_session_responses_page import ExperimentSessionResponsesPage
+from .types.list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort import (
+ ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort,
+)
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawExperimentsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_experiments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentFilter]
+ Filter experiments by name, experiment_group_id, agent_name, agent_version, dataset_name, dataset_version, created_by, created_at, or updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentResponsesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponsesPage,
+ parse_obj_as(
+ type_=ExperimentResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_experiment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments",
+ method="POST",
+ json={
+ "name": name,
+ "experiment_group_id": experiment_group_id,
+ "agent_name": agent_name,
+ "agent_version": agent_version,
+ "dataset_name": dataset_name,
+ "dataset_version": dataset_version,
+ "source_link": source_link,
+ "metadata": metadata,
+ "description": description,
+ "summary": summary,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_experiment(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name_)}",
+ method="PUT",
+ json={
+ "name": name,
+ "experiment_group_id": experiment_group_id,
+ "agent_name": agent_name,
+ "agent_version": agent_version,
+ "dataset_name": dataset_name,
+ "dataset_version": dataset_version,
+ "source_link": source_link,
+ "metadata": metadata,
+ "description": description,
+ "summary": summary,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_experiment_sessions(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ filter: typing.Optional[ExperimentSessionFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ExperimentSessionResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ filter : typing.Optional[ExperimentSessionFilter]
+ Filter sessions by test_case_id and status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ExperimentSessionResponsesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}/sessions",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentSessionFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentSessionResponsesPage,
+ parse_obj_as(
+ type_=ExperimentSessionResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 503:
+ raise ServiceUnavailableError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawExperimentsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_experiments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort] = None,
+ filter: typing.Optional[ExperimentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort]
+ Sort field; prefix with '-' for descending.
+
+ filter : typing.Optional[ExperimentFilter]
+ Filter experiments by name, experiment_group_id, agent_name, agent_version, dataset_name, dataset_version, created_by, created_at, or updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentResponsesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponsesPage,
+ parse_obj_as(
+ type_=ExperimentResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_experiment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments",
+ method="POST",
+ json={
+ "name": name,
+ "experiment_group_id": experiment_group_id,
+ "agent_name": agent_name,
+ "agent_version": agent_version,
+ "dataset_name": dataset_name,
+ "dataset_version": dataset_version,
+ "source_link": source_link,
+ "metadata": metadata,
+ "description": description,
+ "summary": summary,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_experiment(
+ self,
+ workspace: str,
+ name_: str,
+ *,
+ name: str,
+ agent_name: str,
+ agent_version: str,
+ dataset_name: str,
+ experiment_group_id: typing.Optional[str] = OMIT,
+ dataset_version: typing.Optional[str] = OMIT,
+ source_link: typing.Optional[str] = OMIT,
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ summary: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name_ : str
+
+ name : str
+ Producer-supplied, workspace-unique experiment id.
+
+ agent_name : str
+ Name of the agent under test.
+
+ agent_version : str
+ Version of the agent under test.
+
+ dataset_name : str
+ Producer-supplied dataset name.
+
+ experiment_group_id : typing.Optional[str]
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+
+ dataset_version : typing.Optional[str]
+ Producer-supplied dataset version.
+
+ source_link : typing.Optional[str]
+ Optional URL for the source experiment.
+
+ metadata : typing.Optional[typing.Dict[str, typing.Any]]
+ Free-form producer metadata.
+
+ description : typing.Optional[str]
+ Human-readable description.
+
+ summary : typing.Optional[str]
+ Human-authored summary of results.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name_)}",
+ method="PUT",
+ json={
+ "name": name,
+ "experiment_group_id": experiment_group_id,
+ "agent_name": agent_name,
+ "agent_version": agent_version,
+ "dataset_name": dataset_name,
+ "dataset_version": dataset_version,
+ "source_link": source_link,
+ "metadata": metadata,
+ "description": description,
+ "summary": summary,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentResponse,
+ parse_obj_as(
+ type_=ExperimentResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_experiment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_experiment_sessions(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ filter: typing.Optional[ExperimentSessionFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ExperimentSessionResponsesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ filter : typing.Optional[ExperimentSessionFilter]
+ Filter sessions by test_case_id and status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ExperimentSessionResponsesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/experiments/{encode_path_param(name)}/sessions",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ExperimentSessionFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ExperimentSessionResponsesPage,
+ parse_obj_as(
+ type_=ExperimentSessionResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 503:
+ raise ServiceUnavailableError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/experiments/types/__init__.py b/sdks/python/experiments/types/__init__.py
new file mode 100644
index 0000000000..b649223ace
--- /dev/null
+++ b/sdks/python/experiments/types/__init__.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort import (
+ ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort": ".list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort"
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort"]
diff --git a/sdks/python/experiments/types/list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort.py b/sdks/python/experiments/types/list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort.py
new file mode 100644
index 0000000000..d5b7ebd098
--- /dev/null
+++ b/sdks/python/experiments/types/list_experiments_apis_intake_v2workspaces_workspace_experiments_get_request_sort.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort = typing.Union[
+ typing.Literal["-created_at", "created_at", "-updated_at", "updated_at", "-name"], typing.Any
+]
diff --git a/sdks/python/files/__init__.py b/sdks/python/files/__init__.py
new file mode 100644
index 0000000000..3cde42948a
--- /dev/null
+++ b/sdks/python/files/__init__.py
@@ -0,0 +1,52 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import (
+ CreateFilesetRequestStorage,
+ CreateFilesetRequestStorage_Huggingface,
+ CreateFilesetRequestStorage_Local,
+ CreateFilesetRequestStorage_Ngc,
+ CreateFilesetRequestStorage_S3,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "CreateFilesetRequestStorage": ".types",
+ "CreateFilesetRequestStorage_Huggingface": ".types",
+ "CreateFilesetRequestStorage_Local": ".types",
+ "CreateFilesetRequestStorage_Ngc": ".types",
+ "CreateFilesetRequestStorage_S3": ".types",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "CreateFilesetRequestStorage",
+ "CreateFilesetRequestStorage_Huggingface",
+ "CreateFilesetRequestStorage_Local",
+ "CreateFilesetRequestStorage_Ngc",
+ "CreateFilesetRequestStorage_S3",
+]
diff --git a/sdks/python/files/client.py b/sdks/python/files/client.py
new file mode 100644
index 0000000000..58678b21d1
--- /dev/null
+++ b/sdks/python/files/client.py
@@ -0,0 +1,1136 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.fileset_file_output import FilesetFileOutput
+from ..types.fileset_filter import FilesetFilter
+from ..types.fileset_metadata_input import FilesetMetadataInput
+from ..types.fileset_output import FilesetOutput
+from ..types.fileset_outputs_page import FilesetOutputsPage
+from ..types.fileset_purpose import FilesetPurpose
+from ..types.generic_sort_field import GenericSortField
+from ..types.list_fileset_files_response import ListFilesetFilesResponse
+from .raw_client import AsyncRawFilesClient, RawFilesClient
+from .types.create_fileset_request_storage import CreateFilesetRequestStorage
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class FilesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawFilesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawFilesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawFilesClient
+ """
+ return self._raw_client
+
+ def list_filesets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[FilesetFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutputsPage:
+ """
+ List Filesets endpoint with filtering and pagination.
+
+ Supports filtering by name, description, purpose, storage_type, created_at, and updated_at via query parameters.
+ Returns paginated results with sorting options.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[FilesetFilter]
+ Filter filesets by name, description, purpose, storage_type, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutputsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.list_filesets(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_filesets(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_fileset(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ storage: typing.Optional[CreateFilesetRequestStorage] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ cache: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutput:
+ """
+ Create a new fileset.
+
+ If no storage configuration is provided, the default storage backend will be used.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the fileset. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ storage : typing.Optional[CreateFilesetRequestStorage]
+ The storage configuration for the fileset. If not provided, uses default storage.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ cache : typing.Optional[bool]
+ Cache all files after creation. Only applies to external storage.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.create_fileset(
+ workspace="workspace",
+ name="training-data-v1",
+ )
+ """
+ _response = self._raw_client.create_fileset(
+ workspace,
+ name=name,
+ description=description,
+ project=project,
+ storage=storage,
+ purpose=purpose,
+ metadata=metadata,
+ custom_fields=custom_fields,
+ cache=cache,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def retrieve_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetOutput:
+ """
+ Get Fileset by Workspace and Name.
+
+ Returns the details of a specific fileset identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.retrieve_fileset(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.retrieve_fileset(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetOutput:
+ """
+ Delete Fileset.
+
+ Permanently deletes a fileset from the platform.
+ Returns metadata about the deleted fileset.
+ For local storage backends, this also deletes the underlying files.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.delete_fileset(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_fileset(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_fileset_metadata(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutput:
+ """
+ Update Fileset Metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.update_fileset_metadata(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_fileset_metadata(
+ workspace,
+ name,
+ description=description,
+ project=project,
+ purpose=purpose,
+ metadata=metadata,
+ custom_fields=custom_fields,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Iterator[bytes]:
+ """
+ Download file content from a fileset.
+
+ Supports HTTP Range requests for partial content retrieval (status 206).
+ Returns the full file content (status 200) if no Range header is provided.
+ For external resources (HuggingFace, NGC), content is cached locally on first access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+ """
+ with self._raw_client.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ workspace, name, path, request_options=request_options
+ ) as r:
+ yield from r.data
+
+ def upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ self,
+ workspace: str,
+ name: str,
+ path: str,
+ *,
+ request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetFileOutput:
+ """
+ Upload file content to a fileset.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetFileOutput
+ Successful Response
+ """
+ _response = self._raw_client.upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ workspace, name, path, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetFileOutput:
+ """
+ Delete a specific file from a fileset.
+
+ Permanently deletes the file from the storage backend.
+ Returns metadata about the deleted file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetFileOutput
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+ """
+ _response = self._raw_client.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ workspace, name, path, request_options=request_options
+ )
+ return _response.data
+
+ def head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, str]:
+ """
+ Get file metadata without downloading content.
+
+ HEAD requests are often used before Range GETs to ensure the server
+ supports partial downloads (e.g., DuckDB's httpfs).
+ Returns Accept-Ranges, Content-Length, and Content-Type headers.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, str]
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+ """
+ _response = self._raw_client.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ workspace, name, path, request_options=request_options
+ )
+ return _response.headers
+
+ def list_fileset_files(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ path: typing.Optional[str] = None,
+ include_cache_status: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ListFilesetFilesResponse:
+ """
+ List Files in Fileset.
+
+ Returns a list of files stored in the specified fileset.
+ Optionally filter by path prefix to list files under a specific directory.
+
+ Each file includes a cache_status field:
+ - "not_cacheable": File is on default storage, caching not applicable
+ - "cached": File exists in cache storage
+ - "caching": File is currently being downloaded and cached
+ - "not_cached": File not in cache, will be cached on next download
+ - null: External storage, but cache status not checked (use include_cache_status=true)
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : typing.Optional[str]
+ Filter files by path prefix
+
+ include_cache_status : typing.Optional[bool]
+ Check and return cache status for each file. When false, storage files return null for cache_status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ListFilesetFilesResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.files.list_fileset_files(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_fileset_files(
+ workspace, name, path=path, include_cache_status=include_cache_status, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncFilesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawFilesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawFilesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawFilesClient
+ """
+ return self._raw_client
+
+ async def list_filesets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[FilesetFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutputsPage:
+ """
+ List Filesets endpoint with filtering and pagination.
+
+ Supports filtering by name, description, purpose, storage_type, created_at, and updated_at via query parameters.
+ Returns paginated results with sorting options.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[FilesetFilter]
+ Filter filesets by name, description, purpose, storage_type, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutputsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.list_filesets(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_filesets(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_fileset(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ storage: typing.Optional[CreateFilesetRequestStorage] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ cache: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutput:
+ """
+ Create a new fileset.
+
+ If no storage configuration is provided, the default storage backend will be used.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the fileset. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ storage : typing.Optional[CreateFilesetRequestStorage]
+ The storage configuration for the fileset. If not provided, uses default storage.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ cache : typing.Optional[bool]
+ Cache all files after creation. Only applies to external storage.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.create_fileset(
+ workspace="workspace",
+ name="training-data-v1",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_fileset(
+ workspace,
+ name=name,
+ description=description,
+ project=project,
+ storage=storage,
+ purpose=purpose,
+ metadata=metadata,
+ custom_fields=custom_fields,
+ cache=cache,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def retrieve_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetOutput:
+ """
+ Get Fileset by Workspace and Name.
+
+ Returns the details of a specific fileset identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.retrieve_fileset(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.retrieve_fileset(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetOutput:
+ """
+ Delete Fileset.
+
+ Permanently deletes a fileset from the platform.
+ Returns metadata about the deleted fileset.
+ For local storage backends, this also deletes the underlying files.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.delete_fileset(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_fileset(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_fileset_metadata(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetOutput:
+ """
+ Update Fileset Metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetOutput
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.update_fileset_metadata(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_fileset_metadata(
+ workspace,
+ name,
+ description=description,
+ project=project,
+ purpose=purpose,
+ metadata=metadata,
+ custom_fields=custom_fields,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Download file content from a fileset.
+
+ Supports HTTP Range requests for partial content retrieval (status 206).
+ Returns the full file content (status 200) if no Range header is provided.
+ For external resources (HuggingFace, NGC), content is cached locally on first access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+
+
+ asyncio.run(main())
+ """
+ async with self._raw_client.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ workspace, name, path, request_options=request_options
+ ) as r:
+ async for _chunk in r.data:
+ yield _chunk
+
+ async def upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ self,
+ workspace: str,
+ name: str,
+ path: str,
+ *,
+ request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> FilesetFileOutput:
+ """
+ Upload file content to a fileset.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetFileOutput
+ Successful Response
+ """
+ _response = await self._raw_client.upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ workspace, name, path, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> FilesetFileOutput:
+ """
+ Delete a specific file from a fileset.
+
+ Permanently deletes the file from the storage backend.
+ Returns metadata about the deleted file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ FilesetFileOutput
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ workspace, name, path, request_options=request_options
+ )
+ return _response.data
+
+ async def head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, str]:
+ """
+ Get file metadata without downloading content.
+
+ HEAD requests are often used before Range GETs to ensure the server
+ supports partial downloads (e.g., DuckDB's httpfs).
+ Returns Accept-Ranges, Content-Length, and Content-Type headers.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, str]
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ workspace="workspace",
+ name="name",
+ path="path",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ workspace, name, path, request_options=request_options
+ )
+ return _response.headers
+
+ async def list_fileset_files(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ path: typing.Optional[str] = None,
+ include_cache_status: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ListFilesetFilesResponse:
+ """
+ List Files in Fileset.
+
+ Returns a list of files stored in the specified fileset.
+ Optionally filter by path prefix to list files under a specific directory.
+
+ Each file includes a cache_status field:
+ - "not_cacheable": File is on default storage, caching not applicable
+ - "cached": File exists in cache storage
+ - "caching": File is currently being downloaded and cached
+ - "not_cached": File not in cache, will be cached on next download
+ - null: External storage, but cache status not checked (use include_cache_status=true)
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : typing.Optional[str]
+ Filter files by path prefix
+
+ include_cache_status : typing.Optional[bool]
+ Check and return cache status for each file. When false, storage files return null for cache_status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ListFilesetFilesResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.files.list_fileset_files(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_fileset_files(
+ workspace, name, path=path, include_cache_status=include_cache_status, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/files/raw_client.py b/sdks/python/files/raw_client.py
new file mode 100644
index 0000000000..ab702ccb4d
--- /dev/null
+++ b/sdks/python/files/raw_client.py
@@ -0,0 +1,1521 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import contextlib
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.fileset_file_output import FilesetFileOutput
+from ..types.fileset_filter import FilesetFilter
+from ..types.fileset_metadata_input import FilesetMetadataInput
+from ..types.fileset_output import FilesetOutput
+from ..types.fileset_outputs_page import FilesetOutputsPage
+from ..types.fileset_purpose import FilesetPurpose
+from ..types.generic_sort_field import GenericSortField
+from ..types.list_fileset_files_response import ListFilesetFilesResponse
+from .types.create_fileset_request_storage import CreateFilesetRequestStorage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawFilesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_filesets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[FilesetFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[FilesetOutputsPage]:
+ """
+ List Filesets endpoint with filtering and pagination.
+
+ Supports filtering by name, description, purpose, storage_type, created_at, and updated_at via query parameters.
+ Returns paginated results with sorting options.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[FilesetFilter]
+ Filter filesets by name, description, purpose, storage_type, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetOutputsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=FilesetFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutputsPage,
+ parse_obj_as(
+ type_=FilesetOutputsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_fileset(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ storage: typing.Optional[CreateFilesetRequestStorage] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ cache: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[FilesetOutput]:
+ """
+ Create a new fileset.
+
+ If no storage configuration is provided, the default storage backend will be used.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the fileset. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ storage : typing.Optional[CreateFilesetRequestStorage]
+ The storage configuration for the fileset. If not provided, uses default storage.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ cache : typing.Optional[bool]
+ Cache all files after creation. Only applies to external storage.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "project": project,
+ "storage": convert_and_respect_annotation_metadata(
+ object_=storage, annotation=CreateFilesetRequestStorage, direction="write"
+ ),
+ "purpose": purpose,
+ "metadata": convert_and_respect_annotation_metadata(
+ object_=metadata, annotation=FilesetMetadataInput, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "cache": cache,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def retrieve_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[FilesetOutput]:
+ """
+ Get Fileset by Workspace and Name.
+
+ Returns the details of a specific fileset identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[FilesetOutput]:
+ """
+ Delete Fileset.
+
+ Permanently deletes a fileset from the platform.
+ Returns metadata about the deleted fileset.
+ For local storage backends, this also deletes the underlying files.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_fileset_metadata(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[FilesetOutput]:
+ """
+ Update Fileset Metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "project": project,
+ "purpose": purpose,
+ "metadata": convert_and_respect_annotation_metadata(
+ object_=metadata, annotation=FilesetMetadataInput, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ @contextlib.contextmanager
+ def download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Download file content from a fileset.
+
+ Supports HTTP Range requests for partial content retrieval (status 206).
+ Returns the full file content (status 200) if no Range header is provided.
+ For external resources (HuggingFace, NGC), content is cached locally on first access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ Successful Response
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="GET",
+ request_options=request_options,
+ ) as _response:
+
+ def _stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code,
+ headers=dict(_response.headers),
+ body=_response.json(),
+ cause=e,
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ yield _stream()
+
+ def upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ self,
+ workspace: str,
+ name: str,
+ path: str,
+ *,
+ request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[FilesetFileOutput]:
+ """
+ Upload file content to a fileset.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetFileOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="PUT",
+ content=request,
+ headers={
+ "content-type": "application/octet-stream",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetFileOutput,
+ parse_obj_as(
+ type_=FilesetFileOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[FilesetFileOutput]:
+ """
+ Delete a specific file from a fileset.
+
+ Permanently deletes the file from the storage backend.
+ Returns metadata about the deleted file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[FilesetFileOutput]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetFileOutput,
+ parse_obj_as(
+ type_=FilesetFileOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Get file metadata without downloading content.
+
+ HEAD requests are often used before Range GETs to ensure the server
+ supports partial downloads (e.g., DuckDB's httpfs).
+ Returns Accept-Ranges, Content-Length, and Content-Type headers.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="HEAD",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_fileset_files(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ path: typing.Optional[str] = None,
+ include_cache_status: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ListFilesetFilesResponse]:
+ """
+ List Files in Fileset.
+
+ Returns a list of files stored in the specified fileset.
+ Optionally filter by path prefix to list files under a specific directory.
+
+ Each file includes a cache_status field:
+ - "not_cacheable": File is on default storage, caching not applicable
+ - "cached": File exists in cache storage
+ - "caching": File is currently being downloaded and cached
+ - "not_cached": File not in cache, will be cached on next download
+ - null: External storage, but cache status not checked (use include_cache_status=true)
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : typing.Optional[str]
+ Filter files by path prefix
+
+ include_cache_status : typing.Optional[bool]
+ Check and return cache status for each file. When false, storage files return null for cache_status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ListFilesetFilesResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/files",
+ method="GET",
+ params={
+ "path": path,
+ "include_cache_status": include_cache_status,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ListFilesetFilesResponse,
+ parse_obj_as(
+ type_=ListFilesetFilesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawFilesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_filesets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[FilesetFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[FilesetOutputsPage]:
+ """
+ List Filesets endpoint with filtering and pagination.
+
+ Supports filtering by name, description, purpose, storage_type, created_at, and updated_at via query parameters.
+ Returns paginated results with sorting options.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[FilesetFilter]
+ Filter filesets by name, description, purpose, storage_type, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetOutputsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=FilesetFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutputsPage,
+ parse_obj_as(
+ type_=FilesetOutputsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_fileset(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ storage: typing.Optional[CreateFilesetRequestStorage] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ cache: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[FilesetOutput]:
+ """
+ Create a new fileset.
+
+ If no storage configuration is provided, the default storage backend will be used.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the fileset. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ storage : typing.Optional[CreateFilesetRequestStorage]
+ The storage configuration for the fileset. If not provided, uses default storage.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ cache : typing.Optional[bool]
+ Cache all files after creation. Only applies to external storage.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "project": project,
+ "storage": convert_and_respect_annotation_metadata(
+ object_=storage, annotation=CreateFilesetRequestStorage, direction="write"
+ ),
+ "purpose": purpose,
+ "metadata": convert_and_respect_annotation_metadata(
+ object_=metadata, annotation=FilesetMetadataInput, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "cache": cache,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def retrieve_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[FilesetOutput]:
+ """
+ Get Fileset by Workspace and Name.
+
+ Returns the details of a specific fileset identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_fileset(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[FilesetOutput]:
+ """
+ Delete Fileset.
+
+ Permanently deletes a fileset from the platform.
+ Returns metadata about the deleted fileset.
+ For local storage backends, this also deletes the underlying files.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_fileset_metadata(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ purpose: typing.Optional[FilesetPurpose] = OMIT,
+ metadata: typing.Optional[FilesetMetadataInput] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[FilesetOutput]:
+ """
+ Update Fileset Metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ The description of the fileset.
+
+ project : typing.Optional[str]
+ The name of the project associated with this fileset.
+
+ purpose : typing.Optional[FilesetPurpose]
+ The purpose of the fileset.
+
+ metadata : typing.Optional[FilesetMetadataInput]
+ Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for the fileset.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "project": project,
+ "purpose": purpose,
+ "metadata": convert_and_respect_annotation_metadata(
+ object_=metadata, annotation=FilesetMetadataInput, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetOutput,
+ parse_obj_as(
+ type_=FilesetOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ @contextlib.asynccontextmanager
+ async def download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Download file content from a fileset.
+
+ Supports HTTP Range requests for partial content retrieval (status 206).
+ Returns the full file content (status 200) if no Range header is provided.
+ For external resources (HuggingFace, NGC), content is cached locally on first access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ Successful Response
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="GET",
+ request_options=request_options,
+ ) as _response:
+
+ async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code,
+ headers=dict(_response.headers),
+ body=_response.json(),
+ cause=e,
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ yield await _stream()
+
+ async def upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(
+ self,
+ workspace: str,
+ name: str,
+ path: str,
+ *,
+ request: typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[FilesetFileOutput]:
+ """
+ Upload file content to a fileset.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request : typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetFileOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="PUT",
+ content=request,
+ headers={
+ "content-type": "application/octet-stream",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetFileOutput,
+ parse_obj_as(
+ type_=FilesetFileOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[FilesetFileOutput]:
+ """
+ Delete a specific file from a fileset.
+
+ Permanently deletes the file from the storage backend.
+ Returns metadata about the deleted file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[FilesetFileOutput]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ FilesetFileOutput,
+ parse_obj_as(
+ type_=FilesetFileOutput, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ self, workspace: str, name: str, path: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Get file metadata without downloading content.
+
+ HEAD requests are often used before Range GETs to ensure the server
+ supports partial downloads (e.g., DuckDB's httpfs).
+ Returns Accept-Ranges, Content-Length, and Content-Type headers.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/-/{encode_path_param(path)}",
+ method="HEAD",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_fileset_files(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ path: typing.Optional[str] = None,
+ include_cache_status: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ListFilesetFilesResponse]:
+ """
+ List Files in Fileset.
+
+ Returns a list of files stored in the specified fileset.
+ Optionally filter by path prefix to list files under a specific directory.
+
+ Each file includes a cache_status field:
+ - "not_cacheable": File is on default storage, caching not applicable
+ - "cached": File exists in cache storage
+ - "caching": File is currently being downloaded and cached
+ - "not_cached": File not in cache, will be cached on next download
+ - null: External storage, but cache status not checked (use include_cache_status=true)
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ path : typing.Optional[str]
+ Filter files by path prefix
+
+ include_cache_status : typing.Optional[bool]
+ Check and return cache status for each file. When false, storage files return null for cache_status.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ListFilesetFilesResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/files",
+ method="GET",
+ params={
+ "path": path,
+ "include_cache_status": include_cache_status,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ListFilesetFilesResponse,
+ parse_obj_as(
+ type_=ListFilesetFilesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/files/types/__init__.py b/sdks/python/files/types/__init__.py
new file mode 100644
index 0000000000..93bfae4215
--- /dev/null
+++ b/sdks/python/files/types/__init__.py
@@ -0,0 +1,52 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .create_fileset_request_storage import (
+ CreateFilesetRequestStorage,
+ CreateFilesetRequestStorage_Huggingface,
+ CreateFilesetRequestStorage_Local,
+ CreateFilesetRequestStorage_Ngc,
+ CreateFilesetRequestStorage_S3,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "CreateFilesetRequestStorage": ".create_fileset_request_storage",
+ "CreateFilesetRequestStorage_Huggingface": ".create_fileset_request_storage",
+ "CreateFilesetRequestStorage_Local": ".create_fileset_request_storage",
+ "CreateFilesetRequestStorage_Ngc": ".create_fileset_request_storage",
+ "CreateFilesetRequestStorage_S3": ".create_fileset_request_storage",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "CreateFilesetRequestStorage",
+ "CreateFilesetRequestStorage_Huggingface",
+ "CreateFilesetRequestStorage_Local",
+ "CreateFilesetRequestStorage_Ngc",
+ "CreateFilesetRequestStorage_S3",
+]
diff --git a/sdks/python/files/types/create_fileset_request_storage.py b/sdks/python/files/types/create_fileset_request_storage.py
new file mode 100644
index 0000000000..5a2720bb29
--- /dev/null
+++ b/sdks/python/files/types/create_fileset_request_storage.py
@@ -0,0 +1,120 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ...types.huggingface_storage_config_repo_type import HuggingfaceStorageConfigRepoType
+from ...types.ngc_storage_config_target_type import NgcStorageConfigTargetType
+from ...types.s3storage_config_signature_version import S3StorageConfigSignatureVersion
+from ...types.secret_ref import SecretRef
+
+
+class CreateFilesetRequestStorage_Local(UniversalBaseModel):
+ """
+ The storage configuration for the fileset. If not provided, uses default storage.
+ """
+
+ type: typing.Literal["local"] = "local"
+ read_chunk_size: typing.Optional[int] = None
+ path: str
+ write_buffer_size: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class CreateFilesetRequestStorage_Ngc(UniversalBaseModel):
+ """
+ The storage configuration for the fileset. If not provided, uses default storage.
+ """
+
+ type: typing.Literal["ngc"] = "ngc"
+ read_chunk_size: typing.Optional[int] = None
+ org: str
+ team: str
+ target: str
+ target_type: typing.Optional[NgcStorageConfigTargetType] = None
+ version: typing.Optional[str] = None
+ original_version: typing.Optional[str] = None
+ api_key_secret: SecretRef
+ host: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class CreateFilesetRequestStorage_Huggingface(UniversalBaseModel):
+ """
+ The storage configuration for the fileset. If not provided, uses default storage.
+ """
+
+ type: typing.Literal["huggingface"] = "huggingface"
+ read_chunk_size: typing.Optional[int] = None
+ repo_id: str
+ repo_type: typing.Optional[HuggingfaceStorageConfigRepoType] = None
+ revision: typing.Optional[str] = None
+ original_revision: typing.Optional[str] = None
+ token_secret: typing.Optional[SecretRef] = None
+ endpoint: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class CreateFilesetRequestStorage_S3(UniversalBaseModel):
+ """
+ The storage configuration for the fileset. If not provided, uses default storage.
+ """
+
+ type: typing.Literal["s3"] = "s3"
+ read_chunk_size: typing.Optional[int] = None
+ bucket: str
+ prefix: typing.Optional[str] = None
+ region: typing.Optional[str] = None
+ endpoint_url: typing.Optional[str] = None
+ use_sdk_auth: typing.Optional[bool] = None
+ access_key_id_secret: typing.Optional[SecretRef] = None
+ secret_access_key_secret: typing.Optional[SecretRef] = None
+ signature_version: typing.Optional[S3StorageConfigSignatureVersion] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+CreateFilesetRequestStorage = typing_extensions.Annotated[
+ typing.Union[
+ CreateFilesetRequestStorage_Local,
+ CreateFilesetRequestStorage_Ngc,
+ CreateFilesetRequestStorage_Huggingface,
+ CreateFilesetRequestStorage_S3,
+ ],
+ pydantic.Field(discriminator="type"),
+]
diff --git a/sdks/python/guardrails/__init__.py b/sdks/python/guardrails/__init__.py
new file mode 100644
index 0000000000..54fa462621
--- /dev/null
+++ b/sdks/python/guardrails/__init__.py
@@ -0,0 +1,64 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import (
+ GuardrailCheckRequestFunctionCall,
+ GuardrailCheckRequestMessagesItem,
+ GuardrailCheckRequestMessagesItem_Assistant,
+ GuardrailCheckRequestMessagesItem_Function,
+ GuardrailCheckRequestMessagesItem_System,
+ GuardrailCheckRequestMessagesItem_Tool,
+ GuardrailCheckRequestMessagesItem_User,
+ GuardrailCheckRequestStop,
+ GuardrailCheckRequestToolChoice,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "GuardrailCheckRequestFunctionCall": ".types",
+ "GuardrailCheckRequestMessagesItem": ".types",
+ "GuardrailCheckRequestMessagesItem_Assistant": ".types",
+ "GuardrailCheckRequestMessagesItem_Function": ".types",
+ "GuardrailCheckRequestMessagesItem_System": ".types",
+ "GuardrailCheckRequestMessagesItem_Tool": ".types",
+ "GuardrailCheckRequestMessagesItem_User": ".types",
+ "GuardrailCheckRequestStop": ".types",
+ "GuardrailCheckRequestToolChoice": ".types",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GuardrailCheckRequestFunctionCall",
+ "GuardrailCheckRequestMessagesItem",
+ "GuardrailCheckRequestMessagesItem_Assistant",
+ "GuardrailCheckRequestMessagesItem_Function",
+ "GuardrailCheckRequestMessagesItem_System",
+ "GuardrailCheckRequestMessagesItem_Tool",
+ "GuardrailCheckRequestMessagesItem_User",
+ "GuardrailCheckRequestStop",
+ "GuardrailCheckRequestToolChoice",
+]
diff --git a/sdks/python/guardrails/client.py b/sdks/python/guardrails/client.py
new file mode 100644
index 0000000000..2490840caf
--- /dev/null
+++ b/sdks/python/guardrails/client.py
@@ -0,0 +1,891 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.delete_response import DeleteResponse
+from ..types.generic_sort_field import GenericSortField
+from ..types.guardrail_check_response import GuardrailCheckResponse
+from ..types.guardrail_config import GuardrailConfig
+from ..types.guardrail_config_filter import GuardrailConfigFilter
+from ..types.guardrail_configs_page import GuardrailConfigsPage
+from ..types.guardrails_data_input import GuardrailsDataInput
+from .raw_client import AsyncRawGuardrailsClient, RawGuardrailsClient
+from .types.guardrail_check_request_function_call import GuardrailCheckRequestFunctionCall
+from .types.guardrail_check_request_messages_item import GuardrailCheckRequestMessagesItem
+from .types.guardrail_check_request_stop import GuardrailCheckRequestStop
+from .types.guardrail_check_request_tool_choice import GuardrailCheckRequestToolChoice
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class GuardrailsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawGuardrailsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawGuardrailsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawGuardrailsClient
+ """
+ return self._raw_client
+
+ def check(
+ self,
+ workspace: str,
+ *,
+ model: str,
+ messages: typing.Sequence[GuardrailCheckRequestMessagesItem],
+ response_format: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ max_tokens: typing.Optional[int] = OMIT,
+ n: typing.Optional[int] = OMIT,
+ stream: typing.Optional[bool] = OMIT,
+ temperature: typing.Optional[float] = OMIT,
+ top_p: typing.Optional[float] = OMIT,
+ stop: typing.Optional[GuardrailCheckRequestStop] = OMIT,
+ frequency_penalty: typing.Optional[float] = OMIT,
+ presence_penalty: typing.Optional[float] = OMIT,
+ function_call: typing.Optional[GuardrailCheckRequestFunctionCall] = OMIT,
+ seed: typing.Optional[int] = OMIT,
+ logit_bias: typing.Optional[typing.Dict[str, float]] = OMIT,
+ top_logprobs: typing.Optional[int] = OMIT,
+ logprobs: typing.Optional[bool] = OMIT,
+ tool_choice: typing.Optional[GuardrailCheckRequestToolChoice] = OMIT,
+ user: typing.Optional[str] = OMIT,
+ tools: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
+ ignore_eos: typing.Optional[bool] = OMIT,
+ reasoning_effort: typing.Optional[str] = OMIT,
+ max_completion_tokens: typing.Optional[int] = OMIT,
+ stream_options: typing.Optional[typing.Dict[str, bool]] = OMIT,
+ vision: typing.Optional[bool] = OMIT,
+ guardrails: typing.Optional[GuardrailsDataInput] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailCheckResponse:
+ """
+ Chat completion for the provided conversation.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model : str
+ The model to use for completion. Must be one of the available models.
+
+ messages : typing.Sequence[GuardrailCheckRequestMessagesItem]
+ A list of messages comprising the conversation so far
+
+ response_format : typing.Optional[typing.Dict[str, typing.Any]]
+ Format of the response. Use {'type': 'json_object'} for JSON mode or {'type': 'json_schema', 'json_schema': {...}} for structured outputs.
+
+ max_tokens : typing.Optional[int]
+ The maximum number of tokens that can be generated in the chat completion.
+
+ n : typing.Optional[int]
+ How many chat completion choices to generate for each input message.
+
+ stream : typing.Optional[bool]
+ If set, partial message deltas will be sent, like in ChatGPT.
+
+ temperature : typing.Optional[float]
+ What sampling temperature to use, between 0 and 2.
+
+ top_p : typing.Optional[float]
+ An alternative to sampling with temperature, called nucleus sampling.
+
+ stop : typing.Optional[GuardrailCheckRequestStop]
+ Up to 4 sequences where the API will stop generating further tokens.
+
+ frequency_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on their existing frequency in the text.
+
+ presence_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on whether they appear in the text so far.
+
+ function_call : typing.Optional[GuardrailCheckRequestFunctionCall]
+ Deprecated in favor of tool_choice. 'none' means the model will not call a function and instead generates a message. 'auto' means the model can pick between generating a message or calling a function. Specifying a particular function via {'name': 'my_function'} forces the model to call that function.
+
+ seed : typing.Optional[int]
+ If specified, attempts to sample deterministically.
+
+ logit_bias : typing.Optional[typing.Dict[str, float]]
+ Modify the likelihood of specified tokens appearing in the completion. Maps token IDs (as strings) to bias values from -100 to 100.
+
+ top_logprobs : typing.Optional[int]
+ The number of most likely tokens to return at each token position.
+
+ logprobs : typing.Optional[bool]
+ Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message
+
+ tool_choice : typing.Optional[GuardrailCheckRequestToolChoice]
+ Controls which (if any) tool is called by the model. 'none' means no tool is called, 'auto' lets the model decide, 'required' forces a tool call.
+
+ user : typing.Optional[str]
+ A unique identifier representing your end-user, used by some providers for abuse monitoring.
+
+ tools : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
+ A list of tools the model may call. Each tool is an object with a 'type' field and a 'function' definition.
+
+ ignore_eos : typing.Optional[bool]
+ Ignore the eos when running
+
+ reasoning_effort : typing.Optional[str]
+ Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
+
+ max_completion_tokens : typing.Optional[int]
+ An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens. Preferred over max_tokens for reasoning models.
+
+ stream_options : typing.Optional[typing.Dict[str, bool]]
+ Options for streaming response. Only set this when stream=True. Supports include_usage to receive token usage in the final stream chunk.
+
+ vision : typing.Optional[bool]
+ Whether this is a vision-capable request with image inputs.
+
+ guardrails : typing.Optional[GuardrailsDataInput]
+ Guardrails specific options for the request.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailCheckResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+ from nvidia.guardrails import GuardrailCheckRequestMessagesItem_System
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.check(
+ workspace="workspace",
+ model="model",
+ messages=[
+ GuardrailCheckRequestMessagesItem_System(
+ content="content",
+ )
+ ],
+ )
+ """
+ _response = self._raw_client.check(
+ workspace,
+ model=model,
+ messages=messages,
+ response_format=response_format,
+ max_tokens=max_tokens,
+ n=n,
+ stream=stream,
+ temperature=temperature,
+ top_p=top_p,
+ stop=stop,
+ frequency_penalty=frequency_penalty,
+ presence_penalty=presence_penalty,
+ function_call=function_call,
+ seed=seed,
+ logit_bias=logit_bias,
+ top_logprobs=top_logprobs,
+ logprobs=logprobs,
+ tool_choice=tool_choice,
+ user=user,
+ tools=tools,
+ ignore_eos=ignore_eos,
+ reasoning_effort=reasoning_effort,
+ max_completion_tokens=max_completion_tokens,
+ stream_options=stream_options,
+ vision=vision,
+ guardrails=guardrails,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def list_guardrail_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[GuardrailConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfigsPage:
+ """
+ List available guardrail configs.
+
+ Lists guardrail configs for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[GuardrailConfigFilter]
+ Filter guardrail configs by name, description, project, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfigsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.list_guardrail_configs(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_guardrail_configs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfig:
+ """
+ Create a new guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the guardrail config
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Config created successfully.
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.create_config(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.create_config(
+ workspace, name=name, description=description, data=data, request_options=request_options
+ )
+ return _response.data
+
+ def get_guardrail_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> GuardrailConfig:
+ """
+ Get info about a guardrail configuration.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.get_guardrail_config(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_guardrail_config(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteResponse:
+ """
+ Delete a guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful model deletion.
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.delete_config(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_config(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfig:
+ """
+ Update model metadata. If the request body has an empty field,
+ keep the old value.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.guardrails.update_config(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_config(
+ workspace, name, description=description, data=data, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncGuardrailsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawGuardrailsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawGuardrailsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawGuardrailsClient
+ """
+ return self._raw_client
+
+ async def check(
+ self,
+ workspace: str,
+ *,
+ model: str,
+ messages: typing.Sequence[GuardrailCheckRequestMessagesItem],
+ response_format: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ max_tokens: typing.Optional[int] = OMIT,
+ n: typing.Optional[int] = OMIT,
+ stream: typing.Optional[bool] = OMIT,
+ temperature: typing.Optional[float] = OMIT,
+ top_p: typing.Optional[float] = OMIT,
+ stop: typing.Optional[GuardrailCheckRequestStop] = OMIT,
+ frequency_penalty: typing.Optional[float] = OMIT,
+ presence_penalty: typing.Optional[float] = OMIT,
+ function_call: typing.Optional[GuardrailCheckRequestFunctionCall] = OMIT,
+ seed: typing.Optional[int] = OMIT,
+ logit_bias: typing.Optional[typing.Dict[str, float]] = OMIT,
+ top_logprobs: typing.Optional[int] = OMIT,
+ logprobs: typing.Optional[bool] = OMIT,
+ tool_choice: typing.Optional[GuardrailCheckRequestToolChoice] = OMIT,
+ user: typing.Optional[str] = OMIT,
+ tools: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
+ ignore_eos: typing.Optional[bool] = OMIT,
+ reasoning_effort: typing.Optional[str] = OMIT,
+ max_completion_tokens: typing.Optional[int] = OMIT,
+ stream_options: typing.Optional[typing.Dict[str, bool]] = OMIT,
+ vision: typing.Optional[bool] = OMIT,
+ guardrails: typing.Optional[GuardrailsDataInput] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailCheckResponse:
+ """
+ Chat completion for the provided conversation.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model : str
+ The model to use for completion. Must be one of the available models.
+
+ messages : typing.Sequence[GuardrailCheckRequestMessagesItem]
+ A list of messages comprising the conversation so far
+
+ response_format : typing.Optional[typing.Dict[str, typing.Any]]
+ Format of the response. Use {'type': 'json_object'} for JSON mode or {'type': 'json_schema', 'json_schema': {...}} for structured outputs.
+
+ max_tokens : typing.Optional[int]
+ The maximum number of tokens that can be generated in the chat completion.
+
+ n : typing.Optional[int]
+ How many chat completion choices to generate for each input message.
+
+ stream : typing.Optional[bool]
+ If set, partial message deltas will be sent, like in ChatGPT.
+
+ temperature : typing.Optional[float]
+ What sampling temperature to use, between 0 and 2.
+
+ top_p : typing.Optional[float]
+ An alternative to sampling with temperature, called nucleus sampling.
+
+ stop : typing.Optional[GuardrailCheckRequestStop]
+ Up to 4 sequences where the API will stop generating further tokens.
+
+ frequency_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on their existing frequency in the text.
+
+ presence_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on whether they appear in the text so far.
+
+ function_call : typing.Optional[GuardrailCheckRequestFunctionCall]
+ Deprecated in favor of tool_choice. 'none' means the model will not call a function and instead generates a message. 'auto' means the model can pick between generating a message or calling a function. Specifying a particular function via {'name': 'my_function'} forces the model to call that function.
+
+ seed : typing.Optional[int]
+ If specified, attempts to sample deterministically.
+
+ logit_bias : typing.Optional[typing.Dict[str, float]]
+ Modify the likelihood of specified tokens appearing in the completion. Maps token IDs (as strings) to bias values from -100 to 100.
+
+ top_logprobs : typing.Optional[int]
+ The number of most likely tokens to return at each token position.
+
+ logprobs : typing.Optional[bool]
+ Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message
+
+ tool_choice : typing.Optional[GuardrailCheckRequestToolChoice]
+ Controls which (if any) tool is called by the model. 'none' means no tool is called, 'auto' lets the model decide, 'required' forces a tool call.
+
+ user : typing.Optional[str]
+ A unique identifier representing your end-user, used by some providers for abuse monitoring.
+
+ tools : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
+ A list of tools the model may call. Each tool is an object with a 'type' field and a 'function' definition.
+
+ ignore_eos : typing.Optional[bool]
+ Ignore the eos when running
+
+ reasoning_effort : typing.Optional[str]
+ Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
+
+ max_completion_tokens : typing.Optional[int]
+ An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens. Preferred over max_tokens for reasoning models.
+
+ stream_options : typing.Optional[typing.Dict[str, bool]]
+ Options for streaming response. Only set this when stream=True. Supports include_usage to receive token usage in the final stream chunk.
+
+ vision : typing.Optional[bool]
+ Whether this is a vision-capable request with image inputs.
+
+ guardrails : typing.Optional[GuardrailsDataInput]
+ Guardrails specific options for the request.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailCheckResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+ from nvidia.guardrails import GuardrailCheckRequestMessagesItem_System
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.check(
+ workspace="workspace",
+ model="model",
+ messages=[
+ GuardrailCheckRequestMessagesItem_System(
+ content="content",
+ )
+ ],
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.check(
+ workspace,
+ model=model,
+ messages=messages,
+ response_format=response_format,
+ max_tokens=max_tokens,
+ n=n,
+ stream=stream,
+ temperature=temperature,
+ top_p=top_p,
+ stop=stop,
+ frequency_penalty=frequency_penalty,
+ presence_penalty=presence_penalty,
+ function_call=function_call,
+ seed=seed,
+ logit_bias=logit_bias,
+ top_logprobs=top_logprobs,
+ logprobs=logprobs,
+ tool_choice=tool_choice,
+ user=user,
+ tools=tools,
+ ignore_eos=ignore_eos,
+ reasoning_effort=reasoning_effort,
+ max_completion_tokens=max_completion_tokens,
+ stream_options=stream_options,
+ vision=vision,
+ guardrails=guardrails,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def list_guardrail_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[GuardrailConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfigsPage:
+ """
+ List available guardrail configs.
+
+ Lists guardrail configs for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[GuardrailConfigFilter]
+ Filter guardrail configs by name, description, project, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfigsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.list_guardrail_configs(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_guardrail_configs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfig:
+ """
+ Create a new guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the guardrail config
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Config created successfully.
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.create_config(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_config(
+ workspace, name=name, description=description, data=data, request_options=request_options
+ )
+ return _response.data
+
+ async def get_guardrail_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> GuardrailConfig:
+ """
+ Get info about a guardrail configuration.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.get_guardrail_config(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_guardrail_config(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> DeleteResponse:
+ """
+ Delete a guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful model deletion.
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.delete_config(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_config(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> GuardrailConfig:
+ """
+ Update model metadata. If the request body has an empty field,
+ keep the old value.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ GuardrailConfig
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.guardrails.update_config(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_config(
+ workspace, name, description=description, data=data, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/guardrails/raw_client.py b/sdks/python/guardrails/raw_client.py
new file mode 100644
index 0000000000..ee6890888c
--- /dev/null
+++ b/sdks/python/guardrails/raw_client.py
@@ -0,0 +1,1259 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.bad_request_error import BadRequestError
+from ..errors.conflict_error import ConflictError
+from ..errors.internal_server_error import InternalServerError
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.delete_response import DeleteResponse
+from ..types.generic_sort_field import GenericSortField
+from ..types.guardrail_check_response import GuardrailCheckResponse
+from ..types.guardrail_config import GuardrailConfig
+from ..types.guardrail_config_filter import GuardrailConfigFilter
+from ..types.guardrail_configs_page import GuardrailConfigsPage
+from ..types.guardrails_data_input import GuardrailsDataInput
+from .types.guardrail_check_request_function_call import GuardrailCheckRequestFunctionCall
+from .types.guardrail_check_request_messages_item import GuardrailCheckRequestMessagesItem
+from .types.guardrail_check_request_stop import GuardrailCheckRequestStop
+from .types.guardrail_check_request_tool_choice import GuardrailCheckRequestToolChoice
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawGuardrailsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def check(
+ self,
+ workspace: str,
+ *,
+ model: str,
+ messages: typing.Sequence[GuardrailCheckRequestMessagesItem],
+ response_format: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ max_tokens: typing.Optional[int] = OMIT,
+ n: typing.Optional[int] = OMIT,
+ stream: typing.Optional[bool] = OMIT,
+ temperature: typing.Optional[float] = OMIT,
+ top_p: typing.Optional[float] = OMIT,
+ stop: typing.Optional[GuardrailCheckRequestStop] = OMIT,
+ frequency_penalty: typing.Optional[float] = OMIT,
+ presence_penalty: typing.Optional[float] = OMIT,
+ function_call: typing.Optional[GuardrailCheckRequestFunctionCall] = OMIT,
+ seed: typing.Optional[int] = OMIT,
+ logit_bias: typing.Optional[typing.Dict[str, float]] = OMIT,
+ top_logprobs: typing.Optional[int] = OMIT,
+ logprobs: typing.Optional[bool] = OMIT,
+ tool_choice: typing.Optional[GuardrailCheckRequestToolChoice] = OMIT,
+ user: typing.Optional[str] = OMIT,
+ tools: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
+ ignore_eos: typing.Optional[bool] = OMIT,
+ reasoning_effort: typing.Optional[str] = OMIT,
+ max_completion_tokens: typing.Optional[int] = OMIT,
+ stream_options: typing.Optional[typing.Dict[str, bool]] = OMIT,
+ vision: typing.Optional[bool] = OMIT,
+ guardrails: typing.Optional[GuardrailsDataInput] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GuardrailCheckResponse]:
+ """
+ Chat completion for the provided conversation.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model : str
+ The model to use for completion. Must be one of the available models.
+
+ messages : typing.Sequence[GuardrailCheckRequestMessagesItem]
+ A list of messages comprising the conversation so far
+
+ response_format : typing.Optional[typing.Dict[str, typing.Any]]
+ Format of the response. Use {'type': 'json_object'} for JSON mode or {'type': 'json_schema', 'json_schema': {...}} for structured outputs.
+
+ max_tokens : typing.Optional[int]
+ The maximum number of tokens that can be generated in the chat completion.
+
+ n : typing.Optional[int]
+ How many chat completion choices to generate for each input message.
+
+ stream : typing.Optional[bool]
+ If set, partial message deltas will be sent, like in ChatGPT.
+
+ temperature : typing.Optional[float]
+ What sampling temperature to use, between 0 and 2.
+
+ top_p : typing.Optional[float]
+ An alternative to sampling with temperature, called nucleus sampling.
+
+ stop : typing.Optional[GuardrailCheckRequestStop]
+ Up to 4 sequences where the API will stop generating further tokens.
+
+ frequency_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on their existing frequency in the text.
+
+ presence_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on whether they appear in the text so far.
+
+ function_call : typing.Optional[GuardrailCheckRequestFunctionCall]
+ Deprecated in favor of tool_choice. 'none' means the model will not call a function and instead generates a message. 'auto' means the model can pick between generating a message or calling a function. Specifying a particular function via {'name': 'my_function'} forces the model to call that function.
+
+ seed : typing.Optional[int]
+ If specified, attempts to sample deterministically.
+
+ logit_bias : typing.Optional[typing.Dict[str, float]]
+ Modify the likelihood of specified tokens appearing in the completion. Maps token IDs (as strings) to bias values from -100 to 100.
+
+ top_logprobs : typing.Optional[int]
+ The number of most likely tokens to return at each token position.
+
+ logprobs : typing.Optional[bool]
+ Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message
+
+ tool_choice : typing.Optional[GuardrailCheckRequestToolChoice]
+ Controls which (if any) tool is called by the model. 'none' means no tool is called, 'auto' lets the model decide, 'required' forces a tool call.
+
+ user : typing.Optional[str]
+ A unique identifier representing your end-user, used by some providers for abuse monitoring.
+
+ tools : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
+ A list of tools the model may call. Each tool is an object with a 'type' field and a 'function' definition.
+
+ ignore_eos : typing.Optional[bool]
+ Ignore the eos when running
+
+ reasoning_effort : typing.Optional[str]
+ Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
+
+ max_completion_tokens : typing.Optional[int]
+ An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens. Preferred over max_tokens for reasoning models.
+
+ stream_options : typing.Optional[typing.Dict[str, bool]]
+ Options for streaming response. Only set this when stream=True. Supports include_usage to receive token usage in the final stream chunk.
+
+ vision : typing.Optional[bool]
+ Whether this is a vision-capable request with image inputs.
+
+ guardrails : typing.Optional[GuardrailsDataInput]
+ Guardrails specific options for the request.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GuardrailCheckResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/checks",
+ method="POST",
+ json={
+ "model": model,
+ "response_format": response_format,
+ "max_tokens": max_tokens,
+ "n": n,
+ "stream": stream,
+ "temperature": temperature,
+ "top_p": top_p,
+ "stop": convert_and_respect_annotation_metadata(
+ object_=stop, annotation=GuardrailCheckRequestStop, direction="write"
+ ),
+ "frequency_penalty": frequency_penalty,
+ "presence_penalty": presence_penalty,
+ "function_call": convert_and_respect_annotation_metadata(
+ object_=function_call, annotation=GuardrailCheckRequestFunctionCall, direction="write"
+ ),
+ "seed": seed,
+ "logit_bias": logit_bias,
+ "top_logprobs": top_logprobs,
+ "logprobs": logprobs,
+ "tool_choice": convert_and_respect_annotation_metadata(
+ object_=tool_choice, annotation=GuardrailCheckRequestToolChoice, direction="write"
+ ),
+ "user": user,
+ "tools": tools,
+ "ignore_eos": ignore_eos,
+ "reasoning_effort": reasoning_effort,
+ "max_completion_tokens": max_completion_tokens,
+ "stream_options": stream_options,
+ "messages": convert_and_respect_annotation_metadata(
+ object_=messages, annotation=typing.Sequence[GuardrailCheckRequestMessagesItem], direction="write"
+ ),
+ "vision": vision,
+ "guardrails": convert_and_respect_annotation_metadata(
+ object_=guardrails, annotation=GuardrailsDataInput, direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailCheckResponse,
+ parse_obj_as(
+ type_=GuardrailCheckResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_guardrail_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[GuardrailConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GuardrailConfigsPage]:
+ """
+ List available guardrail configs.
+
+ Lists guardrail configs for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[GuardrailConfigFilter]
+ Filter guardrail configs by name, description, project, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GuardrailConfigsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=GuardrailConfigFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfigsPage,
+ parse_obj_as(
+ type_=GuardrailConfigsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GuardrailConfig]:
+ """
+ Create a new guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the guardrail config
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GuardrailConfig]
+ Config created successfully.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_guardrail_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[GuardrailConfig]:
+ """
+ Get info about a guardrail configuration.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GuardrailConfig]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Delete a guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful model deletion.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[GuardrailConfig]:
+ """
+ Update model metadata. If the request body has an empty field,
+ keep the old value.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[GuardrailConfig]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawGuardrailsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def check(
+ self,
+ workspace: str,
+ *,
+ model: str,
+ messages: typing.Sequence[GuardrailCheckRequestMessagesItem],
+ response_format: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ max_tokens: typing.Optional[int] = OMIT,
+ n: typing.Optional[int] = OMIT,
+ stream: typing.Optional[bool] = OMIT,
+ temperature: typing.Optional[float] = OMIT,
+ top_p: typing.Optional[float] = OMIT,
+ stop: typing.Optional[GuardrailCheckRequestStop] = OMIT,
+ frequency_penalty: typing.Optional[float] = OMIT,
+ presence_penalty: typing.Optional[float] = OMIT,
+ function_call: typing.Optional[GuardrailCheckRequestFunctionCall] = OMIT,
+ seed: typing.Optional[int] = OMIT,
+ logit_bias: typing.Optional[typing.Dict[str, float]] = OMIT,
+ top_logprobs: typing.Optional[int] = OMIT,
+ logprobs: typing.Optional[bool] = OMIT,
+ tool_choice: typing.Optional[GuardrailCheckRequestToolChoice] = OMIT,
+ user: typing.Optional[str] = OMIT,
+ tools: typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]] = OMIT,
+ ignore_eos: typing.Optional[bool] = OMIT,
+ reasoning_effort: typing.Optional[str] = OMIT,
+ max_completion_tokens: typing.Optional[int] = OMIT,
+ stream_options: typing.Optional[typing.Dict[str, bool]] = OMIT,
+ vision: typing.Optional[bool] = OMIT,
+ guardrails: typing.Optional[GuardrailsDataInput] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GuardrailCheckResponse]:
+ """
+ Chat completion for the provided conversation.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model : str
+ The model to use for completion. Must be one of the available models.
+
+ messages : typing.Sequence[GuardrailCheckRequestMessagesItem]
+ A list of messages comprising the conversation so far
+
+ response_format : typing.Optional[typing.Dict[str, typing.Any]]
+ Format of the response. Use {'type': 'json_object'} for JSON mode or {'type': 'json_schema', 'json_schema': {...}} for structured outputs.
+
+ max_tokens : typing.Optional[int]
+ The maximum number of tokens that can be generated in the chat completion.
+
+ n : typing.Optional[int]
+ How many chat completion choices to generate for each input message.
+
+ stream : typing.Optional[bool]
+ If set, partial message deltas will be sent, like in ChatGPT.
+
+ temperature : typing.Optional[float]
+ What sampling temperature to use, between 0 and 2.
+
+ top_p : typing.Optional[float]
+ An alternative to sampling with temperature, called nucleus sampling.
+
+ stop : typing.Optional[GuardrailCheckRequestStop]
+ Up to 4 sequences where the API will stop generating further tokens.
+
+ frequency_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on their existing frequency in the text.
+
+ presence_penalty : typing.Optional[float]
+ Positive values penalize new tokens based on whether they appear in the text so far.
+
+ function_call : typing.Optional[GuardrailCheckRequestFunctionCall]
+ Deprecated in favor of tool_choice. 'none' means the model will not call a function and instead generates a message. 'auto' means the model can pick between generating a message or calling a function. Specifying a particular function via {'name': 'my_function'} forces the model to call that function.
+
+ seed : typing.Optional[int]
+ If specified, attempts to sample deterministically.
+
+ logit_bias : typing.Optional[typing.Dict[str, float]]
+ Modify the likelihood of specified tokens appearing in the completion. Maps token IDs (as strings) to bias values from -100 to 100.
+
+ top_logprobs : typing.Optional[int]
+ The number of most likely tokens to return at each token position.
+
+ logprobs : typing.Optional[bool]
+ Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message
+
+ tool_choice : typing.Optional[GuardrailCheckRequestToolChoice]
+ Controls which (if any) tool is called by the model. 'none' means no tool is called, 'auto' lets the model decide, 'required' forces a tool call.
+
+ user : typing.Optional[str]
+ A unique identifier representing your end-user, used by some providers for abuse monitoring.
+
+ tools : typing.Optional[typing.Sequence[typing.Dict[str, typing.Any]]]
+ A list of tools the model may call. Each tool is an object with a 'type' field and a 'function' definition.
+
+ ignore_eos : typing.Optional[bool]
+ Ignore the eos when running
+
+ reasoning_effort : typing.Optional[str]
+ Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
+
+ max_completion_tokens : typing.Optional[int]
+ An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens. Preferred over max_tokens for reasoning models.
+
+ stream_options : typing.Optional[typing.Dict[str, bool]]
+ Options for streaming response. Only set this when stream=True. Supports include_usage to receive token usage in the final stream chunk.
+
+ vision : typing.Optional[bool]
+ Whether this is a vision-capable request with image inputs.
+
+ guardrails : typing.Optional[GuardrailsDataInput]
+ Guardrails specific options for the request.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GuardrailCheckResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/checks",
+ method="POST",
+ json={
+ "model": model,
+ "response_format": response_format,
+ "max_tokens": max_tokens,
+ "n": n,
+ "stream": stream,
+ "temperature": temperature,
+ "top_p": top_p,
+ "stop": convert_and_respect_annotation_metadata(
+ object_=stop, annotation=GuardrailCheckRequestStop, direction="write"
+ ),
+ "frequency_penalty": frequency_penalty,
+ "presence_penalty": presence_penalty,
+ "function_call": convert_and_respect_annotation_metadata(
+ object_=function_call, annotation=GuardrailCheckRequestFunctionCall, direction="write"
+ ),
+ "seed": seed,
+ "logit_bias": logit_bias,
+ "top_logprobs": top_logprobs,
+ "logprobs": logprobs,
+ "tool_choice": convert_and_respect_annotation_metadata(
+ object_=tool_choice, annotation=GuardrailCheckRequestToolChoice, direction="write"
+ ),
+ "user": user,
+ "tools": tools,
+ "ignore_eos": ignore_eos,
+ "reasoning_effort": reasoning_effort,
+ "max_completion_tokens": max_completion_tokens,
+ "stream_options": stream_options,
+ "messages": convert_and_respect_annotation_metadata(
+ object_=messages, annotation=typing.Sequence[GuardrailCheckRequestMessagesItem], direction="write"
+ ),
+ "vision": vision,
+ "guardrails": convert_and_respect_annotation_metadata(
+ object_=guardrails, annotation=GuardrailsDataInput, direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailCheckResponse,
+ parse_obj_as(
+ type_=GuardrailCheckResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_guardrail_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[GenericSortField] = None,
+ filter: typing.Optional[GuardrailConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GuardrailConfigsPage]:
+ """
+ List available guardrail configs.
+
+ Lists guardrail configs for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[GenericSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[GuardrailConfigFilter]
+ Filter guardrail configs by name, description, project, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GuardrailConfigsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=GuardrailConfigFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfigsPage,
+ parse_obj_as(
+ type_=GuardrailConfigsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GuardrailConfig]:
+ """
+ Create a new guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the guardrail config
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GuardrailConfig]
+ Config created successfully.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_guardrail_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[GuardrailConfig]:
+ """
+ Get info about a guardrail configuration.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GuardrailConfig]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Delete a guardrail config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful model deletion.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[GuardrailConfig]:
+ """
+ Update model metadata. If the request body has an empty field,
+ keep the old value.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ Description of the guardrail config
+
+ data : typing.Optional[typing.Dict[str, typing.Any]]
+ Guardrail configuration data
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[GuardrailConfig]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/guardrails/v2/workspaces/{encode_path_param(workspace)}/configs/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "data": data,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ GuardrailConfig,
+ parse_obj_as(
+ type_=GuardrailConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/guardrails/types/__init__.py b/sdks/python/guardrails/types/__init__.py
new file mode 100644
index 0000000000..37092c0fd6
--- /dev/null
+++ b/sdks/python/guardrails/types/__init__.py
@@ -0,0 +1,64 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .guardrail_check_request_function_call import GuardrailCheckRequestFunctionCall
+ from .guardrail_check_request_messages_item import (
+ GuardrailCheckRequestMessagesItem,
+ GuardrailCheckRequestMessagesItem_Assistant,
+ GuardrailCheckRequestMessagesItem_Function,
+ GuardrailCheckRequestMessagesItem_System,
+ GuardrailCheckRequestMessagesItem_Tool,
+ GuardrailCheckRequestMessagesItem_User,
+ )
+ from .guardrail_check_request_stop import GuardrailCheckRequestStop
+ from .guardrail_check_request_tool_choice import GuardrailCheckRequestToolChoice
+_dynamic_imports: typing.Dict[str, str] = {
+ "GuardrailCheckRequestFunctionCall": ".guardrail_check_request_function_call",
+ "GuardrailCheckRequestMessagesItem": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestMessagesItem_Assistant": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestMessagesItem_Function": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestMessagesItem_System": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestMessagesItem_Tool": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestMessagesItem_User": ".guardrail_check_request_messages_item",
+ "GuardrailCheckRequestStop": ".guardrail_check_request_stop",
+ "GuardrailCheckRequestToolChoice": ".guardrail_check_request_tool_choice",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GuardrailCheckRequestFunctionCall",
+ "GuardrailCheckRequestMessagesItem",
+ "GuardrailCheckRequestMessagesItem_Assistant",
+ "GuardrailCheckRequestMessagesItem_Function",
+ "GuardrailCheckRequestMessagesItem_System",
+ "GuardrailCheckRequestMessagesItem_Tool",
+ "GuardrailCheckRequestMessagesItem_User",
+ "GuardrailCheckRequestStop",
+ "GuardrailCheckRequestToolChoice",
+]
diff --git a/sdks/python/guardrails/types/guardrail_check_request_function_call.py b/sdks/python/guardrails/types/guardrail_check_request_function_call.py
new file mode 100644
index 0000000000..89ac25416a
--- /dev/null
+++ b/sdks/python/guardrails/types/guardrail_check_request_function_call.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GuardrailCheckRequestFunctionCall = typing.Union[str, typing.Dict[str, typing.Any]]
diff --git a/sdks/python/guardrails/types/guardrail_check_request_messages_item.py b/sdks/python/guardrails/types/guardrail_check_request_messages_item.py
new file mode 100644
index 0000000000..a264b97e1b
--- /dev/null
+++ b/sdks/python/guardrails/types/guardrail_check_request_messages_item.py
@@ -0,0 +1,101 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ...types.chat_completion_message_tool_call_param import ChatCompletionMessageToolCallParam
+from ...types.chat_completion_user_message_param_content import ChatCompletionUserMessageParamContent
+from ...types.function_call import FunctionCall
+
+
+class GuardrailCheckRequestMessagesItem_System(UniversalBaseModel):
+ role: typing.Literal["system"] = "system"
+ content: str
+ name: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GuardrailCheckRequestMessagesItem_User(UniversalBaseModel):
+ role: typing.Literal["user"] = "user"
+ content: ChatCompletionUserMessageParamContent
+ name: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GuardrailCheckRequestMessagesItem_Assistant(UniversalBaseModel):
+ role: typing.Literal["assistant"] = "assistant"
+ content: typing.Optional[str] = None
+ function_call: typing.Optional[FunctionCall] = None
+ name: typing.Optional[str] = None
+ tool_calls: typing.Optional[typing.List[ChatCompletionMessageToolCallParam]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GuardrailCheckRequestMessagesItem_Tool(UniversalBaseModel):
+ role: typing.Literal["tool"] = "tool"
+ content: str
+ tool_call_id: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GuardrailCheckRequestMessagesItem_Function(UniversalBaseModel):
+ role: typing.Literal["function"] = "function"
+ content: str
+ name: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+GuardrailCheckRequestMessagesItem = typing_extensions.Annotated[
+ typing.Union[
+ GuardrailCheckRequestMessagesItem_System,
+ GuardrailCheckRequestMessagesItem_User,
+ GuardrailCheckRequestMessagesItem_Assistant,
+ GuardrailCheckRequestMessagesItem_Tool,
+ GuardrailCheckRequestMessagesItem_Function,
+ ],
+ pydantic.Field(discriminator="role"),
+]
diff --git a/sdks/python/guardrails/types/guardrail_check_request_stop.py b/sdks/python/guardrails/types/guardrail_check_request_stop.py
new file mode 100644
index 0000000000..70abcaeef0
--- /dev/null
+++ b/sdks/python/guardrails/types/guardrail_check_request_stop.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GuardrailCheckRequestStop = typing.Union[str, typing.List[str]]
diff --git a/sdks/python/guardrails/types/guardrail_check_request_tool_choice.py b/sdks/python/guardrails/types/guardrail_check_request_tool_choice.py
new file mode 100644
index 0000000000..66dc40329b
--- /dev/null
+++ b/sdks/python/guardrails/types/guardrail_check_request_tool_choice.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GuardrailCheckRequestToolChoice = typing.Union[str, typing.Dict[str, typing.Any]]
diff --git a/sdks/python/iam/__init__.py b/sdks/python/iam/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/iam/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/iam/client.py b/sdks/python/iam/client.py
new file mode 100644
index 0000000000..e61947a887
--- /dev/null
+++ b/sdks/python/iam/client.py
@@ -0,0 +1,428 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.delete_response import DeleteResponse
+from ..types.role_binding import RoleBinding
+from ..types.role_binding_filter import RoleBindingFilter
+from ..types.role_bindings_page import RoleBindingsPage
+from .raw_client import AsyncRawIamClient, RawIamClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class IamClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawIamClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawIamClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawIamClient
+ """
+ return self._raw_client
+
+ def list_role_bindings(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[RoleBindingFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> RoleBindingsPage:
+ """
+ List all role bindings (Platform Admin only)
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[RoleBindingFilter]
+ Filter role bindings by principal, workspace, role, granted_by, is_active, granted_at, and revoked_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBindingsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.iam.list_role_bindings()
+ """
+ _response = self._raw_client.list_role_bindings(
+ page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_role_binding(
+ self,
+ *,
+ principal: str,
+ role: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ workspace: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> RoleBinding:
+ """
+ Create a new role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ role : str
+ The role name (e.g., 'Viewer', 'Editor', 'Admin')
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ workspace : typing.Optional[str]
+ The workspace this binding applies to. None for platform-level roles.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBinding
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.iam.create_role_binding(
+ principal="principal",
+ role="role",
+ )
+ """
+ _response = self._raw_client.create_role_binding(
+ principal=principal,
+ role=role,
+ wait_role_propagation=wait_role_propagation,
+ workspace=workspace,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_role_binding(self, name: str, *, request_options: typing.Optional[RequestOptions] = None) -> RoleBinding:
+ """
+ Get a specific role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBinding
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.iam.get_role_binding(
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_role_binding(name, request_options=request_options)
+ return _response.data
+
+ def revoke_role_binding(
+ self,
+ name: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Revoke a role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.iam.revoke_role_binding(
+ name="name",
+ )
+ """
+ _response = self._raw_client.revoke_role_binding(
+ name, wait_role_propagation=wait_role_propagation, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncIamClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawIamClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawIamClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawIamClient
+ """
+ return self._raw_client
+
+ async def list_role_bindings(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[RoleBindingFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> RoleBindingsPage:
+ """
+ List all role bindings (Platform Admin only)
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[RoleBindingFilter]
+ Filter role bindings by principal, workspace, role, granted_by, is_active, granted_at, and revoked_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBindingsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.iam.list_role_bindings()
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_role_bindings(
+ page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_role_binding(
+ self,
+ *,
+ principal: str,
+ role: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ workspace: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> RoleBinding:
+ """
+ Create a new role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ role : str
+ The role name (e.g., 'Viewer', 'Editor', 'Admin')
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ workspace : typing.Optional[str]
+ The workspace this binding applies to. None for platform-level roles.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBinding
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.iam.create_role_binding(
+ principal="principal",
+ role="role",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_role_binding(
+ principal=principal,
+ role=role,
+ wait_role_propagation=wait_role_propagation,
+ workspace=workspace,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_role_binding(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> RoleBinding:
+ """
+ Get a specific role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ RoleBinding
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.iam.get_role_binding(
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_role_binding(name, request_options=request_options)
+ return _response.data
+
+ async def revoke_role_binding(
+ self,
+ name: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> DeleteResponse:
+ """
+ Revoke a role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ DeleteResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.iam.revoke_role_binding(
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.revoke_role_binding(
+ name, wait_role_propagation=wait_role_propagation, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/iam/raw_client.py b/sdks/python/iam/raw_client.py
new file mode 100644
index 0000000000..57e8d69144
--- /dev/null
+++ b/sdks/python/iam/raw_client.py
@@ -0,0 +1,580 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.delete_response import DeleteResponse
+from ..types.role_binding import RoleBinding
+from ..types.role_binding_filter import RoleBindingFilter
+from ..types.role_bindings_page import RoleBindingsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawIamClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_role_bindings(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[RoleBindingFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[RoleBindingsPage]:
+ """
+ List all role bindings (Platform Admin only)
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[RoleBindingFilter]
+ Filter role bindings by principal, workspace, role, granted_by, is_active, granted_at, and revoked_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[RoleBindingsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/auth/v2/iam/role-bindings",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=RoleBindingFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBindingsPage,
+ parse_obj_as(
+ type_=RoleBindingsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_role_binding(
+ self,
+ *,
+ principal: str,
+ role: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ workspace: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[RoleBinding]:
+ """
+ Create a new role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ role : str
+ The role name (e.g., 'Viewer', 'Editor', 'Admin')
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ workspace : typing.Optional[str]
+ The workspace this binding applies to. None for platform-level roles.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[RoleBinding]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/auth/v2/iam/role-bindings",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "principal": principal,
+ "workspace": workspace,
+ "role": role,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBinding,
+ parse_obj_as(
+ type_=RoleBinding, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_role_binding(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[RoleBinding]:
+ """
+ Get a specific role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[RoleBinding]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/auth/v2/iam/role-bindings/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBinding,
+ parse_obj_as(
+ type_=RoleBinding, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def revoke_role_binding(
+ self,
+ name: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[DeleteResponse]:
+ """
+ Revoke a role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/auth/v2/iam/role-bindings/{encode_path_param(name)}",
+ method="DELETE",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawIamClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_role_bindings(
+ self,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[RoleBindingFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[RoleBindingsPage]:
+ """
+ List all role bindings (Platform Admin only)
+
+ Parameters
+ ----------
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[RoleBindingFilter]
+ Filter role bindings by principal, workspace, role, granted_by, is_active, granted_at, and revoked_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[RoleBindingsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/auth/v2/iam/role-bindings",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=RoleBindingFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBindingsPage,
+ parse_obj_as(
+ type_=RoleBindingsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_role_binding(
+ self,
+ *,
+ principal: str,
+ role: str,
+ wait_role_propagation: typing.Optional[bool] = None,
+ workspace: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[RoleBinding]:
+ """
+ Create a new role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ principal : str
+ The principal identifier (email, user ID, or group ID)
+
+ role : str
+ The role name (e.g., 'Viewer', 'Editor', 'Admin')
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ workspace : typing.Optional[str]
+ The workspace this binding applies to. None for platform-level roles.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[RoleBinding]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/auth/v2/iam/role-bindings",
+ method="POST",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ json={
+ "principal": principal,
+ "workspace": workspace,
+ "role": role,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBinding,
+ parse_obj_as(
+ type_=RoleBinding, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_role_binding(
+ self, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[RoleBinding]:
+ """
+ Get a specific role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[RoleBinding]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/auth/v2/iam/role-bindings/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ RoleBinding,
+ parse_obj_as(
+ type_=RoleBinding, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def revoke_role_binding(
+ self,
+ name: str,
+ *,
+ wait_role_propagation: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[DeleteResponse]:
+ """
+ Revoke a role binding (Platform Admin only)
+
+ Parameters
+ ----------
+ name : str
+
+ wait_role_propagation : typing.Optional[bool]
+ If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[DeleteResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/auth/v2/iam/role-bindings/{encode_path_param(name)}",
+ method="DELETE",
+ params={
+ "wait_role_propagation": wait_role_propagation,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ DeleteResponse,
+ parse_obj_as(
+ type_=DeleteResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/inference_gateway/__init__.py b/sdks/python/inference_gateway/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/inference_gateway/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/inference_gateway/client.py b/sdks/python/inference_gateway/client.py
new file mode 100644
index 0000000000..7d83360a00
--- /dev/null
+++ b/sdks/python/inference_gateway/client.py
@@ -0,0 +1,1890 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.open_ai_list_models_resp import OpenAiListModelsResp
+from ..types.open_ai_model_resp import OpenAiModelResp
+from .raw_client import AsyncRawInferenceGatewayClient, RawInferenceGatewayClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class InferenceGatewayClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawInferenceGatewayClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawInferenceGatewayClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawInferenceGatewayClient
+ """
+ return self._raw_client
+
+ def gateway_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to model entity inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.gateway_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.gateway_proxy_get(workspace, name, trailing_uri, request_options=request_options)
+ return _response.data
+
+ def gateway_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to model entity inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.gateway_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.gateway_proxy_post(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def gateway_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to model entity inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.gateway_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.gateway_proxy_put(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def gateway_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to model entity inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.gateway_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.gateway_proxy_delete(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ def gateway_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to model entity inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.gateway_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.gateway_proxy_patch(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def openai_proxy_list_models(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OpenAiListModelsResp:
+ """
+ This endpoint aggregates models from all model entities and returns them
+ in OpenAI's list models format. Each model ID is the model entity identifier
+ in format workspace/model_entity_name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OpenAiListModelsResp
+ List models request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_list_models(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.openai_proxy_list_models(workspace, request_options=request_options)
+ return _response.data
+
+ def openai_proxy_get_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OpenAiModelResp:
+ """
+ Retrieve information about a specific OpenAI-compatible model.
+ Workspace is always taken from the URL path; name may be model_entity_name
+ or workspace/model_entity_name (workspace prefix is ignored).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OpenAiModelResp
+ Get model request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_get_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.openai_proxy_get_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ def openai_proxy_get(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_get(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.openai_proxy_get(workspace, trailing_uri, request_options=request_options)
+ return _response.data
+
+ def openai_proxy_post(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_post(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.openai_proxy_post(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def openai_proxy_put(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_put(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.openai_proxy_put(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def openai_proxy_delete(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_delete(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.openai_proxy_delete(workspace, trailing_uri, request_options=request_options)
+ return _response.data
+
+ def openai_proxy_patch(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.openai_proxy_patch(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.openai_proxy_patch(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def provider_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to provider inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.provider_proxy_get(workspace, name, trailing_uri, request_options=request_options)
+ return _response.data
+
+ def provider_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to provider inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.provider_proxy_post(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def provider_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to provider inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.provider_proxy_put(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def provider_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to provider inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+ """
+ _response = self._raw_client.provider_proxy_delete(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ def provider_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to provider inference endpoint
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.provider_proxy_patch(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def provider_ready(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Check if a model provider is registered in the gateway's cache.
+
+ This is a lightweight endpoint that only checks the gateway's internal state,
+ without making any requests to the actual provider backend. Use this to verify
+ the gateway is ready to route requests to a provider after deployment.
+
+ Returns:
+ 200 OK with provider info if the provider is registered
+ 404 Not Found if the provider is not yet in the gateway's cache
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Check if the gateway can route to a provider
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.inference_gateway.provider_ready(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.provider_ready(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncInferenceGatewayClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawInferenceGatewayClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawInferenceGatewayClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawInferenceGatewayClient
+ """
+ return self._raw_client
+
+ async def gateway_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to model entity inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.gateway_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.gateway_proxy_get(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ async def gateway_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to model entity inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.gateway_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.gateway_proxy_post(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def gateway_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to model entity inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.gateway_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.gateway_proxy_put(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def gateway_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to model entity inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.gateway_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.gateway_proxy_delete(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ async def gateway_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to model entity inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.gateway_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.gateway_proxy_patch(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def openai_proxy_list_models(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OpenAiListModelsResp:
+ """
+ This endpoint aggregates models from all model entities and returns them
+ in OpenAI's list models format. Each model ID is the model entity identifier
+ in format workspace/model_entity_name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OpenAiListModelsResp
+ List models request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_list_models(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_list_models(workspace, request_options=request_options)
+ return _response.data
+
+ async def openai_proxy_get_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OpenAiModelResp:
+ """
+ Retrieve information about a specific OpenAI-compatible model.
+ Workspace is always taken from the URL path; name may be model_entity_name
+ or workspace/model_entity_name (workspace prefix is ignored).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OpenAiModelResp
+ Get model request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_get_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_get_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def openai_proxy_get(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_get(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_get(workspace, trailing_uri, request_options=request_options)
+ return _response.data
+
+ async def openai_proxy_post(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_post(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_post(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def openai_proxy_put(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_put(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_put(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def openai_proxy_delete(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_delete(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_delete(workspace, trailing_uri, request_options=request_options)
+ return _response.data
+
+ async def openai_proxy_patch(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to OpenAI-compatible endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.openai_proxy_patch(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.openai_proxy_patch(
+ workspace, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy GET request to provider inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_proxy_get(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy POST request to provider inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_proxy_post(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PUT request to provider inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_proxy_put(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Any:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Proxy DELETE request to provider inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_proxy_delete(
+ workspace, name, trailing_uri, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Proxy PATCH request to provider inference endpoint
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_proxy_patch(
+ workspace, name, trailing_uri, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def provider_ready(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Check if a model provider is registered in the gateway's cache.
+
+ This is a lightweight endpoint that only checks the gateway's internal state,
+ without making any requests to the actual provider backend. Use this to verify
+ the gateway is ready to route requests to a provider after deployment.
+
+ Returns:
+ 200 OK with provider info if the provider is registered
+ 404 Not Found if the provider is not yet in the gateway's cache
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Check if the gateway can route to a provider
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.inference_gateway.provider_ready(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.provider_ready(workspace, name, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/inference_gateway/raw_client.py b/sdks/python/inference_gateway/raw_client.py
new file mode 100644
index 0000000000..a064be77b0
--- /dev/null
+++ b/sdks/python/inference_gateway/raw_client.py
@@ -0,0 +1,2481 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.open_ai_list_models_resp import OpenAiListModelsResp
+from ..types.open_ai_model_resp import OpenAiModelResp
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawInferenceGatewayClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def gateway_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy GET request to model entity inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def gateway_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to model entity inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def gateway_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to model entity inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def gateway_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy DELETE request to model entity inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def gateway_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to model entity inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_list_models(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[OpenAiListModelsResp]:
+ """
+ This endpoint aggregates models from all model entities and returns them
+ in OpenAI's list models format. Each model ID is the model entity identifier
+ in format workspace/model_entity_name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[OpenAiListModelsResp]
+ List models request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/v1/models",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OpenAiListModelsResp,
+ parse_obj_as(
+ type_=OpenAiListModelsResp, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_get_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[OpenAiModelResp]:
+ """
+ Retrieve information about a specific OpenAI-compatible model.
+ Workspace is always taken from the URL path; name may be model_entity_name
+ or workspace/model_entity_name (workspace prefix is ignored).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[OpenAiModelResp]
+ Get model request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/v1/models/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OpenAiModelResp,
+ parse_obj_as(
+ type_=OpenAiModelResp, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_get(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy GET request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_post(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_put(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_delete(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy DELETE request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def openai_proxy_patch(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to OpenAI-compatible endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy GET request to provider inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to provider inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to provider inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Proxy DELETE request to provider inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to provider inference endpoint
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def provider_ready(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Check if a model provider is registered in the gateway's cache.
+
+ This is a lightweight endpoint that only checks the gateway's internal state,
+ without making any requests to the actual provider backend. Use this to verify
+ the gateway is ready to route requests to a provider after deployment.
+
+ Returns:
+ 200 OK with provider info if the provider is registered
+ 404 Not Found if the provider is not yet in the gateway's cache
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Check if the gateway can route to a provider
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/ready",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawInferenceGatewayClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def gateway_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy GET request to model entity inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def gateway_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to model entity inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def gateway_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to model entity inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def gateway_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy DELETE request to model entity inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def gateway_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to model entity inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to model entity inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/model/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_list_models(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[OpenAiListModelsResp]:
+ """
+ This endpoint aggregates models from all model entities and returns them
+ in OpenAI's list models format. Each model ID is the model entity identifier
+ in format workspace/model_entity_name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[OpenAiListModelsResp]
+ List models request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/v1/models",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OpenAiListModelsResp,
+ parse_obj_as(
+ type_=OpenAiListModelsResp, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_get_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[OpenAiModelResp]:
+ """
+ Retrieve information about a specific OpenAI-compatible model.
+ Workspace is always taken from the URL path; name may be model_entity_name
+ or workspace/model_entity_name (workspace prefix is ignored).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[OpenAiModelResp]
+ Get model request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/v1/models/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OpenAiModelResp,
+ parse_obj_as(
+ type_=OpenAiModelResp, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_get(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy GET request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_post(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_put(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_delete(
+ self, workspace: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy DELETE request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def openai_proxy_patch(
+ self,
+ workspace: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to OpenAI-compatible inference endpoints.
+
+ All inference requests must resolve to a `VirtualModel`. The platform's
+ provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+ for every served model entity (named after the entity, with
+ `default_model_entity` set to the entity ref) so this is the typical case;
+ operators can also create custom VirtualModels for routing, plugin chains,
+ LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+ return `404`.
+
+ Parameters
+ ----------
+ workspace : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to OpenAI-compatible endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/openai/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_proxy_get(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy GET request to provider inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_proxy_post(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy POST request to provider inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="POST",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_proxy_put(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PUT request to provider inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PUT",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_proxy_delete(
+ self, workspace: str, name: str, trailing_uri: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Proxy DELETE request to provider inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_proxy_patch(
+ self,
+ workspace: str,
+ name: str,
+ trailing_uri: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Proxy requests to provider inference endpoints.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ trailing_uri : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Proxy PATCH request to provider inference endpoint
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/-/{encode_path_param(trailing_uri)}",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def provider_ready(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Check if a model provider is registered in the gateway's cache.
+
+ This is a lightweight endpoint that only checks the gateway's internal state,
+ without making any requests to the actual provider backend. Use this to verify
+ the gateway is ready to route requests to a provider after deployment.
+
+ Returns:
+ 200 OK with provider info if the provider is registered
+ 404 Not Found if the provider is not yet in the gateway's cache
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Check if the gateway can route to a provider
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/provider/{encode_path_param(name)}/ready",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/ingest/__init__.py b/sdks/python/ingest/__init__.py
new file mode 100644
index 0000000000..e653e76a4a
--- /dev/null
+++ b/sdks/python/ingest/__init__.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import AtifIngestRequestSchemaVersion
+_dynamic_imports: typing.Dict[str, str] = {"AtifIngestRequestSchemaVersion": ".types"}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["AtifIngestRequestSchemaVersion"]
diff --git a/sdks/python/ingest/client.py b/sdks/python/ingest/client.py
new file mode 100644
index 0000000000..2058439253
--- /dev/null
+++ b/sdks/python/ingest/client.py
@@ -0,0 +1,504 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.atif_agent import AtifAgent
+from ..types.atif_final_metrics import AtifFinalMetrics
+from ..types.atif_step import AtifStep
+from ..types.captured_chat_completions_request import CapturedChatCompletionsRequest
+from ..types.captured_chat_completions_response import CapturedChatCompletionsResponse
+from ..types.chat_completions_ingest_response import ChatCompletionsIngestResponse
+from ..types.evaluation_context import EvaluationContext
+from ..types.experiment_context import ExperimentContext
+from ..types.ingest_response import IngestResponse
+from .raw_client import AsyncRawIngestClient, RawIngestClient
+from .types.atif_ingest_request_schema_version import AtifIngestRequestSchemaVersion
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class IngestClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawIngestClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawIngestClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawIngestClient
+ """
+ return self._raw_client
+
+ def ingest_atif(
+ self,
+ workspace: str,
+ *,
+ schema_version: AtifIngestRequestSchemaVersion,
+ agent: AtifAgent,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ final_metrics: typing.Optional[AtifFinalMetrics] = OMIT,
+ continued_trajectory_ref: typing.Optional[str] = OMIT,
+ notes: typing.Optional[str] = OMIT,
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ steps: typing.Optional[typing.Sequence[AtifStep]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ schema_version : AtifIngestRequestSchemaVersion
+
+ agent : AtifAgent
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+
+ final_metrics : typing.Optional[AtifFinalMetrics]
+
+ continued_trajectory_ref : typing.Optional[str]
+
+ notes : typing.Optional[str]
+
+ extra : typing.Optional[typing.Dict[str, typing.Any]]
+
+ steps : typing.Optional[typing.Sequence[AtifStep]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import AtifAgent, NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.ingest.ingest_atif(
+ workspace="workspace",
+ schema_version="ATIF-v1.0",
+ agent=AtifAgent(
+ name="name",
+ version="version",
+ ),
+ )
+ """
+ _response = self._raw_client.ingest_atif(
+ workspace,
+ schema_version=schema_version,
+ agent=agent,
+ experiment_context=experiment_context,
+ evaluation_context=evaluation_context,
+ session_id=session_id,
+ final_metrics=final_metrics,
+ continued_trajectory_ref=continued_trajectory_ref,
+ notes=notes,
+ extra=extra,
+ steps=steps,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def ingest_chat_completion(
+ self,
+ workspace: str,
+ *,
+ request: CapturedChatCompletionsRequest,
+ response: CapturedChatCompletionsResponse,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ provider: typing.Optional[str] = OMIT,
+ cost_usd: typing.Optional[float] = OMIT,
+ cost_input_usd: typing.Optional[float] = OMIT,
+ cost_output_usd: typing.Optional[float] = OMIT,
+ cost_details: typing.Optional[typing.Dict[str, float]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ChatCompletionsIngestResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : CapturedChatCompletionsRequest
+
+ response : CapturedChatCompletionsResponse
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+ Groups related chat-completions calls without forcing them into the same trace.
+
+ trace_id : typing.Optional[str]
+ Opt into joining an existing trace built via OTel or ATIF. This is not a grouping mechanism for chat-completions calls; use session_id to group related calls.
+
+ provider : typing.Optional[str]
+
+ cost_usd : typing.Optional[float]
+ Total estimated cost of this model call in USD. This matches ATIF step metrics; Intake stores it as semantic cost_total_usd on spans.
+
+ cost_input_usd : typing.Optional[float]
+ Estimated input-token cost of this model call in USD.
+
+ cost_output_usd : typing.Optional[float]
+ Estimated output-token cost of this model call in USD.
+
+ cost_details : typing.Optional[typing.Dict[str, float]]
+ Additional estimated cost breakdown fields in USD.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ChatCompletionsIngestResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import (
+ CapturedChatCompletionsRequest,
+ CapturedChatMessage,
+ NvidiaApi,
+ )
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.ingest.ingest_chat_completion(
+ workspace="workspace",
+ request=CapturedChatCompletionsRequest(
+ messages=[
+ CapturedChatMessage(
+ role="user",
+ ),
+ CapturedChatMessage(
+ role="user",
+ ),
+ ],
+ model="model",
+ ),
+ response={"key": "value"},
+ )
+ """
+ _response = self._raw_client.ingest_chat_completion(
+ workspace,
+ request=request,
+ response=response,
+ experiment_context=experiment_context,
+ evaluation_context=evaluation_context,
+ session_id=session_id,
+ trace_id=trace_id,
+ provider=provider,
+ cost_usd=cost_usd,
+ cost_input_usd=cost_input_usd,
+ cost_output_usd=cost_output_usd,
+ cost_details=cost_details,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def ingest_otlp_traces(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> IngestResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ IngestResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.ingest.ingest_otlp_traces(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.ingest_otlp_traces(workspace, request_options=request_options)
+ return _response.data
+
+
+class AsyncIngestClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawIngestClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawIngestClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawIngestClient
+ """
+ return self._raw_client
+
+ async def ingest_atif(
+ self,
+ workspace: str,
+ *,
+ schema_version: AtifIngestRequestSchemaVersion,
+ agent: AtifAgent,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ final_metrics: typing.Optional[AtifFinalMetrics] = OMIT,
+ continued_trajectory_ref: typing.Optional[str] = OMIT,
+ notes: typing.Optional[str] = OMIT,
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ steps: typing.Optional[typing.Sequence[AtifStep]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ schema_version : AtifIngestRequestSchemaVersion
+
+ agent : AtifAgent
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+
+ final_metrics : typing.Optional[AtifFinalMetrics]
+
+ continued_trajectory_ref : typing.Optional[str]
+
+ notes : typing.Optional[str]
+
+ extra : typing.Optional[typing.Dict[str, typing.Any]]
+
+ steps : typing.Optional[typing.Sequence[AtifStep]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi, AtifAgent
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.ingest.ingest_atif(
+ workspace="workspace",
+ schema_version="ATIF-v1.0",
+ agent=AtifAgent(
+ name="name",
+ version="version",
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.ingest_atif(
+ workspace,
+ schema_version=schema_version,
+ agent=agent,
+ experiment_context=experiment_context,
+ evaluation_context=evaluation_context,
+ session_id=session_id,
+ final_metrics=final_metrics,
+ continued_trajectory_ref=continued_trajectory_ref,
+ notes=notes,
+ extra=extra,
+ steps=steps,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def ingest_chat_completion(
+ self,
+ workspace: str,
+ *,
+ request: CapturedChatCompletionsRequest,
+ response: CapturedChatCompletionsResponse,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ provider: typing.Optional[str] = OMIT,
+ cost_usd: typing.Optional[float] = OMIT,
+ cost_input_usd: typing.Optional[float] = OMIT,
+ cost_output_usd: typing.Optional[float] = OMIT,
+ cost_details: typing.Optional[typing.Dict[str, float]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ChatCompletionsIngestResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : CapturedChatCompletionsRequest
+
+ response : CapturedChatCompletionsResponse
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+ Groups related chat-completions calls without forcing them into the same trace.
+
+ trace_id : typing.Optional[str]
+ Opt into joining an existing trace built via OTel or ATIF. This is not a grouping mechanism for chat-completions calls; use session_id to group related calls.
+
+ provider : typing.Optional[str]
+
+ cost_usd : typing.Optional[float]
+ Total estimated cost of this model call in USD. This matches ATIF step metrics; Intake stores it as semantic cost_total_usd on spans.
+
+ cost_input_usd : typing.Optional[float]
+ Estimated input-token cost of this model call in USD.
+
+ cost_output_usd : typing.Optional[float]
+ Estimated output-token cost of this model call in USD.
+
+ cost_details : typing.Optional[typing.Dict[str, float]]
+ Additional estimated cost breakdown fields in USD.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ChatCompletionsIngestResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import (
+ AsyncNvidiaApi,
+ CapturedChatCompletionsRequest,
+ CapturedChatMessage,
+ )
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.ingest.ingest_chat_completion(
+ workspace="workspace",
+ request=CapturedChatCompletionsRequest(
+ messages=[
+ CapturedChatMessage(
+ role="user",
+ ),
+ CapturedChatMessage(
+ role="user",
+ ),
+ ],
+ model="model",
+ ),
+ response={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.ingest_chat_completion(
+ workspace,
+ request=request,
+ response=response,
+ experiment_context=experiment_context,
+ evaluation_context=evaluation_context,
+ session_id=session_id,
+ trace_id=trace_id,
+ provider=provider,
+ cost_usd=cost_usd,
+ cost_input_usd=cost_input_usd,
+ cost_output_usd=cost_output_usd,
+ cost_details=cost_details,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def ingest_otlp_traces(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> IngestResponse:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ IngestResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.ingest.ingest_otlp_traces(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.ingest_otlp_traces(workspace, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/ingest/raw_client.py b/sdks/python/ingest/raw_client.py
new file mode 100644
index 0000000000..05e89aeee9
--- /dev/null
+++ b/sdks/python/ingest/raw_client.py
@@ -0,0 +1,584 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.atif_agent import AtifAgent
+from ..types.atif_final_metrics import AtifFinalMetrics
+from ..types.atif_step import AtifStep
+from ..types.captured_chat_completions_request import CapturedChatCompletionsRequest
+from ..types.captured_chat_completions_response import CapturedChatCompletionsResponse
+from ..types.chat_completions_ingest_response import ChatCompletionsIngestResponse
+from ..types.evaluation_context import EvaluationContext
+from ..types.experiment_context import ExperimentContext
+from ..types.ingest_response import IngestResponse
+from .types.atif_ingest_request_schema_version import AtifIngestRequestSchemaVersion
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawIngestClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def ingest_atif(
+ self,
+ workspace: str,
+ *,
+ schema_version: AtifIngestRequestSchemaVersion,
+ agent: AtifAgent,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ final_metrics: typing.Optional[AtifFinalMetrics] = OMIT,
+ continued_trajectory_ref: typing.Optional[str] = OMIT,
+ notes: typing.Optional[str] = OMIT,
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ steps: typing.Optional[typing.Sequence[AtifStep]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ schema_version : AtifIngestRequestSchemaVersion
+
+ agent : AtifAgent
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+
+ final_metrics : typing.Optional[AtifFinalMetrics]
+
+ continued_trajectory_ref : typing.Optional[str]
+
+ notes : typing.Optional[str]
+
+ extra : typing.Optional[typing.Dict[str, typing.Any]]
+
+ steps : typing.Optional[typing.Sequence[AtifStep]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/atif",
+ method="POST",
+ json={
+ "experiment_context": convert_and_respect_annotation_metadata(
+ object_=experiment_context, annotation=ExperimentContext, direction="write"
+ ),
+ "evaluation_context": convert_and_respect_annotation_metadata(
+ object_=evaluation_context, annotation=EvaluationContext, direction="write"
+ ),
+ "schema_version": schema_version,
+ "session_id": session_id,
+ "agent": convert_and_respect_annotation_metadata(
+ object_=agent, annotation=AtifAgent, direction="write"
+ ),
+ "final_metrics": convert_and_respect_annotation_metadata(
+ object_=final_metrics, annotation=AtifFinalMetrics, direction="write"
+ ),
+ "continued_trajectory_ref": continued_trajectory_ref,
+ "notes": notes,
+ "extra": extra,
+ "steps": convert_and_respect_annotation_metadata(
+ object_=steps, annotation=typing.Sequence[AtifStep], direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def ingest_chat_completion(
+ self,
+ workspace: str,
+ *,
+ request: CapturedChatCompletionsRequest,
+ response: CapturedChatCompletionsResponse,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ provider: typing.Optional[str] = OMIT,
+ cost_usd: typing.Optional[float] = OMIT,
+ cost_input_usd: typing.Optional[float] = OMIT,
+ cost_output_usd: typing.Optional[float] = OMIT,
+ cost_details: typing.Optional[typing.Dict[str, float]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ChatCompletionsIngestResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : CapturedChatCompletionsRequest
+
+ response : CapturedChatCompletionsResponse
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+ Groups related chat-completions calls without forcing them into the same trace.
+
+ trace_id : typing.Optional[str]
+ Opt into joining an existing trace built via OTel or ATIF. This is not a grouping mechanism for chat-completions calls; use session_id to group related calls.
+
+ provider : typing.Optional[str]
+
+ cost_usd : typing.Optional[float]
+ Total estimated cost of this model call in USD. This matches ATIF step metrics; Intake stores it as semantic cost_total_usd on spans.
+
+ cost_input_usd : typing.Optional[float]
+ Estimated input-token cost of this model call in USD.
+
+ cost_output_usd : typing.Optional[float]
+ Estimated output-token cost of this model call in USD.
+
+ cost_details : typing.Optional[typing.Dict[str, float]]
+ Additional estimated cost breakdown fields in USD.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ChatCompletionsIngestResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/chat-completions",
+ method="POST",
+ json={
+ "experiment_context": convert_and_respect_annotation_metadata(
+ object_=experiment_context, annotation=ExperimentContext, direction="write"
+ ),
+ "evaluation_context": convert_and_respect_annotation_metadata(
+ object_=evaluation_context, annotation=EvaluationContext, direction="write"
+ ),
+ "request": convert_and_respect_annotation_metadata(
+ object_=request, annotation=CapturedChatCompletionsRequest, direction="write"
+ ),
+ "response": convert_and_respect_annotation_metadata(
+ object_=response, annotation=CapturedChatCompletionsResponse, direction="write"
+ ),
+ "session_id": session_id,
+ "trace_id": trace_id,
+ "provider": provider,
+ "cost_usd": cost_usd,
+ "cost_input_usd": cost_input_usd,
+ "cost_output_usd": cost_output_usd,
+ "cost_details": cost_details,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ChatCompletionsIngestResponse,
+ parse_obj_as(
+ type_=ChatCompletionsIngestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def ingest_otlp_traces(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[IngestResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[IngestResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/otlp/v1/traces",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ IngestResponse,
+ parse_obj_as(
+ type_=IngestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawIngestClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def ingest_atif(
+ self,
+ workspace: str,
+ *,
+ schema_version: AtifIngestRequestSchemaVersion,
+ agent: AtifAgent,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ final_metrics: typing.Optional[AtifFinalMetrics] = OMIT,
+ continued_trajectory_ref: typing.Optional[str] = OMIT,
+ notes: typing.Optional[str] = OMIT,
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ steps: typing.Optional[typing.Sequence[AtifStep]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[None]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ schema_version : AtifIngestRequestSchemaVersion
+
+ agent : AtifAgent
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+
+ final_metrics : typing.Optional[AtifFinalMetrics]
+
+ continued_trajectory_ref : typing.Optional[str]
+
+ notes : typing.Optional[str]
+
+ extra : typing.Optional[typing.Dict[str, typing.Any]]
+
+ steps : typing.Optional[typing.Sequence[AtifStep]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/atif",
+ method="POST",
+ json={
+ "experiment_context": convert_and_respect_annotation_metadata(
+ object_=experiment_context, annotation=ExperimentContext, direction="write"
+ ),
+ "evaluation_context": convert_and_respect_annotation_metadata(
+ object_=evaluation_context, annotation=EvaluationContext, direction="write"
+ ),
+ "schema_version": schema_version,
+ "session_id": session_id,
+ "agent": convert_and_respect_annotation_metadata(
+ object_=agent, annotation=AtifAgent, direction="write"
+ ),
+ "final_metrics": convert_and_respect_annotation_metadata(
+ object_=final_metrics, annotation=AtifFinalMetrics, direction="write"
+ ),
+ "continued_trajectory_ref": continued_trajectory_ref,
+ "notes": notes,
+ "extra": extra,
+ "steps": convert_and_respect_annotation_metadata(
+ object_=steps, annotation=typing.Sequence[AtifStep], direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def ingest_chat_completion(
+ self,
+ workspace: str,
+ *,
+ request: CapturedChatCompletionsRequest,
+ response: CapturedChatCompletionsResponse,
+ experiment_context: typing.Optional[ExperimentContext] = OMIT,
+ evaluation_context: typing.Optional[EvaluationContext] = OMIT,
+ session_id: typing.Optional[str] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ provider: typing.Optional[str] = OMIT,
+ cost_usd: typing.Optional[float] = OMIT,
+ cost_input_usd: typing.Optional[float] = OMIT,
+ cost_output_usd: typing.Optional[float] = OMIT,
+ cost_details: typing.Optional[typing.Dict[str, float]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ChatCompletionsIngestResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request : CapturedChatCompletionsRequest
+
+ response : CapturedChatCompletionsResponse
+
+ experiment_context : typing.Optional[ExperimentContext]
+
+ evaluation_context : typing.Optional[EvaluationContext]
+ Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+ session_id : typing.Optional[str]
+ Groups related chat-completions calls without forcing them into the same trace.
+
+ trace_id : typing.Optional[str]
+ Opt into joining an existing trace built via OTel or ATIF. This is not a grouping mechanism for chat-completions calls; use session_id to group related calls.
+
+ provider : typing.Optional[str]
+
+ cost_usd : typing.Optional[float]
+ Total estimated cost of this model call in USD. This matches ATIF step metrics; Intake stores it as semantic cost_total_usd on spans.
+
+ cost_input_usd : typing.Optional[float]
+ Estimated input-token cost of this model call in USD.
+
+ cost_output_usd : typing.Optional[float]
+ Estimated output-token cost of this model call in USD.
+
+ cost_details : typing.Optional[typing.Dict[str, float]]
+ Additional estimated cost breakdown fields in USD.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ChatCompletionsIngestResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/chat-completions",
+ method="POST",
+ json={
+ "experiment_context": convert_and_respect_annotation_metadata(
+ object_=experiment_context, annotation=ExperimentContext, direction="write"
+ ),
+ "evaluation_context": convert_and_respect_annotation_metadata(
+ object_=evaluation_context, annotation=EvaluationContext, direction="write"
+ ),
+ "request": convert_and_respect_annotation_metadata(
+ object_=request, annotation=CapturedChatCompletionsRequest, direction="write"
+ ),
+ "response": convert_and_respect_annotation_metadata(
+ object_=response, annotation=CapturedChatCompletionsResponse, direction="write"
+ ),
+ "session_id": session_id,
+ "trace_id": trace_id,
+ "provider": provider,
+ "cost_usd": cost_usd,
+ "cost_input_usd": cost_input_usd,
+ "cost_output_usd": cost_output_usd,
+ "cost_details": cost_details,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ChatCompletionsIngestResponse,
+ parse_obj_as(
+ type_=ChatCompletionsIngestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def ingest_otlp_traces(
+ self, workspace: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[IngestResponse]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[IngestResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/ingest/otlp/v1/traces",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ IngestResponse,
+ parse_obj_as(
+ type_=IngestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/ingest/types/__init__.py b/sdks/python/ingest/types/__init__.py
new file mode 100644
index 0000000000..71eb509f44
--- /dev/null
+++ b/sdks/python/ingest/types/__init__.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .atif_ingest_request_schema_version import AtifIngestRequestSchemaVersion
+_dynamic_imports: typing.Dict[str, str] = {"AtifIngestRequestSchemaVersion": ".atif_ingest_request_schema_version"}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["AtifIngestRequestSchemaVersion"]
diff --git a/sdks/python/ingest/types/atif_ingest_request_schema_version.py b/sdks/python/ingest/types/atif_ingest_request_schema_version.py
new file mode 100644
index 0000000000..3bfa4dbbea
--- /dev/null
+++ b/sdks/python/ingest/types/atif_ingest_request_schema_version.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AtifIngestRequestSchemaVersion = typing.Union[
+ typing.Literal[
+ "ATIF-v1.0", "ATIF-v1.1", "ATIF-v1.2", "ATIF-v1.3", "ATIF-v1.4", "ATIF-v1.5", "ATIF-v1.6", "ATIF-v1.7"
+ ],
+ typing.Any,
+]
diff --git a/sdks/python/jobs/__init__.py b/sdks/python/jobs/__init__.py
new file mode 100644
index 0000000000..df4abf7e8c
--- /dev/null
+++ b/sdks/python/jobs/__init__.py
@@ -0,0 +1,55 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import (
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess": ".types",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob": ".types",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob",
+]
diff --git a/sdks/python/jobs/client.py b/sdks/python/jobs/client.py
new file mode 100644
index 0000000000..da31d91cb4
--- /dev/null
+++ b/sdks/python/jobs/client.py
@@ -0,0 +1,2184 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.file_storage_type import FileStorageType
+from ..types.platform_job_list_result_response import PlatformJobListResultResponse
+from ..types.platform_job_list_task_response import PlatformJobListTaskResponse
+from ..types.platform_job_log_page import PlatformJobLogPage
+from ..types.platform_job_response import PlatformJobResponse
+from ..types.platform_job_responses_page import PlatformJobResponsesPage
+from ..types.platform_job_result_response import PlatformJobResultResponse
+from ..types.platform_job_sort_field import PlatformJobSortField
+from ..types.platform_job_spec_input import PlatformJobSpecInput
+from ..types.platform_job_status import PlatformJobStatus
+from ..types.platform_job_status_response import PlatformJobStatusResponse
+from ..types.platform_job_step import PlatformJobStep
+from ..types.platform_job_step_with_contexts_page import PlatformJobStepWithContextsPage
+from ..types.platform_job_steps_list_filter import PlatformJobStepsListFilter
+from ..types.platform_job_task import PlatformJobTask
+from ..types.platform_jobs_list_filter import PlatformJobsListFilter
+from .raw_client import AsyncRawJobsClient, RawJobsClient
+from .types.get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item import (
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem,
+)
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class JobsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawJobsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawJobsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawJobsClient
+ """
+ return self._raw_client
+
+ def get_execution_profiles(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]:
+ """
+ Get all currently configured execution profiles.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_execution_profiles()
+ """
+ _response = self._raw_client.get_execution_profiles(request_options=request_options)
+ return _response.data
+
+ def list_jobs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResponsesPage:
+ """
+ List platform jobs with filtering and pagination.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobsListFilter]
+ Filter jobs by workspace, project, name, status, source, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.list_jobs(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_jobs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_job(
+ self,
+ workspace: str,
+ *,
+ spec: typing.Dict[str, typing.Any],
+ platform_spec: PlatformJobSpecInput,
+ source: str,
+ name: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResponse:
+ """
+ Create a new platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ spec : typing.Dict[str, typing.Any]
+
+ platform_spec : PlatformJobSpecInput
+
+ source : str
+
+ name : typing.Optional[str]
+
+ description : typing.Optional[str]
+
+ project : typing.Optional[str]
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import (
+ ContainerSpec,
+ NvidiaApi,
+ PlatformJobSpecInput,
+ PlatformJobStepSpecInput,
+ PlatformJobStepSpecInputExecutor_Cpu,
+ )
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.create_job(
+ workspace="workspace",
+ spec={"key": "value"},
+ platform_spec=PlatformJobSpecInput(
+ steps=[
+ PlatformJobStepSpecInput(
+ name="preprocess",
+ executor=PlatformJobStepSpecInputExecutor_Cpu(
+ container=ContainerSpec(
+ image="image",
+ ),
+ ),
+ )
+ ],
+ ),
+ source="source",
+ )
+ """
+ _response = self._raw_client.create_job(
+ workspace,
+ spec=spec,
+ platform_spec=platform_spec,
+ source=source,
+ name=name,
+ description=description,
+ project=project,
+ ownership=ownership,
+ custom_fields=custom_fields,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResultResponse:
+ """
+ Get a specific job result.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResultResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_job_result(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ def create_job_result(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ artifact_url: str,
+ artifact_storage_type: FileStorageType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResultResponse:
+ """
+ Create a new result for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ artifact_url : str
+
+ artifact_storage_type : FileStorageType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResultResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.create_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ artifact_url="artifact_url",
+ artifact_storage_type="fileset",
+ )
+ """
+ _response = self._raw_client.create_job_result(
+ workspace,
+ job,
+ name,
+ artifact_url=artifact_url,
+ artifact_storage_type=artifact_storage_type,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def download_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Iterator[bytes]:
+ """
+ Download a job result file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.download_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+ """
+ with self._raw_client.download_job_result(workspace, job, name, request_options=request_options) as r:
+ yield from r.data
+
+ def get_job_step(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobStep:
+ """
+ Get a specific job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStep
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_job_step(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_job_step(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ def update_job_step_status(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ status: PlatformJobStatus,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobStep:
+ """
+ Update a job step status.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ status : PlatformJobStatus
+ The new status to set for the job.
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional status details related to the status update.
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional error details related to the status update.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStep
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.update_job_step_status(
+ workspace="workspace",
+ job="job",
+ name="name",
+ status="created",
+ )
+ """
+ _response = self._raw_client.update_job_step_status(
+ workspace,
+ job,
+ name,
+ status=status,
+ status_details=status_details,
+ error_details=error_details,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def list_job_step_tasks(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobListTaskResponse:
+ """
+ List tasks for a job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobListTaskResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.list_job_step_tasks(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_job_step_tasks(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ def get_job_step_task(
+ self, workspace: str, job: str, step: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobTask:
+ """
+ Get a specific job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobTask
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_job_step_task(workspace, job, step, name, request_options=request_options)
+ return _response.data
+
+ def update_job_step_task(
+ self,
+ workspace: str,
+ job: str,
+ step: str,
+ name: str,
+ *,
+ status: typing.Optional[PlatformJobStatus] = OMIT,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_stack: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobTask:
+ """
+ Update a job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ status : typing.Optional[PlatformJobStatus]
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_stack : typing.Optional[str]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobTask
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.update_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_job_step_task(
+ workspace,
+ job,
+ step,
+ name,
+ status=status,
+ status_details=status_details,
+ error_details=error_details,
+ error_stack=error_stack,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Get a platform job by name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_job(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_job(self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
+ """
+ Delete a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.delete_job(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ def cancel_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Cancel a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.cancel_job(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.cancel_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ def page_job_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ limit: typing.Optional[int] = None,
+ page_cursor: typing.Optional[str] = None,
+ attempt_id: typing.Optional[int] = None,
+ step_id: typing.Optional[str] = None,
+ task_id: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobLogPage:
+ """
+ Get paginated logs for a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ limit : typing.Optional[int]
+ Maximum number of logs to return
+
+ page_cursor : typing.Optional[str]
+ Page cursor
+
+ attempt_id : typing.Optional[int]
+ Filter logs by job attempt ID
+
+ step_id : typing.Optional[str]
+ Filter logs by step name
+
+ task_id : typing.Optional[str]
+ Filter logs by task ID
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobLogPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.page_job_logs(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.page_job_logs(
+ workspace,
+ name,
+ limit=limit,
+ page_cursor=page_cursor,
+ attempt_id=attempt_id,
+ step_id=step_id,
+ task_id=task_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def pause_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Pause a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.pause_job(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.pause_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ def list_job_results(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobListResultResponse:
+ """
+ List results for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobListResultResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.list_job_results(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_job_results(workspace, name, sort=sort, request_options=request_options)
+ return _response.data
+
+ def resume_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Resume a paused platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.resume_job(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.resume_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ def get_job_status(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobStatusResponse:
+ """
+ Get the status of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStatusResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.get_job_status(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_job_status(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_job_status_details(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Any:
+ """
+ Update the status details of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.update_job_status_details(
+ workspace="workspace",
+ name="name",
+ request={"key": "value"},
+ )
+ """
+ _response = self._raw_client.update_job_status_details(
+ workspace, name, request=request, request_options=request_options
+ )
+ return _response.data
+
+ def list_steps(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobStepsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobStepWithContextsPage:
+ """
+ List job steps with pagination and filtering.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobStepsListFilter]
+ Filter steps by job, status, and source.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStepWithContextsPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.jobs.list_steps(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_steps(
+ workspace, name, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncJobsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawJobsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawJobsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawJobsClient
+ """
+ return self._raw_client
+
+ async def get_execution_profiles(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]:
+ """
+ Get all currently configured execution profiles.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_execution_profiles()
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_execution_profiles(request_options=request_options)
+ return _response.data
+
+ async def list_jobs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResponsesPage:
+ """
+ List platform jobs with filtering and pagination.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobsListFilter]
+ Filter jobs by workspace, project, name, status, source, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.list_jobs(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_jobs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_job(
+ self,
+ workspace: str,
+ *,
+ spec: typing.Dict[str, typing.Any],
+ platform_spec: PlatformJobSpecInput,
+ source: str,
+ name: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResponse:
+ """
+ Create a new platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ spec : typing.Dict[str, typing.Any]
+
+ platform_spec : PlatformJobSpecInput
+
+ source : str
+
+ name : typing.Optional[str]
+
+ description : typing.Optional[str]
+
+ project : typing.Optional[str]
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import (
+ AsyncNvidiaApi,
+ ContainerSpec,
+ PlatformJobSpecInput,
+ PlatformJobStepSpecInput,
+ PlatformJobStepSpecInputExecutor_Cpu,
+ )
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.create_job(
+ workspace="workspace",
+ spec={"key": "value"},
+ platform_spec=PlatformJobSpecInput(
+ steps=[
+ PlatformJobStepSpecInput(
+ name="preprocess",
+ executor=PlatformJobStepSpecInputExecutor_Cpu(
+ container=ContainerSpec(
+ image="image",
+ ),
+ ),
+ )
+ ],
+ ),
+ source="source",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_job(
+ workspace,
+ spec=spec,
+ platform_spec=platform_spec,
+ source=source,
+ name=name,
+ description=description,
+ project=project,
+ ownership=ownership,
+ custom_fields=custom_fields,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResultResponse:
+ """
+ Get a specific job result.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResultResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_job_result(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ async def create_job_result(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ artifact_url: str,
+ artifact_storage_type: FileStorageType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobResultResponse:
+ """
+ Create a new result for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ artifact_url : str
+
+ artifact_storage_type : FileStorageType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResultResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.create_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ artifact_url="artifact_url",
+ artifact_storage_type="fileset",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_job_result(
+ workspace,
+ job,
+ name,
+ artifact_url=artifact_url,
+ artifact_storage_type=artifact_storage_type,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def download_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Download a job result file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.download_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ async with self._raw_client.download_job_result(workspace, job, name, request_options=request_options) as r:
+ async for _chunk in r.data:
+ yield _chunk
+
+ async def get_job_step(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobStep:
+ """
+ Get a specific job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStep
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_job_step(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_job_step(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ async def update_job_step_status(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ status: PlatformJobStatus,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobStep:
+ """
+ Update a job step status.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ status : PlatformJobStatus
+ The new status to set for the job.
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional status details related to the status update.
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional error details related to the status update.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStep
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.update_job_step_status(
+ workspace="workspace",
+ job="job",
+ name="name",
+ status="created",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_job_step_status(
+ workspace,
+ job,
+ name,
+ status=status,
+ status_details=status_details,
+ error_details=error_details,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def list_job_step_tasks(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobListTaskResponse:
+ """
+ List tasks for a job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobListTaskResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.list_job_step_tasks(
+ workspace="workspace",
+ job="job",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_job_step_tasks(workspace, job, name, request_options=request_options)
+ return _response.data
+
+ async def get_job_step_task(
+ self, workspace: str, job: str, step: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobTask:
+ """
+ Get a specific job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobTask
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_job_step_task(
+ workspace, job, step, name, request_options=request_options
+ )
+ return _response.data
+
+ async def update_job_step_task(
+ self,
+ workspace: str,
+ job: str,
+ step: str,
+ name: str,
+ *,
+ status: typing.Optional[PlatformJobStatus] = OMIT,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_stack: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobTask:
+ """
+ Update a job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ status : typing.Optional[PlatformJobStatus]
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_stack : typing.Optional[str]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobTask
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.update_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_job_step_task(
+ workspace,
+ job,
+ step,
+ name,
+ status=status,
+ status_details=status_details,
+ error_details=error_details,
+ error_stack=error_stack,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Get a platform job by name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_job(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.delete_job(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def cancel_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Cancel a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.cancel_job(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.cancel_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def page_job_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ limit: typing.Optional[int] = None,
+ page_cursor: typing.Optional[str] = None,
+ attempt_id: typing.Optional[int] = None,
+ step_id: typing.Optional[str] = None,
+ task_id: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobLogPage:
+ """
+ Get paginated logs for a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ limit : typing.Optional[int]
+ Maximum number of logs to return
+
+ page_cursor : typing.Optional[str]
+ Page cursor
+
+ attempt_id : typing.Optional[int]
+ Filter logs by job attempt ID
+
+ step_id : typing.Optional[str]
+ Filter logs by step name
+
+ task_id : typing.Optional[str]
+ Filter logs by task ID
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobLogPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.page_job_logs(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.page_job_logs(
+ workspace,
+ name,
+ limit=limit,
+ page_cursor=page_cursor,
+ attempt_id=attempt_id,
+ step_id=step_id,
+ task_id=task_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def pause_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Pause a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.pause_job(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.pause_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def list_job_results(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobListResultResponse:
+ """
+ List results for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobListResultResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.list_job_results(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_job_results(workspace, name, sort=sort, request_options=request_options)
+ return _response.data
+
+ async def resume_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobResponse:
+ """
+ Resume a paused platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.resume_job(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.resume_job(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def get_job_status(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformJobStatusResponse:
+ """
+ Get the status of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStatusResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.get_job_status(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_job_status(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_job_status_details(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Any:
+ """
+ Update the status details of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Any
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.update_job_status_details(
+ workspace="workspace",
+ name="name",
+ request={"key": "value"},
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_job_status_details(
+ workspace, name, request=request, request_options=request_options
+ )
+ return _response.data
+
+ async def list_steps(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobStepsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobStepWithContextsPage:
+ """
+ List job steps with pagination and filtering.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobStepsListFilter]
+ Filter steps by job, status, and source.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobStepWithContextsPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.jobs.list_steps(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_steps(
+ workspace, name, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/jobs/raw_client.py b/sdks/python/jobs/raw_client.py
new file mode 100644
index 0000000000..506d9899e7
--- /dev/null
+++ b/sdks/python/jobs/raw_client.py
@@ -0,0 +1,3211 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import contextlib
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.conflict_error import ConflictError
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.file_storage_type import FileStorageType
+from ..types.platform_job_list_result_response import PlatformJobListResultResponse
+from ..types.platform_job_list_task_response import PlatformJobListTaskResponse
+from ..types.platform_job_log_page import PlatformJobLogPage
+from ..types.platform_job_response import PlatformJobResponse
+from ..types.platform_job_responses_page import PlatformJobResponsesPage
+from ..types.platform_job_result_response import PlatformJobResultResponse
+from ..types.platform_job_sort_field import PlatformJobSortField
+from ..types.platform_job_spec_input import PlatformJobSpecInput
+from ..types.platform_job_status import PlatformJobStatus
+from ..types.platform_job_status_response import PlatformJobStatusResponse
+from ..types.platform_job_step import PlatformJobStep
+from ..types.platform_job_step_with_contexts_page import PlatformJobStepWithContextsPage
+from ..types.platform_job_steps_list_filter import PlatformJobStepsListFilter
+from ..types.platform_job_task import PlatformJobTask
+from ..types.platform_jobs_list_filter import PlatformJobsListFilter
+from .types.get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item import (
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem,
+)
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawJobsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def get_execution_profiles(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]]:
+ """
+ Get all currently configured execution profiles.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/jobs/v2/execution-profiles",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem],
+ parse_obj_as(
+ type_=typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_jobs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobResponsesPage]:
+ """
+ List platform jobs with filtering and pagination.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobsListFilter]
+ Filter jobs by workspace, project, name, status, source, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponsesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=PlatformJobsListFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponsesPage,
+ parse_obj_as(
+ type_=PlatformJobResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_job(
+ self,
+ workspace: str,
+ *,
+ spec: typing.Dict[str, typing.Any],
+ platform_spec: PlatformJobSpecInput,
+ source: str,
+ name: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobResponse]:
+ """
+ Create a new platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ spec : typing.Dict[str, typing.Any]
+
+ platform_spec : PlatformJobSpecInput
+
+ source : str
+
+ name : typing.Optional[str]
+
+ description : typing.Optional[str]
+
+ project : typing.Optional[str]
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "project": project,
+ "spec": spec,
+ "platform_spec": convert_and_respect_annotation_metadata(
+ object_=platform_spec, annotation=PlatformJobSpecInput, direction="write"
+ ),
+ "source": source,
+ "ownership": ownership,
+ "custom_fields": custom_fields,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobResultResponse]:
+ """
+ Get a specific job result.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResultResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResultResponse,
+ parse_obj_as(
+ type_=PlatformJobResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_job_result(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ artifact_url: str,
+ artifact_storage_type: FileStorageType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobResultResponse]:
+ """
+ Create a new result for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ artifact_url : str
+
+ artifact_storage_type : FileStorageType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResultResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "artifact_url": artifact_url,
+ "artifact_storage_type": artifact_storage_type,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResultResponse,
+ parse_obj_as(
+ type_=PlatformJobResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ @contextlib.contextmanager
+ def download_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Download a job result file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ Successful Response
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}/download",
+ method="GET",
+ request_options=request_options,
+ ) as _response:
+
+ def _stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code,
+ headers=dict(_response.headers),
+ body=_response.json(),
+ cause=e,
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ yield _stream()
+
+ def get_job_step(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobStep]:
+ """
+ Get a specific job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobStep]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStep,
+ parse_obj_as(
+ type_=PlatformJobStep, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_job_step_status(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ status: PlatformJobStatus,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobStep]:
+ """
+ Update a job step status.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ status : PlatformJobStatus
+ The new status to set for the job.
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional status details related to the status update.
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional error details related to the status update.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobStep]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}/status",
+ method="PATCH",
+ json={
+ "status": status,
+ "status_details": status_details,
+ "error_details": error_details,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStep,
+ parse_obj_as(
+ type_=PlatformJobStep, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_job_step_tasks(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobListTaskResponse]:
+ """
+ List tasks for a job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobListTaskResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}/tasks",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobListTaskResponse,
+ parse_obj_as(
+ type_=PlatformJobListTaskResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_job_step_task(
+ self, workspace: str, job: str, step: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobTask]:
+ """
+ Get a specific job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobTask]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(step)}/tasks/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobTask,
+ parse_obj_as(
+ type_=PlatformJobTask, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_job_step_task(
+ self,
+ workspace: str,
+ job: str,
+ step: str,
+ name: str,
+ *,
+ status: typing.Optional[PlatformJobStatus] = OMIT,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_stack: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobTask]:
+ """
+ Update a job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ status : typing.Optional[PlatformJobStatus]
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_stack : typing.Optional[str]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobTask]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(step)}/tasks/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "status": status,
+ "status_details": status_details,
+ "error_details": error_details,
+ "error_stack": error_stack,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobTask,
+ parse_obj_as(
+ type_=PlatformJobTask, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobResponse]:
+ """
+ Get a platform job by name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def cancel_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobResponse]:
+ """
+ Cancel a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/cancel",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def page_job_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ limit: typing.Optional[int] = None,
+ page_cursor: typing.Optional[str] = None,
+ attempt_id: typing.Optional[int] = None,
+ step_id: typing.Optional[str] = None,
+ task_id: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobLogPage]:
+ """
+ Get paginated logs for a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ limit : typing.Optional[int]
+ Maximum number of logs to return
+
+ page_cursor : typing.Optional[str]
+ Page cursor
+
+ attempt_id : typing.Optional[int]
+ Filter logs by job attempt ID
+
+ step_id : typing.Optional[str]
+ Filter logs by step name
+
+ task_id : typing.Optional[str]
+ Filter logs by task ID
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobLogPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/logs",
+ method="GET",
+ params={
+ "limit": limit,
+ "page_cursor": page_cursor,
+ "attempt_id": attempt_id,
+ "step_id": step_id,
+ "task_id": task_id,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobLogPage,
+ parse_obj_as(
+ type_=PlatformJobLogPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def pause_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobResponse]:
+ """
+ Pause a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/pause",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_job_results(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobListResultResponse]:
+ """
+ List results for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobListResultResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/results",
+ method="GET",
+ params={
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobListResultResponse,
+ parse_obj_as(
+ type_=PlatformJobListResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def resume_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobResponse]:
+ """
+ Resume a paused platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/resume",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_job_status(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformJobStatusResponse]:
+ """
+ Get the status of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobStatusResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/status",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStatusResponse,
+ parse_obj_as(
+ type_=PlatformJobStatusResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_job_status_details(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[typing.Any]:
+ """
+ Update the status details of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Any]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/status-details",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_steps(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobStepsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobStepWithContextsPage]:
+ """
+ List job steps with pagination and filtering.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobStepsListFilter]
+ Filter steps by job, status, and source.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobStepWithContextsPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/steps",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=PlatformJobStepsListFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStepWithContextsPage,
+ parse_obj_as(
+ type_=PlatformJobStepWithContextsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawJobsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def get_execution_profiles(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]]:
+ """
+ Get all currently configured execution profiles.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/jobs/v2/execution-profiles",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem],
+ parse_obj_as(
+ type_=typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_jobs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobResponsesPage]:
+ """
+ List platform jobs with filtering and pagination.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobsListFilter]
+ Filter jobs by workspace, project, name, status, source, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponsesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=PlatformJobsListFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponsesPage,
+ parse_obj_as(
+ type_=PlatformJobResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_job(
+ self,
+ workspace: str,
+ *,
+ spec: typing.Dict[str, typing.Any],
+ platform_spec: PlatformJobSpecInput,
+ source: str,
+ name: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ project: typing.Optional[str] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobResponse]:
+ """
+ Create a new platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ spec : typing.Dict[str, typing.Any]
+
+ platform_spec : PlatformJobSpecInput
+
+ source : str
+
+ name : typing.Optional[str]
+
+ description : typing.Optional[str]
+
+ project : typing.Optional[str]
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "project": project,
+ "spec": spec,
+ "platform_spec": convert_and_respect_annotation_metadata(
+ object_=platform_spec, annotation=PlatformJobSpecInput, direction="write"
+ ),
+ "source": source,
+ "ownership": ownership,
+ "custom_fields": custom_fields,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobResultResponse]:
+ """
+ Get a specific job result.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResultResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResultResponse,
+ parse_obj_as(
+ type_=PlatformJobResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_job_result(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ artifact_url: str,
+ artifact_storage_type: FileStorageType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobResultResponse]:
+ """
+ Create a new result for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ artifact_url : str
+
+ artifact_storage_type : FileStorageType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResultResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "artifact_url": artifact_url,
+ "artifact_storage_type": artifact_storage_type,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResultResponse,
+ parse_obj_as(
+ type_=PlatformJobResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ @contextlib.asynccontextmanager
+ async def download_job_result(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Download a job result file.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ Successful Response
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/results/{encode_path_param(name)}/download",
+ method="GET",
+ request_options=request_options,
+ ) as _response:
+
+ async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code,
+ headers=dict(_response.headers),
+ body=_response.json(),
+ cause=e,
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ yield await _stream()
+
+ async def get_job_step(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobStep]:
+ """
+ Get a specific job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobStep]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStep,
+ parse_obj_as(
+ type_=PlatformJobStep, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_job_step_status(
+ self,
+ workspace: str,
+ job: str,
+ name: str,
+ *,
+ status: PlatformJobStatus,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobStep]:
+ """
+ Update a job step status.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ status : PlatformJobStatus
+ The new status to set for the job.
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional status details related to the status update.
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+ Optional error details related to the status update.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobStep]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}/status",
+ method="PATCH",
+ json={
+ "status": status,
+ "status_details": status_details,
+ "error_details": error_details,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStep,
+ parse_obj_as(
+ type_=PlatformJobStep, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_job_step_tasks(
+ self, workspace: str, job: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobListTaskResponse]:
+ """
+ List tasks for a job step.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobListTaskResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(name)}/tasks",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobListTaskResponse,
+ parse_obj_as(
+ type_=PlatformJobListTaskResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_job_step_task(
+ self, workspace: str, job: str, step: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobTask]:
+ """
+ Get a specific job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobTask]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(step)}/tasks/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobTask,
+ parse_obj_as(
+ type_=PlatformJobTask, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_job_step_task(
+ self,
+ workspace: str,
+ job: str,
+ step: str,
+ name: str,
+ *,
+ status: typing.Optional[PlatformJobStatus] = OMIT,
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ error_stack: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobTask]:
+ """
+ Update a job step task.
+
+ Parameters
+ ----------
+ workspace : str
+
+ job : str
+
+ step : str
+
+ name : str
+
+ status : typing.Optional[PlatformJobStatus]
+
+ status_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_details : typing.Optional[typing.Dict[str, typing.Any]]
+
+ error_stack : typing.Optional[str]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobTask]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(job)}/steps/{encode_path_param(step)}/tasks/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "status": status,
+ "status_details": status_details,
+ "error_details": error_details,
+ "error_stack": error_stack,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobTask,
+ parse_obj_as(
+ type_=PlatformJobTask, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobResponse]:
+ """
+ Get a platform job by name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def cancel_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobResponse]:
+ """
+ Cancel a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/cancel",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def page_job_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ limit: typing.Optional[int] = None,
+ page_cursor: typing.Optional[str] = None,
+ attempt_id: typing.Optional[int] = None,
+ step_id: typing.Optional[str] = None,
+ task_id: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobLogPage]:
+ """
+ Get paginated logs for a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ limit : typing.Optional[int]
+ Maximum number of logs to return
+
+ page_cursor : typing.Optional[str]
+ Page cursor
+
+ attempt_id : typing.Optional[int]
+ Filter logs by job attempt ID
+
+ step_id : typing.Optional[str]
+ Filter logs by step name
+
+ task_id : typing.Optional[str]
+ Filter logs by task ID
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobLogPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/logs",
+ method="GET",
+ params={
+ "limit": limit,
+ "page_cursor": page_cursor,
+ "attempt_id": attempt_id,
+ "step_id": step_id,
+ "task_id": task_id,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobLogPage,
+ parse_obj_as(
+ type_=PlatformJobLogPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def pause_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobResponse]:
+ """
+ Pause a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/pause",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_job_results(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobListResultResponse]:
+ """
+ List results for a job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobListResultResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/results",
+ method="GET",
+ params={
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobListResultResponse,
+ parse_obj_as(
+ type_=PlatformJobListResultResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def resume_job(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobResponse]:
+ """
+ Resume a paused platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/resume",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobResponse,
+ parse_obj_as(
+ type_=PlatformJobResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_job_status(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformJobStatusResponse]:
+ """
+ Get the status of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobStatusResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/status",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStatusResponse,
+ parse_obj_as(
+ type_=PlatformJobStatusResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_job_status_details(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ request: typing.Dict[str, typing.Any],
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[typing.Any]:
+ """
+ Update the status details of a platform job.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request : typing.Dict[str, typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Any]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/status-details",
+ method="PATCH",
+ json=request,
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_steps(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[PlatformJobSortField] = None,
+ filter: typing.Optional[PlatformJobStepsListFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobStepWithContextsPage]:
+ """
+ List job steps with pagination and filtering.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[PlatformJobSortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[PlatformJobStepsListFilter]
+ Filter steps by job, status, and source.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobStepWithContextsPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/jobs/v2/workspaces/{encode_path_param(workspace)}/jobs/{encode_path_param(name)}/steps",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=PlatformJobStepsListFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobStepWithContextsPage,
+ parse_obj_as(
+ type_=PlatformJobStepWithContextsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/jobs/types/__init__.py b/sdks/python/jobs/types/__init__.py
new file mode 100644
index 0000000000..98d38eb72d
--- /dev/null
+++ b/sdks/python/jobs/types/__init__.py
@@ -0,0 +1,55 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item import (
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob": ".get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess",
+ "GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob",
+]
diff --git a/sdks/python/jobs/types/get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item.py b/sdks/python/jobs/types/get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item.py
new file mode 100644
index 0000000000..93b2e13ba5
--- /dev/null
+++ b/sdks/python/jobs/types/get_execution_profiles_apis_jobs_v2execution_profiles_get_response_item.py
@@ -0,0 +1,107 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ...types.docker_job_execution_profile_config import DockerJobExecutionProfileConfig
+from ...types.job_execution_profile_config import JobExecutionProfileConfig
+from ...types.kubernetes_job_execution_profile_config import KubernetesJobExecutionProfileConfig
+from ...types.subprocess_job_execution_profile_config import SubprocessJobExecutionProfileConfig
+from ...types.subprocess_job_execution_profile_provider import SubprocessJobExecutionProfileProvider
+from ...types.volcano_job_execution_profile_config import VolcanoJobExecutionProfileConfig
+
+
+class GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker(UniversalBaseModel):
+ backend: typing.Literal["docker"] = "docker"
+ provider: typing.Optional[str] = None
+ profile: typing.Optional[str] = None
+ config: DockerJobExecutionProfileConfig
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob(UniversalBaseModel):
+ backend: typing.Literal["kubernetes_job"] = "kubernetes_job"
+ provider: typing.Optional[str] = None
+ profile: typing.Optional[str] = None
+ config: KubernetesJobExecutionProfileConfig
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob(UniversalBaseModel):
+ backend: typing.Literal["volcano_job"] = "volcano_job"
+ provider: typing.Optional[str] = None
+ profile: typing.Optional[str] = None
+ config: VolcanoJobExecutionProfileConfig
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess(UniversalBaseModel):
+ backend: typing.Literal["subprocess"] = "subprocess"
+ provider: typing.Optional[SubprocessJobExecutionProfileProvider] = None
+ profile: typing.Optional[str] = None
+ config: typing.Optional[SubprocessJobExecutionProfileConfig] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E(UniversalBaseModel):
+ backend: typing.Literal["e2e"] = "e2e"
+ provider: typing.Optional[str] = None
+ profile: typing.Optional[str] = None
+ config: typing.Optional[JobExecutionProfileConfig] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem = typing_extensions.Annotated[
+ typing.Union[
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Docker,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_KubernetesJob,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_VolcanoJob,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_Subprocess,
+ GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem_E2E,
+ ],
+ pydantic.Field(discriminator="backend"),
+]
diff --git a/sdks/python/model_deployment_configs/__init__.py b/sdks/python/model_deployment_configs/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/model_deployment_configs/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/model_deployment_configs/client.py b/sdks/python/model_deployment_configs/client.py
new file mode 100644
index 0000000000..4d1bde647d
--- /dev/null
+++ b/sdks/python/model_deployment_configs/client.py
@@ -0,0 +1,930 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.container_executor_config import ContainerExecutorConfig
+from ..types.engine import Engine
+from ..types.model_deployment_config import ModelDeploymentConfig
+from ..types.model_deployment_config_filter import ModelDeploymentConfigFilter
+from ..types.model_deployment_config_model_spec import ModelDeploymentConfigModelSpec
+from ..types.model_deployment_configs_page import ModelDeploymentConfigsPage
+from .raw_client import AsyncRawModelDeploymentConfigsClient, RawModelDeploymentConfigsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ModelDeploymentConfigsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawModelDeploymentConfigsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawModelDeploymentConfigsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawModelDeploymentConfigsClient
+ """
+ return self._raw_client
+
+ def list_deployment_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[ModelDeploymentConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfigsPage:
+ """
+ List ModelDeploymentConfigs for a specific workspace.
+ Returns only the latest version of each config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelDeploymentConfigFilter]
+ Filter deployment configs by workspace, project, model_entity_id, name, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfigsPage
+ Return model deployment configurations for a workspace
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.list_deployment_configs(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_deployment_configs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_deployment_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfig:
+ """
+ Create a new ModelDeploymentConfig (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment configuration. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment configuration
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Create a new model deployment configuration
+
+ Examples
+ --------
+ from nvidia import (
+ ContainerExecutorConfig,
+ ModelDeploymentConfigModelSpec,
+ NvidiaApi,
+ )
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.create_deployment_config(
+ workspace="workspace",
+ name="nim-config-v1",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+ )
+ """
+ _response = self._raw_client.create_deployment_config(
+ workspace,
+ name=name,
+ engine=engine,
+ model_spec=model_spec,
+ executor_config=executor_config,
+ project=project,
+ description=description,
+ model_entity_id=model_entity_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeploymentConfig:
+ """
+ Get a specific version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Return a specific version of a model deployment configuration
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.get_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_deployment_config_version(
+ workspace, config, name, request_options=request_options
+ )
+ return _response.data
+
+ def delete_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a specific version of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this specific version and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.delete_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_deployment_config_version(
+ workspace, config, name, request_options=request_options
+ )
+ return _response.data
+
+ def get_latest_deployment_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeploymentConfig:
+ """
+ Get the latest version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Return the latest version of a model deployment configuration
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.get_latest_deployment_config(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_latest_deployment_config(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_deployment_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfig:
+ """
+ Update a ModelDeploymentConfig (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Update a model deployment configuration (creates new version)
+
+ Examples
+ --------
+ from nvidia import (
+ ContainerExecutorConfig,
+ ModelDeploymentConfigModelSpec,
+ NvidiaApi,
+ )
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.update_deployment_config(
+ workspace="workspace",
+ name="name",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+ )
+ """
+ _response = self._raw_client.update_deployment_config(
+ workspace,
+ name,
+ engine=engine,
+ model_spec=model_spec,
+ executor_config=executor_config,
+ description=description,
+ model_entity_id=model_entity_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def delete_all_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete all versions of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this config and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.delete_all_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_all_deployment_config_versions(
+ workspace, name, request_options=request_options
+ )
+ return _response.data
+
+ def list_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[ModelDeploymentConfig]:
+ """
+ List all versions of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[ModelDeploymentConfig]
+ Return all versions of a model deployment configuration
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployment_configs.list_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_deployment_config_versions(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncModelDeploymentConfigsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawModelDeploymentConfigsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawModelDeploymentConfigsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawModelDeploymentConfigsClient
+ """
+ return self._raw_client
+
+ async def list_deployment_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[ModelDeploymentConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfigsPage:
+ """
+ List ModelDeploymentConfigs for a specific workspace.
+ Returns only the latest version of each config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelDeploymentConfigFilter]
+ Filter deployment configs by workspace, project, model_entity_id, name, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfigsPage
+ Return model deployment configurations for a workspace
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.list_deployment_configs(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_deployment_configs(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_deployment_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfig:
+ """
+ Create a new ModelDeploymentConfig (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment configuration. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment configuration
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Create a new model deployment configuration
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import (
+ AsyncNvidiaApi,
+ ContainerExecutorConfig,
+ ModelDeploymentConfigModelSpec,
+ )
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.create_deployment_config(
+ workspace="workspace",
+ name="nim-config-v1",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_deployment_config(
+ workspace,
+ name=name,
+ engine=engine,
+ model_spec=model_spec,
+ executor_config=executor_config,
+ project=project,
+ description=description,
+ model_entity_id=model_entity_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeploymentConfig:
+ """
+ Get a specific version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Return a specific version of a model deployment configuration
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.get_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_deployment_config_version(
+ workspace, config, name, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a specific version of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this specific version and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.delete_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_deployment_config_version(
+ workspace, config, name, request_options=request_options
+ )
+ return _response.data
+
+ async def get_latest_deployment_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeploymentConfig:
+ """
+ Get the latest version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Return the latest version of a model deployment configuration
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.get_latest_deployment_config(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_latest_deployment_config(
+ workspace, name, request_options=request_options
+ )
+ return _response.data
+
+ async def update_deployment_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentConfig:
+ """
+ Update a ModelDeploymentConfig (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentConfig
+ Update a model deployment configuration (creates new version)
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import (
+ AsyncNvidiaApi,
+ ContainerExecutorConfig,
+ ModelDeploymentConfigModelSpec,
+ )
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.update_deployment_config(
+ workspace="workspace",
+ name="name",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_deployment_config(
+ workspace,
+ name,
+ engine=engine,
+ model_spec=model_spec,
+ executor_config=executor_config,
+ description=description,
+ model_entity_id=model_entity_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def delete_all_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete all versions of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this config and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.delete_all_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_all_deployment_config_versions(
+ workspace, name, request_options=request_options
+ )
+ return _response.data
+
+ async def list_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[ModelDeploymentConfig]:
+ """
+ List all versions of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[ModelDeploymentConfig]
+ Return all versions of a model deployment configuration
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployment_configs.list_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_deployment_config_versions(
+ workspace, name, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/model_deployment_configs/raw_client.py b/sdks/python/model_deployment_configs/raw_client.py
new file mode 100644
index 0000000000..9e7f3c2860
--- /dev/null
+++ b/sdks/python/model_deployment_configs/raw_client.py
@@ -0,0 +1,1218 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.conflict_error import ConflictError
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.container_executor_config import ContainerExecutorConfig
+from ..types.engine import Engine
+from ..types.model_deployment_config import ModelDeploymentConfig
+from ..types.model_deployment_config_filter import ModelDeploymentConfigFilter
+from ..types.model_deployment_config_model_spec import ModelDeploymentConfigModelSpec
+from ..types.model_deployment_configs_page import ModelDeploymentConfigsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawModelDeploymentConfigsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_deployment_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[ModelDeploymentConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeploymentConfigsPage]:
+ """
+ List ModelDeploymentConfigs for a specific workspace.
+ Returns only the latest version of each config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelDeploymentConfigFilter]
+ Filter deployment configs by workspace, project, model_entity_id, name, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentConfigsPage]
+ Return model deployment configurations for a workspace
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelDeploymentConfigFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfigsPage,
+ parse_obj_as(
+ type_=ModelDeploymentConfigsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_deployment_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeploymentConfig]:
+ """
+ Create a new ModelDeploymentConfig (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment configuration. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment configuration
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentConfig]
+ Create a new model deployment configuration
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "engine": engine,
+ "model_spec": convert_and_respect_annotation_metadata(
+ object_=model_spec, annotation=ModelDeploymentConfigModelSpec, direction="write"
+ ),
+ "executor_config": convert_and_respect_annotation_metadata(
+ object_=executor_config, annotation=ContainerExecutorConfig, direction="write"
+ ),
+ "model_entity_id": model_entity_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ModelDeploymentConfig]:
+ """
+ Get a specific version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentConfig]
+ Return a specific version of a model deployment configuration
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(config)}/versions/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete a specific version of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this specific version and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(config)}/versions/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_latest_deployment_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ModelDeploymentConfig]:
+ """
+ Get the latest version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentConfig]
+ Return the latest version of a model deployment configuration
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_deployment_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeploymentConfig]:
+ """
+ Update a ModelDeploymentConfig (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentConfig]
+ Update a model deployment configuration (creates new version)
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "description": description,
+ "engine": engine,
+ "model_spec": convert_and_respect_annotation_metadata(
+ object_=model_spec, annotation=ModelDeploymentConfigModelSpec, direction="write"
+ ),
+ "executor_config": convert_and_respect_annotation_metadata(
+ object_=executor_config, annotation=ContainerExecutorConfig, direction="write"
+ ),
+ "model_entity_id": model_entity_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_all_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete all versions of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this config and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.List[ModelDeploymentConfig]]:
+ """
+ List all versions of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.List[ModelDeploymentConfig]]
+ Return all versions of a model deployment configuration
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}/versions",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[ModelDeploymentConfig],
+ parse_obj_as(
+ type_=typing.List[ModelDeploymentConfig], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawModelDeploymentConfigsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_deployment_configs(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ filter: typing.Optional[ModelDeploymentConfigFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeploymentConfigsPage]:
+ """
+ List ModelDeploymentConfigs for a specific workspace.
+ Returns only the latest version of each config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelDeploymentConfigFilter]
+ Filter deployment configs by workspace, project, model_entity_id, name, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentConfigsPage]
+ Return model deployment configurations for a workspace
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelDeploymentConfigFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfigsPage,
+ parse_obj_as(
+ type_=ModelDeploymentConfigsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_deployment_config(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeploymentConfig]:
+ """
+ Create a new ModelDeploymentConfig (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment configuration. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment configuration
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentConfig]
+ Create a new model deployment configuration
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "engine": engine,
+ "model_spec": convert_and_respect_annotation_metadata(
+ object_=model_spec, annotation=ModelDeploymentConfigModelSpec, direction="write"
+ ),
+ "executor_config": convert_and_respect_annotation_metadata(
+ object_=executor_config, annotation=ContainerExecutorConfig, direction="write"
+ ),
+ "model_entity_id": model_entity_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ModelDeploymentConfig]:
+ """
+ Get a specific version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentConfig]
+ Return a specific version of a model deployment configuration
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(config)}/versions/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_deployment_config_version(
+ self, workspace: str, config: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete a specific version of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this specific version and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ config : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(config)}/versions/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_latest_deployment_config(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ModelDeploymentConfig]:
+ """
+ Get the latest version of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentConfig]
+ Return the latest version of a model deployment configuration
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_deployment_config(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ engine: Engine,
+ model_spec: ModelDeploymentConfigModelSpec,
+ executor_config: ContainerExecutorConfig,
+ description: typing.Optional[str] = OMIT,
+ model_entity_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeploymentConfig]:
+ """
+ Update a ModelDeploymentConfig (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ engine : Engine
+ Inference engine selecting the compiler path (nim/vllm/generic)
+
+ model_spec : ModelDeploymentConfigModelSpec
+ What model to serve and how -- independent of the executor it runs on
+
+ executor_config : ContainerExecutorConfig
+ Compute + container settings for the executor the deployment runs on
+
+ description : typing.Optional[str]
+ Optional description of the deployment configuration
+
+ model_entity_id : typing.Optional[str]
+ Optional reference to the base model entity ID for this deployment
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentConfig]
+ Update a model deployment configuration (creates new version)
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "description": description,
+ "engine": engine,
+ "model_spec": convert_and_respect_annotation_metadata(
+ object_=model_spec, annotation=ModelDeploymentConfigModelSpec, direction="write"
+ ),
+ "executor_config": convert_and_respect_annotation_metadata(
+ object_=executor_config, annotation=ContainerExecutorConfig, direction="write"
+ ),
+ "model_entity_id": model_entity_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentConfig,
+ parse_obj_as(
+ type_=ModelDeploymentConfig, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_all_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete all versions of a ModelDeploymentConfig.
+
+ This operation will fail with 409 Conflict if any ModelDeployments currently
+ reference this config and are not in DELETED status. Delete or wait for
+ dependent deployments to reach DELETED status before deleting the config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_deployment_config_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.List[ModelDeploymentConfig]]:
+ """
+ List all versions of a ModelDeploymentConfig.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.List[ModelDeploymentConfig]]
+ Return all versions of a model deployment configuration
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployment-configs/{encode_path_param(name)}/versions",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[ModelDeploymentConfig],
+ parse_obj_as(
+ type_=typing.List[ModelDeploymentConfig], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/model_deployments/__init__.py b/sdks/python/model_deployments/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/model_deployments/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/model_deployments/client.py b/sdks/python/model_deployments/client.py
new file mode 100644
index 0000000000..3a03ca3782
--- /dev/null
+++ b/sdks/python/model_deployments/client.py
@@ -0,0 +1,1106 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.model_deployment import ModelDeployment
+from ..types.model_deployment_filter import ModelDeploymentFilter
+from ..types.model_deployment_status import ModelDeploymentStatus
+from ..types.model_deployments_page import ModelDeploymentsPage
+from .raw_client import AsyncRawModelDeploymentsClient, RawModelDeploymentsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ModelDeploymentsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawModelDeploymentsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawModelDeploymentsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawModelDeploymentsClient
+ """
+ return self._raw_client
+
+ def list_deployments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ all_versions: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelDeploymentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentsPage:
+ """
+ List ModelDeployments for a specific workspace.
+
+ By default, returns only the latest version of each deployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ all_versions : typing.Optional[bool]
+ If true, return all versions of each deployment. If false (default), return only the latest version.
+
+ filter : typing.Optional[ModelDeploymentFilter]
+ Filter deployments by workspace, project, status, config, model_provider_id, name, status_message, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentsPage
+ Return model deployments for a workspace
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.list_deployments(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_deployments(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ all_versions=all_versions,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def create_deployment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ config: str,
+ project: typing.Optional[str] = OMIT,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Create a new ModelDeployment (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Create a new model deployment
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.create_deployment(
+ workspace="workspace",
+ name="llama-deploy-v1",
+ config="config",
+ )
+ """
+ _response = self._raw_client.create_deployment(
+ workspace,
+ name=name,
+ config=config,
+ project=project,
+ config_version=config_version,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeployment:
+ """
+ Get a specific version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Return a specific version of a model deployment
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.get_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_deployment_version(
+ workspace, deployment, name, request_options=request_options
+ )
+ return _response.data
+
+ def delete_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Optional[typing.Any]:
+ """
+ Delete a specific version of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment version marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment version permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment version doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Optional[typing.Any]
+ Deployment version marked for deletion (DELETING status)
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.delete_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_deployment_version(
+ workspace, deployment, name, request_options=request_options
+ )
+ return _response.data
+
+ def get_latest_deployment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeployment:
+ """
+ Get the latest version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Return the latest version of a model deployment
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.get_latest_deployment(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_latest_deployment(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_deployment(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ config: str,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Update a ModelDeployment (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Update a model deployment (creates new version)
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.update_deployment(
+ workspace="workspace",
+ name="name",
+ config="config",
+ )
+ """
+ _response = self._raw_client.update_deployment(
+ workspace, name, config=config, config_version=config_version, request_options=request_options
+ )
+ return _response.data
+
+ def delete_all_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Optional[typing.Any]:
+ """
+ Delete all versions of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Optional[typing.Any]
+ Deployment marked for deletion (DELETING status)
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.delete_all_deployment_versions(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_all_deployment_versions(workspace, name, request_options=request_options)
+ return _response.data
+
+ def get_deployment_models(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Get Latest ModelDeployment's Model Entities from Entity Store.
+ This provides the API contract that NIMs expect from Entity Store today, for pulling LoRAs,
+ but enables us to enforce AuthZ boundaries.
+
+ TODO: Implement model entity retrieval based on deployment config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Return model entities from Entity Store for the latest deployment
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.get_deployment_models(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_deployment_models(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_deployment_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ status: ModelDeploymentStatus,
+ version: typing.Optional[str] = None,
+ status_message: typing.Optional[str] = OMIT,
+ model_provider_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Update the status of a ModelDeployment (mutable operation).
+ If version is not specified, updates the latest version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ status : ModelDeploymentStatus
+ New status for the deployment
+
+ version : typing.Optional[str]
+
+ status_message : typing.Optional[str]
+ Detailed status message
+
+ model_provider_id : typing.Optional[str]
+ Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Update ModelDeployment status and status_message
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.update_deployment_status(
+ workspace="workspace",
+ name="name",
+ status="UNKNOWN",
+ )
+ """
+ _response = self._raw_client.update_deployment_status(
+ workspace,
+ name,
+ status=status,
+ version=version,
+ status_message=status_message,
+ model_provider_id=model_provider_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def list_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[ModelDeployment]:
+ """
+ List all versions of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[ModelDeployment]
+ Return all versions of a model deployment
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_deployments.list_deployment_versions(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.list_deployment_versions(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncModelDeploymentsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawModelDeploymentsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawModelDeploymentsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawModelDeploymentsClient
+ """
+ return self._raw_client
+
+ async def list_deployments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ all_versions: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelDeploymentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeploymentsPage:
+ """
+ List ModelDeployments for a specific workspace.
+
+ By default, returns only the latest version of each deployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ all_versions : typing.Optional[bool]
+ If true, return all versions of each deployment. If false (default), return only the latest version.
+
+ filter : typing.Optional[ModelDeploymentFilter]
+ Filter deployments by workspace, project, status, config, model_provider_id, name, status_message, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeploymentsPage
+ Return model deployments for a workspace
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.list_deployments(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_deployments(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ all_versions=all_versions,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def create_deployment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ config: str,
+ project: typing.Optional[str] = OMIT,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Create a new ModelDeployment (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Create a new model deployment
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.create_deployment(
+ workspace="workspace",
+ name="llama-deploy-v1",
+ config="config",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_deployment(
+ workspace,
+ name=name,
+ config=config,
+ project=project,
+ config_version=config_version,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeployment:
+ """
+ Get a specific version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Return a specific version of a model deployment
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.get_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_deployment_version(
+ workspace, deployment, name, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Optional[typing.Any]:
+ """
+ Delete a specific version of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment version marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment version permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment version doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Optional[typing.Any]
+ Deployment version marked for deletion (DELETING status)
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.delete_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_deployment_version(
+ workspace, deployment, name, request_options=request_options
+ )
+ return _response.data
+
+ async def get_latest_deployment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelDeployment:
+ """
+ Get the latest version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Return the latest version of a model deployment
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.get_latest_deployment(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_latest_deployment(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_deployment(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ config: str,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Update a ModelDeployment (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Update a model deployment (creates new version)
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.update_deployment(
+ workspace="workspace",
+ name="name",
+ config="config",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_deployment(
+ workspace, name, config=config, config_version=config_version, request_options=request_options
+ )
+ return _response.data
+
+ async def delete_all_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Optional[typing.Any]:
+ """
+ Delete all versions of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Optional[typing.Any]
+ Deployment marked for deletion (DELETING status)
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.delete_all_deployment_versions(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_all_deployment_versions(
+ workspace, name, request_options=request_options
+ )
+ return _response.data
+
+ async def get_deployment_models(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.Dict[str, typing.Any]:
+ """
+ Get Latest ModelDeployment's Model Entities from Entity Store.
+ This provides the API contract that NIMs expect from Entity Store today, for pulling LoRAs,
+ but enables us to enforce AuthZ boundaries.
+
+ TODO: Implement model entity retrieval based on deployment config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.Dict[str, typing.Any]
+ Return model entities from Entity Store for the latest deployment
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.get_deployment_models(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_deployment_models(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_deployment_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ status: ModelDeploymentStatus,
+ version: typing.Optional[str] = None,
+ status_message: typing.Optional[str] = OMIT,
+ model_provider_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelDeployment:
+ """
+ Update the status of a ModelDeployment (mutable operation).
+ If version is not specified, updates the latest version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ status : ModelDeploymentStatus
+ New status for the deployment
+
+ version : typing.Optional[str]
+
+ status_message : typing.Optional[str]
+ Detailed status message
+
+ model_provider_id : typing.Optional[str]
+ Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelDeployment
+ Update ModelDeployment status and status_message
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.update_deployment_status(
+ workspace="workspace",
+ name="name",
+ status="UNKNOWN",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_deployment_status(
+ workspace,
+ name,
+ status=status,
+ version=version,
+ status_message=status_message,
+ model_provider_id=model_provider_id,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def list_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> typing.List[ModelDeployment]:
+ """
+ List all versions of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ typing.List[ModelDeployment]
+ Return all versions of a model deployment
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_deployments.list_deployment_versions(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_deployment_versions(workspace, name, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/model_deployments/raw_client.py b/sdks/python/model_deployments/raw_client.py
new file mode 100644
index 0000000000..2d9f1250d7
--- /dev/null
+++ b/sdks/python/model_deployments/raw_client.py
@@ -0,0 +1,1475 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.model_deployment import ModelDeployment
+from ..types.model_deployment_filter import ModelDeploymentFilter
+from ..types.model_deployment_status import ModelDeploymentStatus
+from ..types.model_deployments_page import ModelDeploymentsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawModelDeploymentsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_deployments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ all_versions: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelDeploymentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeploymentsPage]:
+ """
+ List ModelDeployments for a specific workspace.
+
+ By default, returns only the latest version of each deployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ all_versions : typing.Optional[bool]
+ If true, return all versions of each deployment. If false (default), return only the latest version.
+
+ filter : typing.Optional[ModelDeploymentFilter]
+ Filter deployments by workspace, project, status, config, model_provider_id, name, status_message, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeploymentsPage]
+ Return model deployments for a workspace
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "all_versions": all_versions,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelDeploymentFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentsPage,
+ parse_obj_as(
+ type_=ModelDeploymentsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_deployment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ config: str,
+ project: typing.Optional[str] = OMIT,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeployment]:
+ """
+ Create a new ModelDeployment (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeployment]
+ Create a new model deployment
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "config": config,
+ "config_version": config_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ModelDeployment]:
+ """
+ Get a specific version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeployment]
+ Return a specific version of a model deployment
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(deployment)}/versions/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
+ """
+ Delete a specific version of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment version marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment version permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment version doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Optional[typing.Any]]
+ Deployment version marked for deletion (DELETING status)
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(deployment)}/versions/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_latest_deployment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ModelDeployment]:
+ """
+ Get the latest version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeployment]
+ Return the latest version of a model deployment
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_deployment(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ config: str,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeployment]:
+ """
+ Update a ModelDeployment (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeployment]
+ Update a model deployment (creates new version)
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "config": config,
+ "config_version": config_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_all_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
+ """
+ Delete all versions of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Optional[typing.Any]]
+ Deployment marked for deletion (DELETING status)
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return HttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_deployment_models(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Get Latest ModelDeployment's Model Entities from Entity Store.
+ This provides the API contract that NIMs expect from Entity Store today, for pulling LoRAs,
+ but enables us to enforce AuthZ boundaries.
+
+ TODO: Implement model entity retrieval based on deployment config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.Dict[str, typing.Any]]
+ Return model entities from Entity Store for the latest deployment
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/models",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_deployment_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ status: ModelDeploymentStatus,
+ version: typing.Optional[str] = None,
+ status_message: typing.Optional[str] = OMIT,
+ model_provider_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelDeployment]:
+ """
+ Update the status of a ModelDeployment (mutable operation).
+ If version is not specified, updates the latest version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ status : ModelDeploymentStatus
+ New status for the deployment
+
+ version : typing.Optional[str]
+
+ status_message : typing.Optional[str]
+ Detailed status message
+
+ model_provider_id : typing.Optional[str]
+ Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelDeployment]
+ Update ModelDeployment status and status_message
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/status",
+ method="POST",
+ params={
+ "version": version,
+ },
+ json={
+ "status": status,
+ "status_message": status_message,
+ "model_provider_id": model_provider_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def list_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[typing.List[ModelDeployment]]:
+ """
+ List all versions of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[typing.List[ModelDeployment]]
+ Return all versions of a model deployment
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/versions",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[ModelDeployment],
+ parse_obj_as(
+ type_=typing.List[ModelDeployment], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawModelDeploymentsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_deployments(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ all_versions: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelDeploymentFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeploymentsPage]:
+ """
+ List ModelDeployments for a specific workspace.
+
+ By default, returns only the latest version of each deployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[str]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ all_versions : typing.Optional[bool]
+ If true, return all versions of each deployment. If false (default), return only the latest version.
+
+ filter : typing.Optional[ModelDeploymentFilter]
+ Filter deployments by workspace, project, status, config, model_provider_id, name, status_message, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeploymentsPage]
+ Return model deployments for a workspace
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "all_versions": all_versions,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelDeploymentFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeploymentsPage,
+ parse_obj_as(
+ type_=ModelDeploymentsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_deployment(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ config: str,
+ project: typing.Optional[str] = OMIT,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeployment]:
+ """
+ Create a new ModelDeployment (version 1).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the deployment. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ project : typing.Optional[str]
+ The URN of the project associated with this deployment
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeployment]
+ Create a new model deployment
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "config": config,
+ "config_version": config_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ModelDeployment]:
+ """
+ Get a specific version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeployment]
+ Return a specific version of a model deployment
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(deployment)}/versions/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_deployment_version(
+ self, workspace: str, deployment: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
+ """
+ Delete a specific version of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment version marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment version permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment version doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ deployment : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Optional[typing.Any]]
+ Deployment version marked for deletion (DELETING status)
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(deployment)}/versions/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_latest_deployment(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ModelDeployment]:
+ """
+ Get the latest version of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeployment]
+ Return the latest version of a model deployment
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_deployment(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ config: str,
+ config_version: typing.Optional[int] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeployment]:
+ """
+ Update a ModelDeployment (creates a new immutable version).
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ config : str
+ Reference to the ModelDeploymentConfig name
+
+ config_version : typing.Optional[int]
+ Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeployment]
+ Update a model deployment (creates new version)
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="POST",
+ json={
+ "config": config,
+ "config_version": config_version,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_all_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
+ """
+ Delete all versions of a ModelDeployment.
+
+ If the deployment is in any state other than DELETED, this will set its status to DELETING.
+ The models controller will then:
+ 1. Delete the infrastructure (e.g., K8s NimService)
+ 2. Update the status to DELETED
+
+ If the deployment is already in DELETED status, calling delete again will permanently
+ remove it from the database.
+
+ Returns:
+ - 202 Accepted: Deployment marked for deletion (status set to DELETING)
+ - 204 No Content: Deployment permanently removed from database (was already DELETED)
+ - 404 Not Found: Deployment doesn't exist
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Optional[typing.Any]]
+ Deployment marked for deletion (DELETING status)
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if _response is None or not _response.text.strip():
+ return AsyncHttpResponse(response=_response, data=None)
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_deployment_models(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
+ """
+ Get Latest ModelDeployment's Model Entities from Entity Store.
+ This provides the API contract that NIMs expect from Entity Store today, for pulling LoRAs,
+ but enables us to enforce AuthZ boundaries.
+
+ TODO: Implement model entity retrieval based on deployment config.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.Dict[str, typing.Any]]
+ Return model entities from Entity Store for the latest deployment
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/models",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.Dict[str, typing.Any],
+ parse_obj_as(
+ type_=typing.Dict[str, typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_deployment_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ status: ModelDeploymentStatus,
+ version: typing.Optional[str] = None,
+ status_message: typing.Optional[str] = OMIT,
+ model_provider_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelDeployment]:
+ """
+ Update the status of a ModelDeployment (mutable operation).
+ If version is not specified, updates the latest version.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ status : ModelDeploymentStatus
+ New status for the deployment
+
+ version : typing.Optional[str]
+
+ status_message : typing.Optional[str]
+ Detailed status message
+
+ model_provider_id : typing.Optional[str]
+ Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelDeployment]
+ Update ModelDeployment status and status_message
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/status",
+ method="POST",
+ params={
+ "version": version,
+ },
+ json={
+ "status": status,
+ "status_message": status_message,
+ "model_provider_id": model_provider_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelDeployment,
+ parse_obj_as(
+ type_=ModelDeployment, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def list_deployment_versions(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[typing.List[ModelDeployment]]:
+ """
+ List all versions of a ModelDeployment.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[typing.List[ModelDeployment]]
+ Return all versions of a model deployment
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/deployments/{encode_path_param(name)}/versions",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ typing.List[ModelDeployment],
+ parse_obj_as(
+ type_=typing.List[ModelDeployment], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/model_providers/__init__.py b/sdks/python/model_providers/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/model_providers/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/model_providers/client.py b/sdks/python/model_providers/client.py
new file mode 100644
index 0000000000..9eb81f600e
--- /dev/null
+++ b/sdks/python/model_providers/client.py
@@ -0,0 +1,920 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.model_provider import ModelProvider
+from ..types.model_provider_filter import ModelProviderFilter
+from ..types.model_provider_sort import ModelProviderSort
+from ..types.model_provider_status import ModelProviderStatus
+from ..types.model_providers_page import ModelProvidersPage
+from ..types.served_model_mapping import ServedModelMapping
+from .raw_client import AsyncRawModelProvidersClient, RawModelProvidersClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ModelProvidersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawModelProvidersClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawModelProvidersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawModelProvidersClient
+ """
+ return self._raw_client
+
+ def list_providers(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelProviderSort] = None,
+ filter: typing.Optional[ModelProviderFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvidersPage:
+ """
+ List model providers for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelProviderSort]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelProviderFilter]
+ Filter model providers by workspace, project, status, model_deployment_id, name, description, host_url, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvidersPage
+ Return model providers for a workspace
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.list_providers(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_providers(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ def create_provider(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Create a new model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model provider. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is being auto-created for a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Create a new model provider
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.create_provider(
+ workspace="workspace",
+ name="my-nim-provider",
+ host_url="host_url",
+ )
+ """
+ _response = self._raw_client.create_provider(
+ workspace,
+ name=name,
+ host_url=host_url,
+ project=project,
+ description=description,
+ api_key_secret_name=api_key_secret_name,
+ enabled_models=enabled_models,
+ default_extra_body=default_extra_body,
+ default_extra_headers=default_extra_headers,
+ required_extra_body=required_extra_body,
+ required_extra_headers=required_extra_headers,
+ model_deployment_id=model_deployment_id,
+ status=status,
+ status_message=status_message,
+ auth_header_format=auth_header_format,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelProvider:
+ """
+ Get a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Return model provider details
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.get_provider(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_provider(workspace, name, request_options=request_options)
+ return _response.data
+
+ def upsert_provider(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Create or update a model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Create or update a model provider
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.upsert_provider(
+ workspace="workspace",
+ name="name",
+ host_url="host_url",
+ )
+ """
+ _response = self._raw_client.upsert_provider(
+ workspace,
+ name,
+ host_url=host_url,
+ project=project,
+ description=description,
+ api_key_secret_name=api_key_secret_name,
+ enabled_models=enabled_models,
+ default_extra_body=default_extra_body,
+ default_extra_headers=default_extra_headers,
+ required_extra_body=required_extra_body,
+ required_extra_headers=required_extra_headers,
+ model_deployment_id=model_deployment_id,
+ status=status,
+ status_message=status_message,
+ auth_header_format=auth_header_format,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def delete_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.delete_provider(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_provider(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_provider_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ served_models: typing.Optional[typing.Sequence[ServedModelMapping]] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Update status-related fields of a model provider.
+
+ This endpoint supports partial updates for fields managed by Models Controller:
+ - model_deployment_id
+ - served_models
+ - status
+ - status_message
+
+ If status is provided without status_message, status_message will be set to empty string.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ model_deployment_id : typing.Optional[str]
+ Reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ served_models : typing.Optional[typing.Sequence[ServedModelMapping]]
+ List of models served by this provider with routing information for IGW
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message. If status is provided without status_message, defaults to empty string.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Update status-related fields of a model provider
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.model_providers.update_provider_status(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_provider_status(
+ workspace,
+ name,
+ model_deployment_id=model_deployment_id,
+ served_models=served_models,
+ status=status,
+ status_message=status_message,
+ request_options=request_options,
+ )
+ return _response.data
+
+
+class AsyncModelProvidersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawModelProvidersClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawModelProvidersClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawModelProvidersClient
+ """
+ return self._raw_client
+
+ async def list_providers(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelProviderSort] = None,
+ filter: typing.Optional[ModelProviderFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvidersPage:
+ """
+ List model providers for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelProviderSort]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelProviderFilter]
+ Filter model providers by workspace, project, status, model_deployment_id, name, description, host_url, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvidersPage
+ Return model providers for a workspace
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.list_providers(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_providers(
+ workspace, page=page, page_size=page_size, sort=sort, filter=filter, request_options=request_options
+ )
+ return _response.data
+
+ async def create_provider(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Create a new model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model provider. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is being auto-created for a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Create a new model provider
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.create_provider(
+ workspace="workspace",
+ name="my-nim-provider",
+ host_url="host_url",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_provider(
+ workspace,
+ name=name,
+ host_url=host_url,
+ project=project,
+ description=description,
+ api_key_secret_name=api_key_secret_name,
+ enabled_models=enabled_models,
+ default_extra_body=default_extra_body,
+ default_extra_headers=default_extra_headers,
+ required_extra_body=required_extra_body,
+ required_extra_headers=required_extra_headers,
+ model_deployment_id=model_deployment_id,
+ status=status,
+ status_message=status_message,
+ auth_header_format=auth_header_format,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ModelProvider:
+ """
+ Get a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Return model provider details
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.get_provider(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_provider(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def upsert_provider(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Create or update a model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Create or update a model provider
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.upsert_provider(
+ workspace="workspace",
+ name="name",
+ host_url="host_url",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.upsert_provider(
+ workspace,
+ name,
+ host_url=host_url,
+ project=project,
+ description=description,
+ api_key_secret_name=api_key_secret_name,
+ enabled_models=enabled_models,
+ default_extra_body=default_extra_body,
+ default_extra_headers=default_extra_headers,
+ required_extra_body=required_extra_body,
+ required_extra_headers=required_extra_headers,
+ model_deployment_id=model_deployment_id,
+ status=status,
+ status_message=status_message,
+ auth_header_format=auth_header_format,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def delete_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.delete_provider(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_provider(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_provider_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ served_models: typing.Optional[typing.Sequence[ServedModelMapping]] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelProvider:
+ """
+ Update status-related fields of a model provider.
+
+ This endpoint supports partial updates for fields managed by Models Controller:
+ - model_deployment_id
+ - served_models
+ - status
+ - status_message
+
+ If status is provided without status_message, status_message will be set to empty string.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ model_deployment_id : typing.Optional[str]
+ Reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ served_models : typing.Optional[typing.Sequence[ServedModelMapping]]
+ List of models served by this provider with routing information for IGW
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message. If status is provided without status_message, defaults to empty string.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelProvider
+ Update status-related fields of a model provider
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.model_providers.update_provider_status(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_provider_status(
+ workspace,
+ name,
+ model_deployment_id=model_deployment_id,
+ served_models=served_models,
+ status=status,
+ status_message=status_message,
+ request_options=request_options,
+ )
+ return _response.data
diff --git a/sdks/python/model_providers/raw_client.py b/sdks/python/model_providers/raw_client.py
new file mode 100644
index 0000000000..769a68f44a
--- /dev/null
+++ b/sdks/python/model_providers/raw_client.py
@@ -0,0 +1,1112 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.model_provider import ModelProvider
+from ..types.model_provider_filter import ModelProviderFilter
+from ..types.model_provider_sort import ModelProviderSort
+from ..types.model_provider_status import ModelProviderStatus
+from ..types.model_providers_page import ModelProvidersPage
+from ..types.served_model_mapping import ServedModelMapping
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawModelProvidersClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_providers(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelProviderSort] = None,
+ filter: typing.Optional[ModelProviderFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelProvidersPage]:
+ """
+ List model providers for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelProviderSort]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelProviderFilter]
+ Filter model providers by workspace, project, status, model_deployment_id, name, description, host_url, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelProvidersPage]
+ Return model providers for a workspace
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelProviderFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvidersPage,
+ parse_obj_as(
+ type_=ModelProvidersPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_provider(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelProvider]:
+ """
+ Create a new model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model provider. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is being auto-created for a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelProvider]
+ Create a new model provider
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "host_url": host_url,
+ "api_key_secret_name": api_key_secret_name,
+ "enabled_models": enabled_models,
+ "default_extra_body": default_extra_body,
+ "default_extra_headers": default_extra_headers,
+ "required_extra_body": required_extra_body,
+ "required_extra_headers": required_extra_headers,
+ "model_deployment_id": model_deployment_id,
+ "status": status,
+ "status_message": status_message,
+ "auth_header_format": auth_header_format,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[ModelProvider]:
+ """
+ Get a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelProvider]
+ Return model provider details
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def upsert_provider(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelProvider]:
+ """
+ Create or update a model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelProvider]
+ Create or update a model provider
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "project": project,
+ "description": description,
+ "host_url": host_url,
+ "api_key_secret_name": api_key_secret_name,
+ "enabled_models": enabled_models,
+ "default_extra_body": default_extra_body,
+ "default_extra_headers": default_extra_headers,
+ "required_extra_body": required_extra_body,
+ "required_extra_headers": required_extra_headers,
+ "model_deployment_id": model_deployment_id,
+ "status": status,
+ "status_message": status_message,
+ "auth_header_format": auth_header_format,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_provider_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ served_models: typing.Optional[typing.Sequence[ServedModelMapping]] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelProvider]:
+ """
+ Update status-related fields of a model provider.
+
+ This endpoint supports partial updates for fields managed by Models Controller:
+ - model_deployment_id
+ - served_models
+ - status
+ - status_message
+
+ If status is provided without status_message, status_message will be set to empty string.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ model_deployment_id : typing.Optional[str]
+ Reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ served_models : typing.Optional[typing.Sequence[ServedModelMapping]]
+ List of models served by this provider with routing information for IGW
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message. If status is provided without status_message, defaults to empty string.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelProvider]
+ Update status-related fields of a model provider
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}/status",
+ method="PUT",
+ json={
+ "model_deployment_id": model_deployment_id,
+ "served_models": convert_and_respect_annotation_metadata(
+ object_=served_models, annotation=typing.Sequence[ServedModelMapping], direction="write"
+ ),
+ "status": status,
+ "status_message": status_message,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawModelProvidersClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_providers(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelProviderSort] = None,
+ filter: typing.Optional[ModelProviderFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelProvidersPage]:
+ """
+ List model providers for a specific workspace.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelProviderSort]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ filter : typing.Optional[ModelProviderFilter]
+ Filter model providers by workspace, project, status, model_deployment_id, name, description, host_url, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelProvidersPage]
+ Return model providers for a workspace
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelProviderFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvidersPage,
+ parse_obj_as(
+ type_=ModelProvidersPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_provider(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelProvider]:
+ """
+ Create a new model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model provider. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is being auto-created for a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelProvider]
+ Create a new model provider
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "host_url": host_url,
+ "api_key_secret_name": api_key_secret_name,
+ "enabled_models": enabled_models,
+ "default_extra_body": default_extra_body,
+ "default_extra_headers": default_extra_headers,
+ "required_extra_body": required_extra_body,
+ "required_extra_headers": required_extra_headers,
+ "model_deployment_id": model_deployment_id,
+ "status": status,
+ "status_message": status_message,
+ "auth_header_format": auth_header_format,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[ModelProvider]:
+ """
+ Get a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelProvider]
+ Return model provider details
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def upsert_provider(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ host_url: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ api_key_secret_name: typing.Optional[str] = OMIT,
+ enabled_models: typing.Optional[typing.Sequence[str]] = OMIT,
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ auth_header_format: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelProvider]:
+ """
+ Create or update a model provider.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ host_url : str
+ The network endpoint URL for the model provider
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model provider
+
+ description : typing.Optional[str]
+ Optional description of the model provider
+
+ api_key_secret_name : typing.Optional[str]
+ Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+ enabled_models : typing.Optional[typing.Sequence[str]]
+ Optional list of specific models to enable from this provider
+
+ default_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Default body parameters for inference requests. Can be overridden by user requests.
+
+ default_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Default headers for inference requests. Can be overridden by user requests.
+
+ required_extra_body : typing.Optional[typing.Dict[str, typing.Any]]
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+
+ required_extra_headers : typing.Optional[typing.Dict[str, str]]
+ Required headers for inference requests. Cannot be overridden by user requests.
+
+ model_deployment_id : typing.Optional[str]
+ Optional reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message
+
+ auth_header_format : typing.Optional[str]
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelProvider]
+ Create or update a model provider
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="PUT",
+ json={
+ "project": project,
+ "description": description,
+ "host_url": host_url,
+ "api_key_secret_name": api_key_secret_name,
+ "enabled_models": enabled_models,
+ "default_extra_body": default_extra_body,
+ "default_extra_headers": default_extra_headers,
+ "required_extra_body": required_extra_body,
+ "required_extra_headers": required_extra_headers,
+ "model_deployment_id": model_deployment_id,
+ "status": status,
+ "status_message": status_message,
+ "auth_header_format": auth_header_format,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_provider(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete a model provider by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_provider_status(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ model_deployment_id: typing.Optional[str] = OMIT,
+ served_models: typing.Optional[typing.Sequence[ServedModelMapping]] = OMIT,
+ status: typing.Optional[ModelProviderStatus] = OMIT,
+ status_message: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelProvider]:
+ """
+ Update status-related fields of a model provider.
+
+ This endpoint supports partial updates for fields managed by Models Controller:
+ - model_deployment_id
+ - served_models
+ - status
+ - status_message
+
+ If status is provided without status_message, status_message will be set to empty string.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ model_deployment_id : typing.Optional[str]
+ Reference to the ModelDeployment ID if this provider is associated with a deployment
+
+ served_models : typing.Optional[typing.Sequence[ServedModelMapping]]
+ List of models served by this provider with routing information for IGW
+
+ status : typing.Optional[ModelProviderStatus]
+ Status of the model provider
+
+ status_message : typing.Optional[str]
+ Status message. If status is provided without status_message, defaults to empty string.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelProvider]
+ Update status-related fields of a model provider
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/providers/{encode_path_param(name)}/status",
+ method="PUT",
+ json={
+ "model_deployment_id": model_deployment_id,
+ "served_models": convert_and_respect_annotation_metadata(
+ object_=served_models, annotation=typing.Sequence[ServedModelMapping], direction="write"
+ ),
+ "status": status,
+ "status_message": status_message,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelProvider,
+ parse_obj_as(
+ type_=ModelProvider, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/models/__init__.py b/sdks/python/models/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/models/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/models/client.py b/sdks/python/models/client.py
new file mode 100644
index 0000000000..1a19f738e5
--- /dev/null
+++ b/sdks/python/models/client.py
@@ -0,0 +1,1237 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.adapter import Adapter
+from ..types.api_endpoint_data import ApiEndpointData
+from ..types.backend_format import BackendFormat
+from ..types.finetuning_type import FinetuningType
+from ..types.lora import Lora
+from ..types.model_entity import ModelEntity
+from ..types.model_entity_filter import ModelEntityFilter
+from ..types.model_entity_sort_field import ModelEntitySortField
+from ..types.model_entitys_page import ModelEntitysPage
+from ..types.model_spec import ModelSpec
+from ..types.prompt_data import PromptData
+from .raw_client import AsyncRawModelsClient, RawModelsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class ModelsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawModelsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawModelsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawModelsClient
+ """
+ return self._raw_client
+
+ def list_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelEntitySortField] = None,
+ verbose: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntitysPage:
+ """
+ List Models endpoint with filtering, pagination, and sorting.
+
+ Supports filter parameters for various criteria (including peft, custom fields),
+ pagination (page, page_size), sorting, and workspace filtering via query parameter.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelEntitySortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ filter : typing.Optional[ModelEntityFilter]
+ Filter models by name, project, workspace, base_model, adapters, finetuning_type, prompt, lora_enabled, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntitysPage
+ Return a list of models
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.list_models(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_models(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ verbose=verbose,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def create_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Create a new model entity.
+
+ This endpoint creates a new Model Entity in the Models service database.
+ The Model Entity will be registered for use within the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model entity
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model - Automatically generated by the platform at creation when fileset provided.
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Create a new model entity
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.create_model(
+ workspace="workspace",
+ name="llama-3.1-8b",
+ )
+ """
+ _response = self._raw_client.create_model(
+ workspace,
+ name=name,
+ project=project,
+ description=description,
+ spec=spec,
+ finetuning_type=finetuning_type,
+ fileset=fileset,
+ base_model=base_model,
+ api_endpoint=api_endpoint,
+ backend_format=backend_format,
+ prompt=prompt,
+ custom_fields=custom_fields,
+ ownership=ownership,
+ model_providers=model_providers,
+ trust_remote_code=trust_remote_code,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def create_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Adds an Adapter to the Model
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Register a new adapter to the model
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.create_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+ )
+ """
+ _response = self._raw_client.create_model_adapter(
+ workspace,
+ model_name,
+ name=name,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ description=description,
+ enabled=enabled,
+ lora_config=lora_config,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def delete_model_adapter(
+ self, workspace: str, model_name: str, adapter: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete Adapter from Model entity.
+
+ Permanently deletes an adapter from a model entity, if it was deployed, it will be cleaned up automatically.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.delete_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+ )
+ """
+ _response = self._raw_client.delete_model_adapter(
+ workspace, model_name, adapter, request_options=request_options
+ )
+ return _response.data
+
+ def update_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ adapter: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Update Adapter deployment or description.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Update adapter metadata
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.update_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+ )
+ """
+ _response = self._raw_client.update_model_adapter(
+ workspace,
+ model_name,
+ adapter,
+ description=description,
+ enabled=enabled,
+ fileset=fileset,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Get Model by Workspace and Name.
+
+ Returns the details of a specific model entity identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Return model details
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.get_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_model(workspace, name, verbose=verbose, request_options=request_options)
+ return _response.data
+
+ def delete_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete Model entity.
+
+ Permanently deletes a model entity from the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.delete_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Update Model metadata.
+
+ Updates the metadata of an existing model entity. If the request body has an empty field,
+ the old value is kept.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Update model metadata
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.models.update_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_model(
+ workspace,
+ name,
+ verbose=verbose,
+ description=description,
+ spec=spec,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ base_model=base_model,
+ api_endpoint=api_endpoint,
+ backend_format=backend_format,
+ prompt=prompt,
+ custom_fields=custom_fields,
+ ownership=ownership,
+ model_providers=model_providers,
+ trust_remote_code=trust_remote_code,
+ request_options=request_options,
+ )
+ return _response.data
+
+
+class AsyncModelsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawModelsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawModelsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawModelsClient
+ """
+ return self._raw_client
+
+ async def list_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelEntitySortField] = None,
+ verbose: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntitysPage:
+ """
+ List Models endpoint with filtering, pagination, and sorting.
+
+ Supports filter parameters for various criteria (including peft, custom fields),
+ pagination (page, page_size), sorting, and workspace filtering via query parameter.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelEntitySortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ filter : typing.Optional[ModelEntityFilter]
+ Filter models by name, project, workspace, base_model, adapters, finetuning_type, prompt, lora_enabled, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntitysPage
+ Return a list of models
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.list_models(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_models(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ verbose=verbose,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def create_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Create a new model entity.
+
+ This endpoint creates a new Model Entity in the Models service database.
+ The Model Entity will be registered for use within the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model entity
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model - Automatically generated by the platform at creation when fileset provided.
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Create a new model entity
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.create_model(
+ workspace="workspace",
+ name="llama-3.1-8b",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_model(
+ workspace,
+ name=name,
+ project=project,
+ description=description,
+ spec=spec,
+ finetuning_type=finetuning_type,
+ fileset=fileset,
+ base_model=base_model,
+ api_endpoint=api_endpoint,
+ backend_format=backend_format,
+ prompt=prompt,
+ custom_fields=custom_fields,
+ ownership=ownership,
+ model_providers=model_providers,
+ trust_remote_code=trust_remote_code,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def create_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Adds an Adapter to the Model
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Register a new adapter to the model
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.create_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_model_adapter(
+ workspace,
+ model_name,
+ name=name,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ description=description,
+ enabled=enabled,
+ lora_config=lora_config,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def delete_model_adapter(
+ self, workspace: str, model_name: str, adapter: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete Adapter from Model entity.
+
+ Permanently deletes an adapter from a model entity, if it was deployed, it will be cleaned up automatically.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.delete_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_model_adapter(
+ workspace, model_name, adapter, request_options=request_options
+ )
+ return _response.data
+
+ async def update_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ adapter: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Adapter:
+ """
+ Update Adapter deployment or description.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Adapter
+ Update adapter metadata
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.update_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_model_adapter(
+ workspace,
+ model_name,
+ adapter,
+ description=description,
+ enabled=enabled,
+ fileset=fileset,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Get Model by Workspace and Name.
+
+ Returns the details of a specific model entity identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Return model details
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.get_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_model(workspace, name, verbose=verbose, request_options=request_options)
+ return _response.data
+
+ async def delete_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete Model entity.
+
+ Permanently deletes a model entity from the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.delete_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ModelEntity:
+ """
+ Update Model metadata.
+
+ Updates the metadata of an existing model entity. If the request body has an empty field,
+ the old value is kept.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ModelEntity
+ Update model metadata
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.models.update_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_model(
+ workspace,
+ name,
+ verbose=verbose,
+ description=description,
+ spec=spec,
+ fileset=fileset,
+ finetuning_type=finetuning_type,
+ base_model=base_model,
+ api_endpoint=api_endpoint,
+ backend_format=backend_format,
+ prompt=prompt,
+ custom_fields=custom_fields,
+ ownership=ownership,
+ model_providers=model_providers,
+ trust_remote_code=trust_remote_code,
+ request_options=request_options,
+ )
+ return _response.data
diff --git a/sdks/python/models/raw_client.py b/sdks/python/models/raw_client.py
new file mode 100644
index 0000000000..c8fe9e6f98
--- /dev/null
+++ b/sdks/python/models/raw_client.py
@@ -0,0 +1,1487 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.adapter import Adapter
+from ..types.api_endpoint_data import ApiEndpointData
+from ..types.backend_format import BackendFormat
+from ..types.finetuning_type import FinetuningType
+from ..types.lora import Lora
+from ..types.model_entity import ModelEntity
+from ..types.model_entity_filter import ModelEntityFilter
+from ..types.model_entity_sort_field import ModelEntitySortField
+from ..types.model_entitys_page import ModelEntitysPage
+from ..types.model_spec import ModelSpec
+from ..types.prompt_data import PromptData
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawModelsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelEntitySortField] = None,
+ verbose: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelEntitysPage]:
+ """
+ List Models endpoint with filtering, pagination, and sorting.
+
+ Supports filter parameters for various criteria (including peft, custom fields),
+ pagination (page, page_size), sorting, and workspace filtering via query parameter.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelEntitySortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ filter : typing.Optional[ModelEntityFilter]
+ Filter models by name, project, workspace, base_model, adapters, finetuning_type, prompt, lora_enabled, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelEntitysPage]
+ Return a list of models
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "verbose": verbose,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelEntityFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntitysPage,
+ parse_obj_as(
+ type_=ModelEntitysPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelEntity]:
+ """
+ Create a new model entity.
+
+ This endpoint creates a new Model Entity in the Models service database.
+ The Model Entity will be registered for use within the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model entity
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model - Automatically generated by the platform at creation when fileset provided.
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelEntity]
+ Create a new model entity
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "spec": convert_and_respect_annotation_metadata(object_=spec, annotation=ModelSpec, direction="write"),
+ "finetuning_type": finetuning_type,
+ "fileset": fileset,
+ "base_model": base_model,
+ "api_endpoint": convert_and_respect_annotation_metadata(
+ object_=api_endpoint, annotation=ApiEndpointData, direction="write"
+ ),
+ "backend_format": backend_format,
+ "prompt": convert_and_respect_annotation_metadata(
+ object_=prompt, annotation=PromptData, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "ownership": ownership,
+ "model_providers": model_providers,
+ "trust_remote_code": trust_remote_code,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Adapter]:
+ """
+ Adds an Adapter to the Model
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Adapter]
+ Register a new adapter to the model
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "enabled": enabled,
+ "lora_config": convert_and_respect_annotation_metadata(
+ object_=lora_config, annotation=Lora, direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_model_adapter(
+ self, workspace: str, model_name: str, adapter: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete Adapter from Model entity.
+
+ Permanently deletes an adapter from a model entity, if it was deployed, it will be cleaned up automatically.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters/{encode_path_param(adapter)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ adapter: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Adapter]:
+ """
+ Update Adapter deployment or description.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Adapter]
+ Update adapter metadata
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters/{encode_path_param(adapter)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "enabled": enabled,
+ "fileset": fileset,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelEntity]:
+ """
+ Get Model by Workspace and Name.
+
+ Returns the details of a specific model entity identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelEntity]
+ Return model details
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="GET",
+ params={
+ "verbose": verbose,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete Model entity.
+
+ Permanently deletes a model entity from the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[ModelEntity]:
+ """
+ Update Model metadata.
+
+ Updates the metadata of an existing model entity. If the request body has an empty field,
+ the old value is kept.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[ModelEntity]
+ Update model metadata
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="PATCH",
+ params={
+ "verbose": verbose,
+ },
+ json={
+ "description": description,
+ "spec": convert_and_respect_annotation_metadata(object_=spec, annotation=ModelSpec, direction="write"),
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "base_model": base_model,
+ "api_endpoint": convert_and_respect_annotation_metadata(
+ object_=api_endpoint, annotation=ApiEndpointData, direction="write"
+ ),
+ "backend_format": backend_format,
+ "prompt": convert_and_respect_annotation_metadata(
+ object_=prompt, annotation=PromptData, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "ownership": ownership,
+ "model_providers": model_providers,
+ "trust_remote_code": trust_remote_code,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawModelsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[ModelEntitySortField] = None,
+ verbose: typing.Optional[bool] = None,
+ filter: typing.Optional[ModelEntityFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelEntitysPage]:
+ """
+ List Models endpoint with filtering, pagination, and sorting.
+
+ Supports filter parameters for various criteria (including peft, custom fields),
+ pagination (page, page_size), sorting, and workspace filtering via query parameter.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[ModelEntitySortField]
+ The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ filter : typing.Optional[ModelEntityFilter]
+ Filter models by name, project, workspace, base_model, adapters, finetuning_type, prompt, lora_enabled, description, created_at, and updated_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelEntitysPage]
+ Return a list of models
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "verbose": verbose,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ModelEntityFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntitysPage,
+ parse_obj_as(
+ type_=ModelEntitysPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ project: typing.Optional[str] = OMIT,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelEntity]:
+ """
+ Create a new model entity.
+
+ This endpoint creates a new Model Entity in the Models service database.
+ The Model Entity will be registered for use within the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the model entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ project : typing.Optional[str]
+ The URN of the project associated with this model entity
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model - Automatically generated by the platform at creation when fileset provided.
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelEntity]
+ Create a new model entity
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models",
+ method="POST",
+ json={
+ "name": name,
+ "project": project,
+ "description": description,
+ "spec": convert_and_respect_annotation_metadata(object_=spec, annotation=ModelSpec, direction="write"),
+ "finetuning_type": finetuning_type,
+ "fileset": fileset,
+ "base_model": base_model,
+ "api_endpoint": convert_and_respect_annotation_metadata(
+ object_=api_endpoint, annotation=ApiEndpointData, direction="write"
+ ),
+ "backend_format": backend_format,
+ "prompt": convert_and_respect_annotation_metadata(
+ object_=prompt, annotation=PromptData, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "ownership": ownership,
+ "model_providers": model_providers,
+ "trust_remote_code": trust_remote_code,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ *,
+ name: str,
+ fileset: str,
+ finetuning_type: FinetuningType,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ lora_config: typing.Optional[Lora] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Adapter]:
+ """
+ Adds an Adapter to the Model
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ name : str
+ Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ fileset : str
+ Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+ finetuning_type : FinetuningType
+ Type of finetuning (LORA, P_TUNING, etc.)
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ lora_config : typing.Optional[Lora]
+ Lora configuration specifics
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Adapter]
+ Register a new adapter to the model
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "enabled": enabled,
+ "lora_config": convert_and_respect_annotation_metadata(
+ object_=lora_config, annotation=Lora, direction="write"
+ ),
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_model_adapter(
+ self, workspace: str, model_name: str, adapter: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete Adapter from Model entity.
+
+ Permanently deletes an adapter from a model entity, if it was deployed, it will be cleaned up automatically.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters/{encode_path_param(adapter)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_model_adapter(
+ self,
+ workspace: str,
+ model_name: str,
+ adapter: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ enabled: typing.Optional[bool] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Adapter]:
+ """
+ Update Adapter deployment or description.
+
+ Parameters
+ ----------
+ workspace : str
+
+ model_name : str
+
+ adapter : str
+
+ description : typing.Optional[str]
+ Optional description of the adapter
+
+ enabled : typing.Optional[bool]
+ Whether to make this adapter available for inference post training
+
+ fileset : typing.Optional[str]
+ Updated fileset for the adapter
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Adapter]
+ Update adapter metadata
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(model_name)}/adapters/{encode_path_param(adapter)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "enabled": enabled,
+ "fileset": fileset,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Adapter,
+ parse_obj_as(
+ type_=Adapter, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelEntity]:
+ """
+ Get Model by Workspace and Name.
+
+ Returns the details of a specific model entity identified by its workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelEntity]
+ Return model details
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="GET",
+ params={
+ "verbose": verbose,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete Model entity.
+
+ Permanently deletes a model entity from the platform.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ verbose: typing.Optional[bool] = None,
+ description: typing.Optional[str] = OMIT,
+ spec: typing.Optional[ModelSpec] = OMIT,
+ fileset: typing.Optional[str] = OMIT,
+ finetuning_type: typing.Optional[FinetuningType] = OMIT,
+ base_model: typing.Optional[str] = OMIT,
+ api_endpoint: typing.Optional[ApiEndpointData] = OMIT,
+ backend_format: typing.Optional[BackendFormat] = OMIT,
+ prompt: typing.Optional[PromptData] = OMIT,
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
+ model_providers: typing.Optional[typing.Sequence[str]] = OMIT,
+ trust_remote_code: typing.Optional[bool] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[ModelEntity]:
+ """
+ Update Model metadata.
+
+ Updates the metadata of an existing model entity. If the request body has an empty field,
+ the old value is kept.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ verbose : typing.Optional[bool]
+ Whether to include full spec details
+
+ description : typing.Optional[str]
+ Optional description of the model
+
+ spec : typing.Optional[ModelSpec]
+ Detailed specification for the model
+
+ fileset : typing.Optional[str]
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+ finetuning_type : typing.Optional[FinetuningType]
+ Set for full weight finetuned models
+
+ base_model : typing.Optional[str]
+ Link to another model which is used as a base for the current model
+
+ api_endpoint : typing.Optional[ApiEndpointData]
+ Data about the inference endpoint for this model
+
+ backend_format : typing.Optional[BackendFormat]
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+ prompt : typing.Optional[PromptData]
+ Configuration for prompt engineering
+
+ custom_fields : typing.Optional[typing.Dict[str, typing.Any]]
+ Custom fields for additional metadata
+
+ ownership : typing.Optional[typing.Dict[str, typing.Any]]
+ Ownership information for the model
+
+ model_providers : typing.Optional[typing.Sequence[str]]
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+ trust_remote_code : typing.Optional[bool]
+ Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[ModelEntity]
+ Update model metadata
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/models/v2/workspaces/{encode_path_param(workspace)}/models/{encode_path_param(name)}",
+ method="PATCH",
+ params={
+ "verbose": verbose,
+ },
+ json={
+ "description": description,
+ "spec": convert_and_respect_annotation_metadata(object_=spec, annotation=ModelSpec, direction="write"),
+ "fileset": fileset,
+ "finetuning_type": finetuning_type,
+ "base_model": base_model,
+ "api_endpoint": convert_and_respect_annotation_metadata(
+ object_=api_endpoint, annotation=ApiEndpointData, direction="write"
+ ),
+ "backend_format": backend_format,
+ "prompt": convert_and_respect_annotation_metadata(
+ object_=prompt, annotation=PromptData, direction="write"
+ ),
+ "custom_fields": custom_fields,
+ "ownership": ownership,
+ "model_providers": model_providers,
+ "trust_remote_code": trust_remote_code,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ ModelEntity,
+ parse_obj_as(
+ type_=ModelEntity, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/otlp/__init__.py b/sdks/python/otlp/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/otlp/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/otlp/client.py b/sdks/python/otlp/client.py
new file mode 100644
index 0000000000..2c43d65678
--- /dev/null
+++ b/sdks/python/otlp/client.py
@@ -0,0 +1,246 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.otel_export_logs_service_response import OtelExportLogsServiceResponse
+from ..types.platform_job_log_page import PlatformJobLogPage
+from .raw_client import AsyncRawOtlpClient, RawOtlpClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class OtlpClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawOtlpClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawOtlpClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawOtlpClient
+ """
+ return self._raw_client
+
+ def upload_otlp_logs(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OtelExportLogsServiceResponse:
+ """
+ Upload OTLP logs to a specified fileset in JSON or Protobuf format.
+
+ Supports both application/json and application/x-protobuf content types.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OtelExportLogsServiceResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.otlp.upload_otlp_logs(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.upload_otlp_logs(workspace, name, request_options=request_options)
+ return _response.data
+
+ def query_otlp_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ filters: typing.Optional[typing.Dict[str, str]] = OMIT,
+ limit: typing.Optional[int] = OMIT,
+ page_cursor: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobLogPage:
+ """
+ Query logs from parquet files in a fileset.
+
+ This is an internal endpoint that runs DuckDB queries with direct storage
+ access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ filters : typing.Optional[typing.Dict[str, str]]
+ Key-value filters to apply to the query
+
+ limit : typing.Optional[int]
+ Maximum number of results to return
+
+ page_cursor : typing.Optional[str]
+ Cursor for pagination
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobLogPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.otlp.query_otlp_logs(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.query_otlp_logs(
+ workspace, name, filters=filters, limit=limit, page_cursor=page_cursor, request_options=request_options
+ )
+ return _response.data
+
+
+class AsyncOtlpClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawOtlpClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawOtlpClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawOtlpClient
+ """
+ return self._raw_client
+
+ async def upload_otlp_logs(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> OtelExportLogsServiceResponse:
+ """
+ Upload OTLP logs to a specified fileset in JSON or Protobuf format.
+
+ Supports both application/json and application/x-protobuf content types.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ OtelExportLogsServiceResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.otlp.upload_otlp_logs(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.upload_otlp_logs(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def query_otlp_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ filters: typing.Optional[typing.Dict[str, str]] = OMIT,
+ limit: typing.Optional[int] = OMIT,
+ page_cursor: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformJobLogPage:
+ """
+ Query logs from parquet files in a fileset.
+
+ This is an internal endpoint that runs DuckDB queries with direct storage
+ access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ filters : typing.Optional[typing.Dict[str, str]]
+ Key-value filters to apply to the query
+
+ limit : typing.Optional[int]
+ Maximum number of results to return
+
+ page_cursor : typing.Optional[str]
+ Cursor for pagination
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformJobLogPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.otlp.query_otlp_logs(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.query_otlp_logs(
+ workspace, name, filters=filters, limit=limit, page_cursor=page_cursor, request_options=request_options
+ )
+ return _response.data
diff --git a/sdks/python/otlp/raw_client.py b/sdks/python/otlp/raw_client.py
new file mode 100644
index 0000000000..3f717ad9da
--- /dev/null
+++ b/sdks/python/otlp/raw_client.py
@@ -0,0 +1,309 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.otel_export_logs_service_response import OtelExportLogsServiceResponse
+from ..types.platform_job_log_page import PlatformJobLogPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawOtlpClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def upload_otlp_logs(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[OtelExportLogsServiceResponse]:
+ """
+ Upload OTLP logs to a specified fileset in JSON or Protobuf format.
+
+ Supports both application/json and application/x-protobuf content types.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[OtelExportLogsServiceResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/otlp/v1/logs",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OtelExportLogsServiceResponse,
+ parse_obj_as(
+ type_=OtelExportLogsServiceResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def query_otlp_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ filters: typing.Optional[typing.Dict[str, str]] = OMIT,
+ limit: typing.Optional[int] = OMIT,
+ page_cursor: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformJobLogPage]:
+ """
+ Query logs from parquet files in a fileset.
+
+ This is an internal endpoint that runs DuckDB queries with direct storage
+ access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ filters : typing.Optional[typing.Dict[str, str]]
+ Key-value filters to apply to the query
+
+ limit : typing.Optional[int]
+ Maximum number of results to return
+
+ page_cursor : typing.Optional[str]
+ Cursor for pagination
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformJobLogPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/otlp/v1/logs/query",
+ method="POST",
+ json={
+ "filters": filters,
+ "limit": limit,
+ "page_cursor": page_cursor,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobLogPage,
+ parse_obj_as(
+ type_=PlatformJobLogPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawOtlpClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def upload_otlp_logs(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[OtelExportLogsServiceResponse]:
+ """
+ Upload OTLP logs to a specified fileset in JSON or Protobuf format.
+
+ Supports both application/json and application/x-protobuf content types.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[OtelExportLogsServiceResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/otlp/v1/logs",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ OtelExportLogsServiceResponse,
+ parse_obj_as(
+ type_=OtelExportLogsServiceResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def query_otlp_logs(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ filters: typing.Optional[typing.Dict[str, str]] = OMIT,
+ limit: typing.Optional[int] = OMIT,
+ page_cursor: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformJobLogPage]:
+ """
+ Query logs from parquet files in a fileset.
+
+ This is an internal endpoint that runs DuckDB queries with direct storage
+ access.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ filters : typing.Optional[typing.Dict[str, str]]
+ Key-value filters to apply to the query
+
+ limit : typing.Optional[int]
+ Maximum number of results to return
+
+ page_cursor : typing.Optional[str]
+ Cursor for pagination
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformJobLogPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/files/v2/workspaces/{encode_path_param(workspace)}/filesets/{encode_path_param(name)}/otlp/v1/logs/query",
+ method="POST",
+ json={
+ "filters": filters,
+ "limit": limit,
+ "page_cursor": page_cursor,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformJobLogPage,
+ parse_obj_as(
+ type_=PlatformJobLogPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/reference.md b/sdks/python/reference.md
new file mode 100644
index 0000000000..e28b8f9655
--- /dev/null
+++ b/sdks/python/reference.md
@@ -0,0 +1,15286 @@
+# Reference
+## Discovery
+client.discovery.get_auth_discovery() -> AuthDiscoveryResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Return authentication configuration for CLI/SDK discovery.
+
+This endpoint is unauthenticated and returns the information clients
+need to authenticate with this NeMo Platform deployment.
+
+**Response fields:**
+
+- `auth_enabled`: Whether authentication is enabled on this cluster
+- `oidc`: OIDC configuration (only present when OIDC is enabled)
+ - `issuer`: The OIDC issuer URL
+ - `authorization_endpoint`: Authorization endpoint for browser-based flows
+ - `token_endpoint`: Token exchange endpoint
+ - `device_authorization_endpoint`: Device flow authorization endpoint (for CLI)
+ - `userinfo_endpoint`: UserInfo endpoint
+ - `client_id`: OAuth client ID to use
+ - `default_scopes`: OAuth scopes to request during authentication
+ - `scope_prefix`: Prefix to prepend to custom scopes (those with ':' or '.default')
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.discovery.get_auth_discovery()
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Iam
+client.iam.list_role_bindings(...) -> RoleBindingsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all role bindings (Platform Admin only)
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.iam.list_role_bindings()
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[RoleBindingFilter]` — Filter role bindings by principal, workspace, role, granted_by, is_active, granted_at, and revoked_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.iam.create_role_binding(...) -> RoleBinding
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new role binding (Platform Admin only)
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.iam.create_role_binding(
+ principal="principal",
+ role="role",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**principal:** `str` — The principal identifier (email, user ID, or group ID)
+
+
+
+
+
+-
+
+**role:** `str` — The role name (e.g., 'Viewer', 'Editor', 'Admin')
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**workspace:** `typing.Optional[str]` — The workspace this binding applies to. None for platform-level roles.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.iam.get_role_binding(...) -> RoleBinding
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific role binding (Platform Admin only)
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.iam.get_role_binding(
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.iam.revoke_role_binding(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Revoke a role binding (Platform Admin only)
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.iam.revoke_role_binding(
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for role to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## EntityStore
+client.entity_store.get_entity_by_id(...) -> Entity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific entity by its unique identifier.
+This endpoint is primarily for debugging and internal use.
+
+Example:
+```
+GET /apis/entities/v2/entities/customization-config-5Q2LoF8z8M9JZxZsHwJKNn
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.get_entity_by_id(
+ id="id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.list_workspaces(...) -> WorkspacesPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all workspaces with pagination.
+
+When authentication is enabled, only workspaces the principal has access to
+are returned. Service principals and platform admins have access to all workspaces.
+
+Query Parameters:
+- page, page_size: Pagination
+- sort: Sort field
+- filter: Advanced filters (JSON, text, or bracket notation)
+
+Example:
+```
+GET /apis/entities/v2/workspaces?sort=-created_at&page=1&page_size=10
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.list_workspaces()
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Items per page
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[GenericSortField]` — Sort field
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[str]`
+
+Query filter expression. Supports text and JSON syntaxes:
+- Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+- Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+- Bracket notation: ?filter[name][$like]=value
+- Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.create_workspace(...) -> Workspace
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new workspace.
+
+The creator is automatically granted Admin role on the workspace.
+By default, this endpoint waits for the Admin role to propagate before returning.
+Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+Example:
+```
+POST /apis/entities/v2/workspaces
+{
+ "name": "ml-team",
+ "description": "Machine Learning Team workspace"
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.create_workspace(
+ name="ml-team",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str` — Workspace name (unique identifier). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for Admin role to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the workspace
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.get_workspace(...) -> Workspace
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific workspace by ID.
+
+Example:
+```
+GET /apis/entities/v2/workspaces/ml-team
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.get_workspace(
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.update_workspace(...) -> Workspace
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a workspace's description.
+
+Example:
+```
+PUT /apis/entities/v2/workspaces/ml-team
+{
+ "description": "Updated description for ML Team"
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.update_workspace(
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Updated description
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.delete_workspace(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a workspace.
+
+This marks the workspace for deletion and returns immediately. The workspace
+will no longer be accessible via the API. An asynchronous cleanup controller
+will handle deletion of all entities and external resources.
+
+Role bindings are immediately deleted to revoke access.
+
+Example:
+```
+DELETE /apis/entities/v2/workspaces/ml-team
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.delete_workspace(
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.list_entities(...) -> EntitiesPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all entities of a specific type in the given workspace.
+
+Use workspace="-" to list entities across all workspaces the principal has
+access to.
+
+Query Parameters:
+- sort: Sort field
+- page, page_size: Pagination
+- filter: Advanced filters (JSON, text, or bracket notation)
+
+Examples:
+```
+GET /apis/entities/v2/workspaces/default/entities/customization_config?sort=-created_at
+GET /apis/entities/v2/workspaces/-/entities/customization_config # Cross-workspace query
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.list_entities(
+ workspace="workspace",
+ entity_type="entity_type",
+ sort="-created_at",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**entity_type:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Items per page
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — Sort field
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[str]`
+
+Query filter expression. Supports text and JSON syntaxes:
+- Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+- Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+- Bracket notation: ?filter[name][$like]=value
+- Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.create_entity(...) -> Entity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new entity of the specified type in the given workspace.
+
+If name is not provided, it will be auto-generated based on the entity type.
+
+Example:
+```
+POST /apis/entities/v2/workspaces/default/entities/customization_config
+{
+ "name": "my-config",
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.01}
+ }
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.create_entity(
+ workspace="workspace",
+ entity_type="entity_type",
+ data={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**entity_type:** `str`
+
+
+
+
+
+-
+
+**data:** `typing.Dict[str, typing.Any]` — Entity-specific data (schema is opaque to entity store, validated by client SDK)
+
+
+
+
+
+-
+
+**name:** `typing.Optional[str]` — Entity name (optional - auto-generated if not provided). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+
+
+
+
+-
+
+**parent:** `typing.Optional[str]` — Parent entity ID for nested entities
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The name of the project associated with this entity
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.get_entity_by_name(...) -> Entity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific entity by its workspace, type, and name.
+
+Example:
+```
+GET /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.get_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**entity_type:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**parent:** `typing.Optional[str]` — Parent entity ID for nested entities
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.update_entity_by_name(...) -> Entity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update an entity by its name. Optionally change the entity's name.
+
+Example:
+```
+PUT /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+{
+ "data": {
+ "target_id": "llama-2-7b",
+ "training_options": {"learning_rate": 0.02}
+ }
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.update_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+ data={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**entity_type:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**data:** `typing.Dict[str, typing.Any]` — Updated entity-specific data
+
+
+
+
+
+-
+
+**parent:** `typing.Optional[str]` — Parent entity ID for nested entities
+
+
+
+
+
+-
+
+**new_name:** `typing.Optional[str]` — Updated entity name (optional). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The name of the project associated with this entity
+
+
+
+
+
+-
+
+**expected_db_version:** `typing.Optional[int]` — Optional database version for optimistic locking. Update only succeeds if current version matches.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.delete_entity_by_name(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete an entity by its name.
+
+Example:
+```
+DELETE /apis/entities/v2/workspaces/default/entities/customization_config/my-config
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.delete_entity_by_name(
+ workspace="workspace",
+ entity_type="entity_type",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**entity_type:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**parent:** `typing.Optional[str]` — Parent entity ID for nested entities
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.list_workspace_members(...) -> WorkspaceMemberListResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all members of a workspace with their roles.
+
+Returns a list of all principals with active role bindings in the workspace.
+
+Example:
+```
+GET /apis/entities/v2/workspaces/ml-team/members
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.list_workspace_members(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.add_workspace_member(...) -> WorkspaceMember
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Add a new member to the workspace with specified roles.
+
+This creates role bindings for the specified principal with the given roles.
+By default, this endpoint waits for the roles to propagate before returning.
+Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+Example:
+```
+POST /apis/entities/v2/workspaces/ml-team/members
+{
+ "principal": "user@example.com",
+ "roles": ["Editor"]
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.add_workspace_member(
+ workspace="workspace",
+ principal="user@example.com",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**principal:** `str` — The principal identifier (email, user ID, or group ID)
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**roles:** `typing.Optional[typing.List[str]]` — List of roles to grant to the principal
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.update_workspace_member(...) -> WorkspaceMember
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update the roles for a workspace member.
+
+This will revoke existing roles not in the new list and add new roles.
+By default, this endpoint waits for the roles to propagate before returning.
+Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+Example:
+```
+PUT /apis/entities/v2/workspaces/ml-team/members/user@example.com
+{
+ "roles": ["Viewer", "Editor"]
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.update_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+ roles=[
+ "Viewer"
+ ],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**principal_id:** `str`
+
+
+
+
+
+-
+
+**roles:** `typing.List[str]` — Updated list of roles for the principal
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.remove_workspace_member(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Remove a member from the workspace by revoking all their roles.
+
+This revokes all active role bindings for the principal in the workspace.
+By default, this endpoint waits for all roles to be revoked before returning.
+Use `wait_role_propagation=false` to skip waiting (useful for bulk operations).
+
+Example:
+```
+DELETE /apis/entities/v2/workspaces/ml-team/members/user@example.com
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.remove_workspace_member(
+ workspace="workspace",
+ principal_id="principal_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**principal_id:** `str`
+
+
+
+
+
+-
+
+**wait_role_propagation:** `typing.Optional[bool]` — If true, wait for roles to propagate before returning (default: true). Set to false for bulk operations.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.list_projects(...) -> ProjectsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all projects in a workspace with pagination.
+
+Query Parameters:
+- page, page_size: Pagination
+- sort: Sort field
+- filter: Advanced filters
+
+Example:
+```
+GET /apis/entities/v2/workspaces/default/projects?sort=-created_at&page=1&page_size=10
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.list_projects(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Items per page
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[ProjectSortField]` — Sort field
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[str]`
+
+Query filter expression. Supports text and JSON syntaxes:
+- Text: name:"value" AND status>500 with operators : ~ > >= < <= IN NOT IN AND OR and negation prefix -
+- Object (JSON): {"name":{"$like":"value"}} with operators $eq, $like, $lt, $lte, $gt, $gte, $in, $nin, $and, $or, $not
+- Bracket notation: ?filter[name][$like]=value
+- Relationship traversal: ?filter[relationship][$exists]=true or ?filter[relationship][field]=value
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.create_project(...) -> Project
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new project in the given workspace.
+
+Example:
+```
+POST /apis/entities/v2/workspaces/default/projects
+{
+ "name": "ml-project",
+ "description": "Machine Learning project"
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.create_project(
+ workspace="workspace",
+ name="ml-project",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Project name (unique within workspace). Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the project
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.get_project(...) -> Project
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific project by its workspace and name.
+
+Example:
+```
+GET /apis/entities/v2/workspaces/default/projects/ml-project
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.get_project(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.update_project(...) -> Project
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a project's description.
+
+Example:
+```
+PUT /apis/entities/v2/workspaces/default/projects/ml-project
+{
+ "description": "Updated description for ML project"
+}
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.update_project(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Updated description
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.entity_store.delete_project(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a project.
+
+Example:
+```
+DELETE /apis/entities/v2/workspaces/default/projects/ml-project
+```
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.entity_store.delete_project(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Files
+client.files.list_filesets(...) -> FilesetOutputsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List Filesets endpoint with filtering and pagination.
+
+Supports filtering by name, description, purpose, storage_type, created_at, and updated_at via query parameters.
+Returns paginated results with sorting options.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.list_filesets(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[GenericSortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[FilesetFilter]` — Filter filesets by name, description, purpose, storage_type, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.create_fileset(...) -> FilesetOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new fileset.
+
+If no storage configuration is provided, the default storage backend will be used.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.create_fileset(
+ workspace="workspace",
+ name="training-data-v1",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — The name of the fileset. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — The description of the fileset.
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The name of the project associated with this fileset.
+
+
+
+
+
+-
+
+**storage:** `typing.Optional[CreateFilesetRequestStorage]` — The storage configuration for the fileset. If not provided, uses default storage.
+
+
+
+
+
+-
+
+**purpose:** `typing.Optional[FilesetPurpose]` — The purpose of the fileset.
+
+
+
+
+
+-
+
+**metadata:** `typing.Optional[FilesetMetadataInput]` — Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+
+
+
+
+-
+
+**custom_fields:** `typing.Optional[typing.Dict[str, typing.Any]]` — Custom fields for the fileset.
+
+
+
+
+
+-
+
+**cache:** `typing.Optional[bool]` — Cache all files after creation. Only applies to external storage.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.retrieve_fileset(...) -> FilesetOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get Fileset by Workspace and Name.
+
+Returns the details of a specific fileset identified by its workspace and name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.retrieve_fileset(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.delete_fileset(...) -> FilesetOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete Fileset.
+
+Permanently deletes a fileset from the platform.
+Returns metadata about the deleted fileset.
+For local storage backends, this also deletes the underlying files.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.delete_fileset(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.update_fileset_metadata(...) -> FilesetOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update Fileset Metadata.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.update_fileset_metadata(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — The description of the fileset.
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The name of the project associated with this fileset.
+
+
+
+
+
+-
+
+**purpose:** `typing.Optional[FilesetPurpose]` — The purpose of the fileset.
+
+
+
+
+
+-
+
+**metadata:** `typing.Optional[FilesetMetadataInput]` — Purpose-specific metadata. Use the purpose as the key (e.g., {dataset: {...}}).
+
+
+
+
+
+-
+
+**custom_fields:** `typing.Optional[typing.Dict[str, typing.Any]]` — Custom fields for the fileset.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(...) -> typing.Iterator[bytes]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Download file content from a fileset.
+
+Supports HTTP Range requests for partial content retrieval (status 206).
+Returns the full file content (status 200) if no Range header is provided.
+For external resources (HuggingFace, NGC), content is cached locally on first access.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.download_file_apis_files_v2workspaces_workspace_filesets_name_path_get(
+ workspace="workspace",
+ name="name",
+ path="path",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**path:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(...) -> FilesetFileOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Upload file content to a fileset.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+client.files.upload_file_apis_files_v2workspaces_workspace_filesets_name_path_put(...)
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**path:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]` — Upload the file either as a raw octet stream.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(...) -> FilesetFileOutput
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a specific file from a fileset.
+
+Permanently deletes the file from the storage backend.
+Returns metadata about the deleted file.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.delete_file_apis_files_v2workspaces_workspace_filesets_name_path_delete(
+ workspace="workspace",
+ name="name",
+ path="path",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**path:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get file metadata without downloading content.
+
+HEAD requests are often used before Range GETs to ensure the server
+supports partial downloads (e.g., DuckDB's httpfs).
+Returns Accept-Ranges, Content-Length, and Content-Type headers.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.head_file_apis_files_v2workspaces_workspace_filesets_name_path_head(
+ workspace="workspace",
+ name="name",
+ path="path",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**path:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.files.list_fileset_files(...) -> ListFilesetFilesResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List Files in Fileset.
+
+Returns a list of files stored in the specified fileset.
+Optionally filter by path prefix to list files under a specific directory.
+
+Each file includes a cache_status field:
+- "not_cacheable": File is on default storage, caching not applicable
+- "cached": File exists in cache storage
+- "caching": File is currently being downloaded and cached
+- "not_cached": File not in cache, will be cached on next download
+- null: External storage, but cache status not checked (use include_cache_status=true)
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.files.list_fileset_files(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**path:** `typing.Optional[str]` — Filter files by path prefix
+
+
+
+
+
+-
+
+**include_cache_status:** `typing.Optional[bool]` — Check and return cache status for each file. When false, storage files return null for cache_status.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Otlp
+client.otlp.upload_otlp_logs(...) -> OtelExportLogsServiceResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Upload OTLP logs to a specified fileset in JSON or Protobuf format.
+
+Supports both application/json and application/x-protobuf content types.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.otlp.upload_otlp_logs(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.otlp.query_otlp_logs(...) -> PlatformJobLogPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Query logs from parquet files in a fileset.
+
+This is an internal endpoint that runs DuckDB queries with direct storage
+access.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.otlp.query_otlp_logs(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**filters:** `typing.Optional[typing.Dict[str, str]]` — Key-value filters to apply to the query
+
+
+
+
+
+-
+
+**limit:** `typing.Optional[int]` — Maximum number of results to return
+
+
+
+
+
+-
+
+**page_cursor:** `typing.Optional[str]` — Cursor for pagination
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Guardrails
+client.guardrails.check(...) -> GuardrailCheckResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Chat completion for the provided conversation.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+from nvidia.guardrails import GuardrailCheckRequestMessagesItem_System
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.check(
+ workspace="workspace",
+ model="model",
+ messages=[
+ GuardrailCheckRequestMessagesItem_System(
+ content="content",
+ )
+ ],
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**model:** `str` — The model to use for completion. Must be one of the available models.
+
+
+
+
+
+-
+
+**messages:** `typing.List[GuardrailCheckRequestMessagesItem]` — A list of messages comprising the conversation so far
+
+
+
+
+
+-
+
+**response_format:** `typing.Optional[typing.Dict[str, typing.Any]]` — Format of the response. Use {'type': 'json_object'} for JSON mode or {'type': 'json_schema', 'json_schema': {...}} for structured outputs.
+
+
+
+
+
+-
+
+**max_tokens:** `typing.Optional[int]` — The maximum number of tokens that can be generated in the chat completion.
+
+
+
+
+
+-
+
+**n:** `typing.Optional[int]` — How many chat completion choices to generate for each input message.
+
+
+
+
+
+-
+
+**stream:** `typing.Optional[bool]` — If set, partial message deltas will be sent, like in ChatGPT.
+
+
+
+
+
+-
+
+**temperature:** `typing.Optional[float]` — What sampling temperature to use, between 0 and 2.
+
+
+
+
+
+-
+
+**top_p:** `typing.Optional[float]` — An alternative to sampling with temperature, called nucleus sampling.
+
+
+
+
+
+-
+
+**stop:** `typing.Optional[GuardrailCheckRequestStop]` — Up to 4 sequences where the API will stop generating further tokens.
+
+
+
+
+
+-
+
+**frequency_penalty:** `typing.Optional[float]` — Positive values penalize new tokens based on their existing frequency in the text.
+
+
+
+
+
+-
+
+**presence_penalty:** `typing.Optional[float]` — Positive values penalize new tokens based on whether they appear in the text so far.
+
+
+
+
+
+-
+
+**function_call:** `typing.Optional[GuardrailCheckRequestFunctionCall]` — Deprecated in favor of tool_choice. 'none' means the model will not call a function and instead generates a message. 'auto' means the model can pick between generating a message or calling a function. Specifying a particular function via {'name': 'my_function'} forces the model to call that function.
+
+
+
+
+
+-
+
+**seed:** `typing.Optional[int]` — If specified, attempts to sample deterministically.
+
+
+
+
+
+-
+
+**logit_bias:** `typing.Optional[typing.Dict[str, float]]` — Modify the likelihood of specified tokens appearing in the completion. Maps token IDs (as strings) to bias values from -100 to 100.
+
+
+
+
+
+-
+
+**top_logprobs:** `typing.Optional[int]` — The number of most likely tokens to return at each token position.
+
+
+
+
+
+-
+
+**logprobs:** `typing.Optional[bool]` — Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message
+
+
+
+
+
+-
+
+**tool_choice:** `typing.Optional[GuardrailCheckRequestToolChoice]` — Controls which (if any) tool is called by the model. 'none' means no tool is called, 'auto' lets the model decide, 'required' forces a tool call.
+
+
+
+
+
+-
+
+**user:** `typing.Optional[str]` — A unique identifier representing your end-user, used by some providers for abuse monitoring.
+
+
+
+
+
+-
+
+**tools:** `typing.Optional[typing.List[typing.Dict[str, typing.Any]]]` — A list of tools the model may call. Each tool is an object with a 'type' field and a 'function' definition.
+
+
+
+
+
+-
+
+**ignore_eos:** `typing.Optional[bool]` — Ignore the eos when running
+
+
+
+
+
+-
+
+**reasoning_effort:** `typing.Optional[str]` — Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
+
+
+
+
+
+-
+
+**max_completion_tokens:** `typing.Optional[int]` — An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens. Preferred over max_tokens for reasoning models.
+
+
+
+
+
+-
+
+**stream_options:** `typing.Optional[typing.Dict[str, bool]]` — Options for streaming response. Only set this when stream=True. Supports include_usage to receive token usage in the final stream chunk.
+
+
+
+
+
+-
+
+**vision:** `typing.Optional[bool]` — Whether this is a vision-capable request with image inputs.
+
+
+
+
+
+-
+
+**guardrails:** `typing.Optional[GuardrailsDataInput]` — Guardrails specific options for the request.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.guardrails.list_guardrail_configs(...) -> GuardrailConfigsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List available guardrail configs.
+
+Lists guardrail configs for a specific workspace.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.list_guardrail_configs(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[GenericSortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[GuardrailConfigFilter]` — Filter guardrail configs by name, description, project, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.guardrails.create_config(...) -> GuardrailConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new guardrail config.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.create_config(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — The name of the guardrail config
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Description of the guardrail config
+
+
+
+
+
+-
+
+**data:** `typing.Optional[typing.Dict[str, typing.Any]]` — Guardrail configuration data
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.guardrails.get_guardrail_config(...) -> GuardrailConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get info about a guardrail configuration.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.get_guardrail_config(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.guardrails.delete_config(...) -> DeleteResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a guardrail config.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.delete_config(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.guardrails.update_config(...) -> GuardrailConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update model metadata. If the request body has an empty field,
+keep the old value.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.guardrails.update_config(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Description of the guardrail config
+
+
+
+
+
+-
+
+**data:** `typing.Optional[typing.Dict[str, typing.Any]]` — Guardrail configuration data
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## InferenceGateway
+client.inference_gateway.gateway_proxy_get(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to model entity inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.gateway_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.gateway_proxy_post(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to model entity inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.gateway_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.gateway_proxy_put(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to model entity inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.gateway_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.gateway_proxy_delete(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to model entity inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.gateway_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.gateway_proxy_patch(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to model entity inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.gateway_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_list_models(...) -> OpenAiListModelsResp
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+This endpoint aggregates models from all model entities and returns them
+in OpenAI's list models format. Each model ID is the model entity identifier
+in format workspace/model_entity_name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_list_models(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_get_model(...) -> OpenAiModelResp
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve information about a specific OpenAI-compatible model.
+Workspace is always taken from the URL path; name may be model_entity_name
+or workspace/model_entity_name (workspace prefix is ignored).
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_get_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_get(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to OpenAI-compatible inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_get(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_post(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to OpenAI-compatible inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_post(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_put(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to OpenAI-compatible inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_put(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_delete(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to OpenAI-compatible inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_delete(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.openai_proxy_patch(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to OpenAI-compatible inference endpoints.
+
+All inference requests must resolve to a `VirtualModel`. The platform's
+provider reconciler auto-creates an implicit `autoprovisioned` VirtualModel
+for every served model entity (named after the entity, with
+`default_model_entity` set to the entity ref) so this is the typical case;
+operators can also create custom VirtualModels for routing, plugin chains,
+LoRA escape-hatches, etc. Requests for which no VirtualModel can be found
+return `404`.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.openai_proxy_patch(
+ workspace="workspace",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_proxy_get(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to provider inference endpoints.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_proxy_get(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_proxy_post(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to provider inference endpoints.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_proxy_post(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_proxy_put(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to provider inference endpoints.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_proxy_put(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_proxy_delete(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to provider inference endpoints.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_proxy_delete(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_proxy_patch(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Proxy requests to provider inference endpoints.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_proxy_patch(
+ workspace="workspace",
+ name="name",
+ trailing_uri="trailing_uri",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**trailing_uri:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.inference_gateway.provider_ready(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Check if a model provider is registered in the gateway's cache.
+
+This is a lightweight endpoint that only checks the gateway's internal state,
+without making any requests to the actual provider backend. Use this to verify
+the gateway is ready to route requests to a provider after deployment.
+
+Returns:
+ 200 OK with provider info if the provider is registered
+ 404 Not Found if the provider is not yet in the gateway's cache
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.inference_gateway.provider_ready(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## VirtualModels
+client.virtual_models.list_virtual_models(...) -> VirtualModelsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List VirtualModels for the given workspace.
+
+Use ``workspace=-`` to list across all workspaces accessible to the caller.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.virtual_models.list_virtual_models(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number (1-indexed).
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Number of results per page.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — Sort field. Prefix with ``-`` for descending order.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.virtual_models.create_virtual_model(...) -> VirtualModel
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new VirtualModel in the given workspace.
+
+A VirtualModel defines an ordered middleware pipeline that IGW executes
+when an inference request arrives with ``model: "workspace/name"`` matching
+this entity.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.virtual_models.create_virtual_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the virtual model within the workspace. Must be unique per workspace.
+
+
+
+
+
+-
+
+**default_model_entity:** `typing.Optional[str]` — Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+
+
+
+
+-
+
+**autoprovisioned:** `typing.Optional[bool]` — Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+
+
+
+
+-
+
+**models:** `typing.Optional[typing.List[VirtualModelInferenceConfig]]` — Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+
+
+
+
+-
+
+**request_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+
+
+
+
+-
+
+**response_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+
+
+
+
+-
+
+**post_response_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+
+
+
+
+-
+
+**override_proxy:** `typing.Optional[str]` — Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.virtual_models.get_virtual_model(...) -> VirtualModel
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a VirtualModel by workspace and name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.virtual_models.get_virtual_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.virtual_models.delete_virtual_model(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Permanently delete a VirtualModel.
+
+This does not affect any in-flight requests already being routed through
+this VirtualModel. IGW's model cache is refreshed on its next polling cycle.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.virtual_models.delete_virtual_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.virtual_models.update_virtual_model(...) -> VirtualModel
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Partially update a VirtualModel.
+
+Only fields present in the request body are modified. Fields absent from
+the request body retain their current values.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.virtual_models.update_virtual_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**default_model_entity:** `typing.Optional[str]` — Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+
+
+
+
+-
+
+**autoprovisioned:** `typing.Optional[bool]` — Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+
+
+
+
+-
+
+**models:** `typing.Optional[typing.List[VirtualModelInferenceConfig]]` — Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+
+
+
+
+-
+
+**request_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+
+
+
+
+-
+
+**response_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+
+
+
+
+-
+
+**post_response_middleware:** `typing.Optional[typing.List[MiddlewareCall]]` — Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+
+
+
+
+-
+
+**override_proxy:** `typing.Optional[str]` — Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Annotations
+client.annotations.list_annotations(...) -> AnnotationsPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.annotations.list_annotations(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[AnnotationSortField]`
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[AnnotationFilter]` — Filter annotations by span_id, session_id, kind, name, created_by, and created_at range.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.annotations.create_annotation(...) -> Annotation
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, AnnotationInput_Feedback
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.annotations.create_annotation(
+ workspace="workspace",
+ request=AnnotationInput_Feedback(
+ session_id="session_id",
+ value="positive",
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request:** `AnnotationInput`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.annotations.get_annotation(...) -> Annotation
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.annotations.get_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**annotation_id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.annotations.delete_annotation(...)
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.annotations.delete_annotation(
+ workspace="workspace",
+ annotation_id="annotation_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**annotation_id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## EvaluatorResults
+client.evaluator_results.list_evaluator_results(...) -> EvaluatorResultsPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.evaluator_results.list_evaluator_results(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[EvaluatorResultSortField]`
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[EvaluatorResultFilter]` — Filter evaluator results by span_id, session_id, name, data_type, created_by, value range, and created_at range.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.evaluator_results.create_evaluator_result(...) -> EvaluatorResult
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.evaluator_results.create_evaluator_result(
+ workspace="workspace",
+ span_id="span_id",
+ session_id="session_id",
+ name="name",
+ data_type="NUMERIC",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**span_id:** `str` — Target span id. Not validated against existing spans (loose target policy).
+
+
+
+
+
+-
+
+**session_id:** `str` — Session id the target span belongs to. Denormalized so session-scoped reads stay fast.
+
+
+
+
+
+-
+
+**name:** `str` — Evaluator / metric identity (e.g. 'faithfulness/v1').
+
+
+
+
+
+-
+
+**data_type:** `EvaluatorResultDataType` — Discriminator for which of value / string_value carries the payload.
+
+
+
+
+
+-
+
+**value:** `typing.Optional[float]` — Numeric value. Required when data_type is NUMERIC or BOOLEAN (0|1).
+
+
+
+
+
+-
+
+**string_value:** `typing.Optional[str]` — String value. Required when data_type is CATEGORICAL or TEXT.
+
+
+
+
+
+-
+
+**comment:** `typing.Optional[str]` — Free-text rationale or explanation.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.evaluator_results.get_evaluator_result(...) -> EvaluatorResult
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.evaluator_results.get_evaluator_result(
+ workspace="workspace",
+ evaluator_result_id="evaluator_result_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**evaluator_result_id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.evaluator_results.list_evaluator_results_for_span(...) -> typing.List[EvaluatorResult]
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.evaluator_results.list_evaluator_results_for_span(
+ workspace="workspace",
+ span_id="span_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**span_id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## ExperimentGroups
+client.experiment_groups.list_experiment_groups(...) -> ExperimentGroupResponsesPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiment_groups.list_experiment_groups(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[ListExperimentGroupsApisIntakeV2WorkspacesWorkspaceExperimentGroupsGetRequestSort]` — Sort field; prefix with '-' for descending.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ExperimentGroupFilter]` — Filter experiment groups by name.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiment_groups.create_experiment_group(...) -> ExperimentGroupResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiment_groups.create_experiment_group(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request:** `ExperimentGroupRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiment_groups.get_experiment_group(...) -> ExperimentGroupResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiment_groups.get_experiment_group(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiment_groups.update_experiment_group(...) -> ExperimentGroupResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiment_groups.update_experiment_group(
+ workspace="workspace",
+ name_="name",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request:** `ExperimentGroupRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiment_groups.delete_experiment_group(...)
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiment_groups.delete_experiment_group(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Experiments
+client.experiments.list_experiments(...) -> ExperimentResponsesPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.list_experiments(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[ListExperimentsApisIntakeV2WorkspacesWorkspaceExperimentsGetRequestSort]` — Sort field; prefix with '-' for descending.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ExperimentFilter]` — Filter experiments by name, experiment_group_id, agent_name, agent_version, dataset_name, dataset_version, created_by, created_at, or updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiments.create_experiment(...) -> ExperimentResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.create_experiment(
+ workspace="workspace",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request:** `ExperimentRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiments.get_experiment(...) -> ExperimentResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.get_experiment(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiments.update_experiment(...) -> ExperimentResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.update_experiment(
+ workspace="workspace",
+ name_="name",
+ name="name",
+ agent_name="agent_name",
+ agent_version="agent_version",
+ dataset_name="dataset_name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request:** `ExperimentRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiments.delete_experiment(...)
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.delete_experiment(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.experiments.list_experiment_sessions(...) -> ExperimentSessionResponsesPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.experiments.list_experiment_sessions(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ExperimentSessionFilter]` — Filter sessions by test_case_id and status.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Ingest
+client.ingest.ingest_atif(...)
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, AtifAgent
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.ingest.ingest_atif(
+ workspace="workspace",
+ schema_version="ATIF-v1.0",
+ agent=AtifAgent(
+ name="name",
+ version="version",
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**schema_version:** `AtifIngestRequestSchemaVersion`
+
+
+
+
+
+-
+
+**agent:** `AtifAgent`
+
+
+
+
+
+-
+
+**experiment_context:** `typing.Optional[ExperimentContext]`
+
+
+
+
+
+-
+
+**evaluation_context:** `typing.Optional[EvaluationContext]` — Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+
+
+
+
+-
+
+**session_id:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**final_metrics:** `typing.Optional[AtifFinalMetrics]`
+
+
+
+
+
+-
+
+**continued_trajectory_ref:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**notes:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**extra:** `typing.Optional[typing.Dict[str, typing.Any]]`
+
+
+
+
+
+-
+
+**steps:** `typing.Optional[typing.List[AtifStep]]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.ingest.ingest_chat_completion(...) -> ChatCompletionsIngestResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, CapturedChatCompletionsRequest, CapturedChatMessage
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.ingest.ingest_chat_completion(
+ workspace="workspace",
+ request=CapturedChatCompletionsRequest(
+ messages=[
+ CapturedChatMessage(
+ role="user",
+ ),
+ CapturedChatMessage(
+ role="user",
+ )
+ ],
+ model="model",
+ ),
+ response={"key": "value"},
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request:** `CapturedChatCompletionsRequest`
+
+
+
+
+
+-
+
+**response:** `CapturedChatCompletionsResponse`
+
+
+
+
+
+-
+
+**experiment_context:** `typing.Optional[ExperimentContext]`
+
+
+
+
+
+-
+
+**evaluation_context:** `typing.Optional[EvaluationContext]` — Deprecated. Use experiment_context; when both are sent, experiment_context takes precedence.
+
+
+
+
+
+-
+
+**session_id:** `typing.Optional[str]` — Groups related chat-completions calls without forcing them into the same trace.
+
+
+
+
+
+-
+
+**trace_id:** `typing.Optional[str]` — Opt into joining an existing trace built via OTel or ATIF. This is not a grouping mechanism for chat-completions calls; use session_id to group related calls.
+
+
+
+
+
+-
+
+**provider:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**cost_usd:** `typing.Optional[float]` — Total estimated cost of this model call in USD. This matches ATIF step metrics; Intake stores it as semantic cost_total_usd on spans.
+
+
+
+
+
+-
+
+**cost_input_usd:** `typing.Optional[float]` — Estimated input-token cost of this model call in USD.
+
+
+
+
+
+-
+
+**cost_output_usd:** `typing.Optional[float]` — Estimated output-token cost of this model call in USD.
+
+
+
+
+
+-
+
+**cost_details:** `typing.Optional[typing.Dict[str, float]]` — Additional estimated cost breakdown fields in USD.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.ingest.ingest_otlp_traces(...) -> IngestResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.ingest.ingest_otlp_traces(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Spans
+client.spans.list_spans(...) -> SpansPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.spans.list_spans(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[SpanSortField]`
+
+
+
+
+
+-
+
+**mode:** `typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode]`
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[SpanFilter]` — Filter spans by session_id, trace_id, parent_span_id, project, evaluation context fields, source, kind, status, model, tool_name, provider, agent_id, agent_name, prompt_name, prompt_version, and started_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.spans.get_span(...) -> Span
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.spans.get_span(
+ workspace="workspace",
+ span_id="span_id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**span_id:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Traces
+client.traces.list_traces(...) -> TracesPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.traces.list_traces(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[TraceSortField]`
+
+
+
+
+
+-
+
+**mode:** `typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode]` — Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[TraceFilter]` — Filter root-span-backed traces by id, session_id, rolled-up status, root span started_at, and root-span evaluation context fields.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.traces.get_trace(...) -> Trace
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.traces.get_trace(
+ workspace="workspace",
+ id="id",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**id:** `str`
+
+
+
+
+
+-
+
+**mode:** `typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode]` — Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Jobs
+client.jobs.get_execution_profiles() -> typing.List[GetExecutionProfilesApisJobsV2ExecutionProfilesGetResponseItem]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get all currently configured execution profiles.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_execution_profiles()
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.list_jobs(...) -> PlatformJobResponsesPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List platform jobs with filtering and pagination.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.list_jobs(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[PlatformJobSortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[PlatformJobsListFilter]` — Filter jobs by workspace, project, name, status, source, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.create_job(...) -> PlatformJobResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, PlatformJobSpecInput, PlatformJobStepSpecInput, PlatformJobStepSpecInputExecutor_Cpu, ContainerSpec
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.create_job(
+ workspace="workspace",
+ spec={
+ "key": "value"
+ },
+ platform_spec=PlatformJobSpecInput(
+ steps=[
+ PlatformJobStepSpecInput(
+ name="preprocess",
+ executor=PlatformJobStepSpecInputExecutor_Cpu(
+ container=ContainerSpec(
+ image="image",
+ ),
+ ),
+ )
+ ],
+ ),
+ source="source",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**spec:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**platform_spec:** `PlatformJobSpecInput`
+
+
+
+
+
+-
+
+**source:** `str`
+
+
+
+
+
+-
+
+**name:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**ownership:** `typing.Optional[typing.Dict[str, typing.Any]]`
+
+
+
+
+
+-
+
+**custom_fields:** `typing.Optional[typing.Dict[str, typing.Any]]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.get_job_result(...) -> PlatformJobResultResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific job result.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.create_job_result(...) -> PlatformJobResultResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new result for a job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.create_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+ artifact_url="artifact_url",
+ artifact_storage_type="fileset",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**artifact_url:** `str`
+
+
+
+
+
+-
+
+**artifact_storage_type:** `FileStorageType`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.download_job_result(...) -> typing.Iterator[bytes]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Download a job result file.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.download_job_result(
+ workspace="workspace",
+ job="job",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.get_job_step(...) -> PlatformJobStep
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific job step.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_job_step(
+ workspace="workspace",
+ job="job",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.update_job_step_status(...) -> PlatformJobStep
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a job step status.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.update_job_step_status(
+ workspace="workspace",
+ job="job",
+ name="name",
+ status="created",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**status:** `PlatformJobStatus` — The new status to set for the job.
+
+
+
+
+
+-
+
+**status_details:** `typing.Optional[typing.Dict[str, typing.Any]]` — Optional status details related to the status update.
+
+
+
+
+
+-
+
+**error_details:** `typing.Optional[typing.Dict[str, typing.Any]]` — Optional error details related to the status update.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.list_job_step_tasks(...) -> PlatformJobListTaskResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List tasks for a job step.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.list_job_step_tasks(
+ workspace="workspace",
+ job="job",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.get_job_step_task(...) -> PlatformJobTask
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific job step task.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**step:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.update_job_step_task(...) -> PlatformJobTask
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a job step task.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.update_job_step_task(
+ workspace="workspace",
+ job="job",
+ step="step",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**job:** `str`
+
+
+
+
+
+-
+
+**step:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**status:** `typing.Optional[PlatformJobStatus]`
+
+
+
+
+
+-
+
+**status_details:** `typing.Optional[typing.Dict[str, typing.Any]]`
+
+
+
+
+
+-
+
+**error_details:** `typing.Optional[typing.Dict[str, typing.Any]]`
+
+
+
+
+
+-
+
+**error_stack:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.get_job(...) -> PlatformJobResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a platform job by name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_job(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.delete_job(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.delete_job(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.cancel_job(...) -> PlatformJobResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Cancel a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.cancel_job(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.page_job_logs(...) -> PlatformJobLogPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get paginated logs for a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.page_job_logs(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**limit:** `typing.Optional[int]` — Maximum number of logs to return
+
+
+
+
+
+-
+
+**page_cursor:** `typing.Optional[str]` — Page cursor
+
+
+
+
+
+-
+
+**attempt_id:** `typing.Optional[int]` — Filter logs by job attempt ID
+
+
+
+
+
+-
+
+**step_id:** `typing.Optional[str]` — Filter logs by step name
+
+
+
+
+
+-
+
+**task_id:** `typing.Optional[str]` — Filter logs by task ID
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.pause_job(...) -> PlatformJobResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Pause a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.pause_job(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.list_job_results(...) -> PlatformJobListResultResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List results for a job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.list_job_results(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[PlatformJobSortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.resume_job(...) -> PlatformJobResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Resume a paused platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.resume_job(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.get_job_status(...) -> PlatformJobStatusResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get the status of a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.get_job_status(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.update_job_status_details(...) -> typing.Any
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update the status details of a platform job.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.update_job_status_details(
+ workspace="workspace",
+ name="name",
+ request={
+ "key": "value"
+ },
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request:** `typing.Dict[str, typing.Any]`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.jobs.list_steps(...) -> PlatformJobStepWithContextsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List job steps with pagination and filtering.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.jobs.list_steps(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[PlatformJobSortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[PlatformJobStepsListFilter]` — Filter steps by job, status, and source.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Adapters
+client.adapters.list_adapters(...) -> AdaptersPage
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.adapters.list_adapters(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[AdapterEntityFilter]` — Filter adapters by name, model (parent model ref string, stored on the adapter), description, fileset, finetuning_type, enabled, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.adapters.create_adapter(...) -> Adapter
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create an adapter under a base model specified by the "model" field in the body.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.adapters.create_adapter(
+ workspace="workspace",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+ model="llama-3-8b-instruct",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**fileset:** `str` — Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+
+
+
+
+-
+
+**finetuning_type:** `FinetuningType` — Type of finetuning (LORA, P_TUNING, etc.)
+
+
+
+
+
+-
+
+**model:** `str`
+
+Base model entity.
+ Use `{workspace}/{model_name}` to reference a model in any workspace, or a single `{model_name}` resolved in the path workspace. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the adapter
+
+
+
+
+
+-
+
+**enabled:** `typing.Optional[bool]` — Whether to make this adapter available for inference post training
+
+
+
+
+
+-
+
+**lora_config:** `typing.Optional[Lora]` — Lora configuration specifics
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.adapters.get_adapter(...) -> Adapter
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.adapters.get_adapter(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.adapters.delete_adapter(...)
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.adapters.delete_adapter(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.adapters.update_adapter(...) -> Adapter
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.adapters.update_adapter(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request:** `UpdateAdapterRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## ModelDeploymentConfigs
+client.model_deployment_configs.list_deployment_configs(...) -> ModelDeploymentConfigsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List ModelDeploymentConfigs for a specific workspace.
+Returns only the latest version of each config.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.list_deployment_configs(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ModelDeploymentConfigFilter]` — Filter deployment configs by workspace, project, model_entity_id, name, description, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.create_deployment_config(...) -> ModelDeploymentConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new ModelDeploymentConfig (version 1).
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, ModelDeploymentConfigModelSpec, ContainerExecutorConfig
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.create_deployment_config(
+ workspace="workspace",
+ name="nim-config-v1",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the deployment configuration. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**engine:** `Engine` — Inference engine selecting the compiler path (nim/vllm/generic)
+
+
+
+
+
+-
+
+**model_spec:** `ModelDeploymentConfigModelSpec` — What model to serve and how -- independent of the executor it runs on
+
+
+
+
+
+-
+
+**executor_config:** `ContainerExecutorConfig` — Compute + container settings for the executor the deployment runs on
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The URN of the project associated with this deployment configuration
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the deployment configuration
+
+
+
+
+
+-
+
+**model_entity_id:** `typing.Optional[str]` — Optional reference to the base model entity ID for this deployment
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.get_deployment_config_version(...) -> ModelDeploymentConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific version of a ModelDeploymentConfig.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.get_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**config:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.delete_deployment_config_version(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a specific version of a ModelDeploymentConfig.
+
+This operation will fail with 409 Conflict if any ModelDeployments currently
+reference this specific version and are not in DELETED status. Delete or wait for
+dependent deployments to reach DELETED status before deleting the config version.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.delete_deployment_config_version(
+ workspace="workspace",
+ config="config",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**config:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.get_latest_deployment_config(...) -> ModelDeploymentConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get the latest version of a ModelDeploymentConfig.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.get_latest_deployment_config(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.update_deployment_config(...) -> ModelDeploymentConfig
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a ModelDeploymentConfig (creates a new immutable version).
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi, ModelDeploymentConfigModelSpec, ContainerExecutorConfig
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.update_deployment_config(
+ workspace="workspace",
+ name="name",
+ engine="nim",
+ model_spec=ModelDeploymentConfigModelSpec(),
+ executor_config=ContainerExecutorConfig(
+ gpu=1,
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**engine:** `Engine` — Inference engine selecting the compiler path (nim/vllm/generic)
+
+
+
+
+
+-
+
+**model_spec:** `ModelDeploymentConfigModelSpec` — What model to serve and how -- independent of the executor it runs on
+
+
+
+
+
+-
+
+**executor_config:** `ContainerExecutorConfig` — Compute + container settings for the executor the deployment runs on
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the deployment configuration
+
+
+
+
+
+-
+
+**model_entity_id:** `typing.Optional[str]` — Optional reference to the base model entity ID for this deployment
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.delete_all_deployment_config_versions(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete all versions of a ModelDeploymentConfig.
+
+This operation will fail with 409 Conflict if any ModelDeployments currently
+reference this config and are not in DELETED status. Delete or wait for
+dependent deployments to reach DELETED status before deleting the config.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.delete_all_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployment_configs.list_deployment_config_versions(...) -> typing.List[ModelDeploymentConfig]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all versions of a ModelDeploymentConfig.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployment_configs.list_deployment_config_versions(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## ModelDeployments
+client.model_deployments.list_deployments(...) -> ModelDeploymentsPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List ModelDeployments for a specific workspace.
+
+By default, returns only the latest version of each deployment.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.list_deployments(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[str]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**all_versions:** `typing.Optional[bool]` — If true, return all versions of each deployment. If false (default), return only the latest version.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ModelDeploymentFilter]` — Filter deployments by workspace, project, status, config, model_provider_id, name, status_message, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.create_deployment(...) -> ModelDeployment
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new ModelDeployment (version 1).
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.create_deployment(
+ workspace="workspace",
+ name="llama-deploy-v1",
+ config="config",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the deployment. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**config:** `str` — Reference to the ModelDeploymentConfig name
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The URN of the project associated with this deployment
+
+
+
+
+
+-
+
+**config_version:** `typing.Optional[int]` — Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.get_deployment_version(...) -> ModelDeployment
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a specific version of a ModelDeployment.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.get_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**deployment:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.delete_deployment_version(...) -> typing.Optional[typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a specific version of a ModelDeployment.
+
+If the deployment is in any state other than DELETED, this will set its status to DELETING.
+The models controller will then:
+1. Delete the infrastructure (e.g., K8s NimService)
+2. Update the status to DELETED
+
+If the deployment is already in DELETED status, calling delete again will permanently
+remove it from the database.
+
+Returns:
+- 202 Accepted: Deployment version marked for deletion (status set to DELETING)
+- 204 No Content: Deployment version permanently removed from database (was already DELETED)
+- 404 Not Found: Deployment version doesn't exist
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.delete_deployment_version(
+ workspace="workspace",
+ deployment="deployment",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**deployment:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.get_latest_deployment(...) -> ModelDeployment
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get the latest version of a ModelDeployment.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.get_latest_deployment(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.update_deployment(...) -> ModelDeployment
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a ModelDeployment (creates a new immutable version).
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.update_deployment(
+ workspace="workspace",
+ name="name",
+ config="config",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**config:** `str` — Reference to the ModelDeploymentConfig name
+
+
+
+
+
+-
+
+**config_version:** `typing.Optional[int]` — Reference to a specific ModelDeploymentConfig version. If not specified, uses latest.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.delete_all_deployment_versions(...) -> typing.Optional[typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete all versions of a ModelDeployment.
+
+If the deployment is in any state other than DELETED, this will set its status to DELETING.
+The models controller will then:
+1. Delete the infrastructure (e.g., K8s NimService)
+2. Update the status to DELETED
+
+If the deployment is already in DELETED status, calling delete again will permanently
+remove it from the database.
+
+Returns:
+- 202 Accepted: Deployment marked for deletion (status set to DELETING)
+- 204 No Content: Deployment permanently removed from database (was already DELETED)
+- 404 Not Found: Deployment doesn't exist
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.delete_all_deployment_versions(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.get_deployment_models(...) -> typing.Dict[str, typing.Any]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get Latest ModelDeployment's Model Entities from Entity Store.
+This provides the API contract that NIMs expect from Entity Store today, for pulling LoRAs,
+but enables us to enforce AuthZ boundaries.
+
+TODO: Implement model entity retrieval based on deployment config.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.get_deployment_models(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.update_deployment_status(...) -> ModelDeployment
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update the status of a ModelDeployment (mutable operation).
+If version is not specified, updates the latest version.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.update_deployment_status(
+ workspace="workspace",
+ name="name",
+ status="UNKNOWN",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**status:** `ModelDeploymentStatus` — New status for the deployment
+
+
+
+
+
+-
+
+**version:** `typing.Optional[str]`
+
+
+
+
+
+-
+
+**status_message:** `typing.Optional[str]` — Detailed status message
+
+
+
+
+
+-
+
+**model_provider_id:** `typing.Optional[str]` — Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_deployments.list_deployment_versions(...) -> typing.List[ModelDeployment]
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List all versions of a ModelDeployment.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_deployments.list_deployment_versions(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Models
+client.models.list_models(...) -> ModelEntitysPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List Models endpoint with filtering, pagination, and sorting.
+
+Supports filter parameters for various criteria (including peft, custom fields),
+pagination (page, page_size), sorting, and workspace filtering via query parameter.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.list_models(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[ModelEntitySortField]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**verbose:** `typing.Optional[bool]` — Whether to include full spec details
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ModelEntityFilter]` — Filter models by name, project, workspace, base_model, adapters, finetuning_type, prompt, lora_enabled, description, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.create_model(...) -> ModelEntity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new model entity.
+
+This endpoint creates a new Model Entity in the Models service database.
+The Model Entity will be registered for use within the platform.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.create_model(
+ workspace="workspace",
+ name="llama-3.1-8b",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the model entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The URN of the project associated with this model entity
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the model
+
+
+
+
+
+-
+
+**spec:** `typing.Optional[ModelSpec]` — Detailed specification for the model - Automatically generated by the platform at creation when fileset provided.
+
+
+
+
+
+-
+
+**finetuning_type:** `typing.Optional[FinetuningType]` — Set for full weight finetuned models
+
+
+
+
+
+-
+
+**fileset:** `typing.Optional[str]` — A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+
+
+
+
+-
+
+**base_model:** `typing.Optional[str]` — Link to another model which is used as a base for the current model
+
+
+
+
+
+-
+
+**api_endpoint:** `typing.Optional[ApiEndpointData]` — Data about the inference endpoint for this model
+
+
+
+
+
+-
+
+**backend_format:** `typing.Optional[BackendFormat]` — Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+
+
+
+
+-
+
+**prompt:** `typing.Optional[PromptData]` — Configuration for prompt engineering
+
+
+
+
+
+-
+
+**custom_fields:** `typing.Optional[typing.Dict[str, typing.Any]]` — Custom fields for additional metadata
+
+
+
+
+
+-
+
+**ownership:** `typing.Optional[typing.Dict[str, typing.Any]]` — Ownership information for the model
+
+
+
+
+
+-
+
+**model_providers:** `typing.Optional[typing.List[str]]` — List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+
+
+
+
+-
+
+**trust_remote_code:** `typing.Optional[bool]`
+
+Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.create_model_adapter(...) -> Adapter
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Adds an Adapter to the Model
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.create_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ name="lora-adapter-v1",
+ fileset="fileset",
+ finetuning_type="lora_merged",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**model_name:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the adapter. Name must be unique in the workspace. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**fileset:** `str` — Location where adapter files are stored - expected format {workspace}/{fileset_name}
+
+
+
+
+
+-
+
+**finetuning_type:** `FinetuningType` — Type of finetuning (LORA, P_TUNING, etc.)
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the adapter
+
+
+
+
+
+-
+
+**enabled:** `typing.Optional[bool]` — Whether to make this adapter available for inference post training
+
+
+
+
+
+-
+
+**lora_config:** `typing.Optional[Lora]` — Lora configuration specifics
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.delete_model_adapter(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete Adapter from Model entity.
+
+Permanently deletes an adapter from a model entity, if it was deployed, it will be cleaned up automatically.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.delete_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**model_name:** `str`
+
+
+
+
+
+-
+
+**adapter:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.update_model_adapter(...) -> Adapter
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update Adapter deployment or description.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.update_model_adapter(
+ workspace="workspace",
+ model_name="model_name",
+ adapter="adapter",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**model_name:** `str`
+
+
+
+
+
+-
+
+**adapter:** `str`
+
+
+
+
+
+-
+
+**request:** `UpdateAdapterRequest`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.get_model(...) -> ModelEntity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get Model by Workspace and Name.
+
+Returns the details of a specific model entity identified by its workspace and name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.get_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**verbose:** `typing.Optional[bool]` — Whether to include full spec details
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.delete_model(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete Model entity.
+
+Permanently deletes a model entity from the platform.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.delete_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.models.update_model(...) -> ModelEntity
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update Model metadata.
+
+Updates the metadata of an existing model entity. If the request body has an empty field,
+the old value is kept.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.models.update_model(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**verbose:** `typing.Optional[bool]` — Whether to include full spec details
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the model
+
+
+
+
+
+-
+
+**spec:** `typing.Optional[ModelSpec]` — Detailed specification for the model
+
+
+
+
+
+-
+
+**fileset:** `typing.Optional[str]` — A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+
+
+
+
+
+-
+
+**finetuning_type:** `typing.Optional[FinetuningType]` — Set for full weight finetuned models
+
+
+
+
+
+-
+
+**base_model:** `typing.Optional[str]` — Link to another model which is used as a base for the current model
+
+
+
+
+
+-
+
+**api_endpoint:** `typing.Optional[ApiEndpointData]` — Data about the inference endpoint for this model
+
+
+
+
+
+-
+
+**backend_format:** `typing.Optional[BackendFormat]` — Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+
+
+
+
+
+-
+
+**prompt:** `typing.Optional[PromptData]` — Configuration for prompt engineering
+
+
+
+
+
+-
+
+**custom_fields:** `typing.Optional[typing.Dict[str, typing.Any]]` — Custom fields for additional metadata
+
+
+
+
+
+-
+
+**ownership:** `typing.Optional[typing.Dict[str, typing.Any]]` — Ownership information for the model
+
+
+
+
+
+-
+
+**model_providers:** `typing.Optional[typing.List[str]]` — List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+
+
+
+
+
+-
+
+**trust_remote_code:** `typing.Optional[bool]`
+
+Whether to trust remote code for the checkpoint.
+ Some models without support in certain libraries such as Transformers require additional custom Python code to execute.
+ Due to security ramifications of running arbitrary code, this can only be set to true on one of the following conditions:
+ (1) the model's fileset's source is pre-approved in the platform config, or
+ (2) the user creating this model is an administrator.
+
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## ModelProviders
+client.model_providers.list_providers(...) -> ModelProvidersPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List model providers for a specific workspace.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.list_providers(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**sort:** `typing.Optional[ModelProviderSort]` — The field to sort by. To sort in decreasing order, use `-` in front of the field name.
+
+
+
+
+
+-
+
+**filter:** `typing.Optional[ModelProviderFilter]` — Filter model providers by workspace, project, status, model_deployment_id, name, description, host_url, created_at, and updated_at.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_providers.create_provider(...) -> ModelProvider
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new model provider.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.create_provider(
+ workspace="workspace",
+ name="my-nim-provider",
+ host_url="host_url",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — Name of the model provider. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**host_url:** `str` — The network endpoint URL for the model provider
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The URN of the project associated with this model provider
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the model provider
+
+
+
+
+
+-
+
+**api_key_secret_name:** `typing.Optional[str]` — Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+
+
+
+
+-
+
+**enabled_models:** `typing.Optional[typing.List[str]]` — Optional list of specific models to enable from this provider
+
+
+
+
+
+-
+
+**default_extra_body:** `typing.Optional[typing.Dict[str, typing.Any]]` — Default body parameters for inference requests. Can be overridden by user requests.
+
+
+
+
+
+-
+
+**default_extra_headers:** `typing.Optional[typing.Dict[str, str]]` — Default headers for inference requests. Can be overridden by user requests.
+
+
+
+
+
+-
+
+**required_extra_body:** `typing.Optional[typing.Dict[str, typing.Any]]` — Required body parameters for inference requests. Cannot be overridden by user requests.
+
+
+
+
+
+-
+
+**required_extra_headers:** `typing.Optional[typing.Dict[str, str]]` — Required headers for inference requests. Cannot be overridden by user requests.
+
+
+
+
+
+-
+
+**model_deployment_id:** `typing.Optional[str]` — Optional reference to the ModelDeployment ID if this provider is being auto-created for a deployment
+
+
+
+
+
+-
+
+**status:** `typing.Optional[ModelProviderStatus]` — Status of the model provider
+
+
+
+
+
+-
+
+**status_message:** `typing.Optional[str]` — Status message
+
+
+
+
+
+-
+
+**auth_header_format:** `typing.Optional[str]` — Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_providers.get_provider(...) -> ModelProvider
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Get a model provider by workspace and name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.get_provider(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_providers.upsert_provider(...) -> ModelProvider
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create or update a model provider.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.upsert_provider(
+ workspace="workspace",
+ name="name",
+ host_url="host_url",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**host_url:** `str` — The network endpoint URL for the model provider
+
+
+
+
+
+-
+
+**project:** `typing.Optional[str]` — The URN of the project associated with this model provider
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — Optional description of the model provider
+
+
+
+
+
+-
+
+**api_key_secret_name:** `typing.Optional[str]` — Reference to an API key secret stored in the Secrets service. Create the secret first via secrets API, then pass the secret name here.
+
+
+
+
+
+-
+
+**enabled_models:** `typing.Optional[typing.List[str]]` — Optional list of specific models to enable from this provider
+
+
+
+
+
+-
+
+**default_extra_body:** `typing.Optional[typing.Dict[str, typing.Any]]` — Default body parameters for inference requests. Can be overridden by user requests.
+
+
+
+
+
+-
+
+**default_extra_headers:** `typing.Optional[typing.Dict[str, str]]` — Default headers for inference requests. Can be overridden by user requests.
+
+
+
+
+
+-
+
+**required_extra_body:** `typing.Optional[typing.Dict[str, typing.Any]]` — Required body parameters for inference requests. Cannot be overridden by user requests.
+
+
+
+
+
+-
+
+**required_extra_headers:** `typing.Optional[typing.Dict[str, str]]` — Required headers for inference requests. Cannot be overridden by user requests.
+
+
+
+
+
+-
+
+**model_deployment_id:** `typing.Optional[str]` — Optional reference to the ModelDeployment ID if this provider is associated with a deployment
+
+
+
+
+
+-
+
+**status:** `typing.Optional[ModelProviderStatus]` — Status of the model provider
+
+
+
+
+
+-
+
+**status_message:** `typing.Optional[str]` — Status message
+
+
+
+
+
+-
+
+**auth_header_format:** `typing.Optional[str]` — Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_providers.delete_provider(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a model provider by workspace and name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.delete_provider(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.model_providers.update_provider_status(...) -> ModelProvider
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update status-related fields of a model provider.
+
+This endpoint supports partial updates for fields managed by Models Controller:
+- model_deployment_id
+- served_models
+- status
+- status_message
+
+If status is provided without status_message, status_message will be set to empty string.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.model_providers.update_provider_status(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**model_deployment_id:** `typing.Optional[str]` — Reference to the ModelDeployment ID if this provider is associated with a deployment
+
+
+
+
+
+-
+
+**served_models:** `typing.Optional[typing.List[ServedModelMapping]]` — List of models served by this provider with routing information for IGW
+
+
+
+
+
+-
+
+**status:** `typing.Optional[ModelProviderStatus]` — Status of the model provider
+
+
+
+
+
+-
+
+**status_message:** `typing.Optional[str]` — Status message. If status is provided without status_message, defaults to empty string.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## SecretsAdmin
+client.secrets_admin.admin_rotate_encryption_keys() -> PlatformSecretAdminRotationResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Rotate encryption keys for all platform secrets.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets_admin.admin_rotate_encryption_keys()
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+## Secrets
+client.secrets.list_secrets(...) -> PlatformSecretResponsesPage
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+List available secrets
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.list_secrets(
+ workspace="workspace",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**page:** `typing.Optional[int]` — Page number.
+
+
+
+
+
+-
+
+**page_size:** `typing.Optional[int]` — Page size.
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.secrets.create_secret(...) -> PlatformSecretResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Create a new secret.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.create_secret(
+ workspace="workspace",
+ name="hf-token",
+ value="value",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str` — The name of the secret to create. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+
+
+
+
+-
+
+**value:** `str` — The payload of the secret
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — An optional description of the secret
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.secrets.get_secret(...) -> PlatformSecretResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieve a secret by its name.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.get_secret(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.secrets.delete_secret(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Delete a secret.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.delete_secret(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.secrets.update_secret(...) -> PlatformSecretResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Update a secret's metadata.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.update_secret(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**description:** `typing.Optional[str]` — An optional description of the secret
+
+
+
+
+
+-
+
+**value:** `typing.Optional[str]` — The new secret value
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.secrets.access_secret(...) -> PlatformSecretAccessResponse
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Access the value of a secret.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from nvidia import NvidiaApi
+
+client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+)
+
+client.secrets.access_secret(
+ workspace="workspace",
+ name="name",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**workspace:** `str`
+
+
+
+
+
+-
+
+**name:** `str`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sdks/python/secrets/__init__.py b/sdks/python/secrets/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/secrets/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/secrets/client.py b/sdks/python/secrets/client.py
new file mode 100644
index 0000000000..b00de86602
--- /dev/null
+++ b/sdks/python/secrets/client.py
@@ -0,0 +1,591 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.platform_secret_access_response import PlatformSecretAccessResponse
+from ..types.platform_secret_response import PlatformSecretResponse
+from ..types.platform_secret_responses_page import PlatformSecretResponsesPage
+from .raw_client import AsyncRawSecretsClient, RawSecretsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class SecretsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawSecretsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawSecretsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawSecretsClient
+ """
+ return self._raw_client
+
+ def list_secrets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponsesPage:
+ """
+ List available secrets
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.list_secrets(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_secrets(
+ workspace, page=page, page_size=page_size, request_options=request_options
+ )
+ return _response.data
+
+ def create_secret(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ value: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponse:
+ """
+ Create a new secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the secret to create. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ value : str
+ The payload of the secret
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.create_secret(
+ workspace="workspace",
+ name="hf-token",
+ value="value",
+ )
+ """
+ _response = self._raw_client.create_secret(
+ workspace, name=name, value=value, description=description, request_options=request_options
+ )
+ return _response.data
+
+ def get_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretResponse:
+ """
+ Retrieve a secret by its name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.get_secret(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_secret(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.delete_secret(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_secret(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_secret(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ value: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponse:
+ """
+ Update a secret's metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ value : typing.Optional[str]
+ The new secret value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.update_secret(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_secret(
+ workspace, name, description=description, value=value, request_options=request_options
+ )
+ return _response.data
+
+ def access_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretAccessResponse:
+ """
+ Access the value of a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretAccessResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets.access_secret(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.access_secret(workspace, name, request_options=request_options)
+ return _response.data
+
+
+class AsyncSecretsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawSecretsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawSecretsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawSecretsClient
+ """
+ return self._raw_client
+
+ async def list_secrets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponsesPage:
+ """
+ List available secrets
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponsesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.list_secrets(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_secrets(
+ workspace, page=page, page_size=page_size, request_options=request_options
+ )
+ return _response.data
+
+ async def create_secret(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ value: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponse:
+ """
+ Create a new secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the secret to create. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ value : str
+ The payload of the secret
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.create_secret(
+ workspace="workspace",
+ name="hf-token",
+ value="value",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_secret(
+ workspace, name=name, value=value, description=description, request_options=request_options
+ )
+ return _response.data
+
+ async def get_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretResponse:
+ """
+ Retrieve a secret by its name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.get_secret(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_secret(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Delete a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.delete_secret(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_secret(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_secret(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ value: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> PlatformSecretResponse:
+ """
+ Update a secret's metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ value : typing.Optional[str]
+ The new secret value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.update_secret(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_secret(
+ workspace, name, description=description, value=value, request_options=request_options
+ )
+ return _response.data
+
+ async def access_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretAccessResponse:
+ """
+ Access the value of a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretAccessResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets.access_secret(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.access_secret(workspace, name, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/secrets/raw_client.py b/sdks/python/secrets/raw_client.py
new file mode 100644
index 0000000000..99ce97571b
--- /dev/null
+++ b/sdks/python/secrets/raw_client.py
@@ -0,0 +1,784 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.platform_secret_access_response import PlatformSecretAccessResponse
+from ..types.platform_secret_response import PlatformSecretResponse
+from ..types.platform_secret_responses_page import PlatformSecretResponsesPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawSecretsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_secrets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformSecretResponsesPage]:
+ """
+ List available secrets
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretResponsesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponsesPage,
+ parse_obj_as(
+ type_=PlatformSecretResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_secret(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ value: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformSecretResponse]:
+ """
+ Create a new secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the secret to create. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ value : str
+ The payload of the secret
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "value": value,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformSecretResponse]:
+ """
+ Retrieve a secret by its name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Delete a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_secret(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ value: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[PlatformSecretResponse]:
+ """
+ Update a secret's metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ value : typing.Optional[str]
+ The new secret value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "value": value,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def access_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformSecretAccessResponse]:
+ """
+ Access the value of a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretAccessResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}/access",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretAccessResponse,
+ parse_obj_as(
+ type_=PlatformSecretAccessResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawSecretsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_secrets(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformSecretResponsesPage]:
+ """
+ List available secrets
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretResponsesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponsesPage,
+ parse_obj_as(
+ type_=PlatformSecretResponsesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_secret(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ value: str,
+ description: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformSecretResponse]:
+ """
+ Create a new secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ The name of the secret to create. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+
+ value : str
+ The payload of the secret
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets",
+ method="POST",
+ json={
+ "name": name,
+ "description": description,
+ "value": value,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformSecretResponse]:
+ """
+ Retrieve a secret by its name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Delete a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_secret(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ description: typing.Optional[str] = OMIT,
+ value: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[PlatformSecretResponse]:
+ """
+ Update a secret's metadata.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ description : typing.Optional[str]
+ An optional description of the secret
+
+ value : typing.Optional[str]
+ The new secret value
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "description": description,
+ "value": value,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretResponse,
+ parse_obj_as(
+ type_=PlatformSecretResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def access_secret(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformSecretAccessResponse]:
+ """
+ Access the value of a secret.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretAccessResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/secrets/v2/workspaces/{encode_path_param(workspace)}/secrets/{encode_path_param(name)}/access",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretAccessResponse,
+ parse_obj_as(
+ type_=PlatformSecretAccessResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/secrets_admin/__init__.py b/sdks/python/secrets_admin/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/secrets_admin/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/secrets_admin/client.py b/sdks/python/secrets_admin/client.py
new file mode 100644
index 0000000000..f78c9d32dd
--- /dev/null
+++ b/sdks/python/secrets_admin/client.py
@@ -0,0 +1,104 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.platform_secret_admin_rotation_response import PlatformSecretAdminRotationResponse
+from .raw_client import AsyncRawSecretsAdminClient, RawSecretsAdminClient
+
+
+class SecretsAdminClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawSecretsAdminClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawSecretsAdminClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawSecretsAdminClient
+ """
+ return self._raw_client
+
+ def admin_rotate_encryption_keys(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretAdminRotationResponse:
+ """
+ Rotate encryption keys for all platform secrets.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretAdminRotationResponse
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.secrets_admin.admin_rotate_encryption_keys()
+ """
+ _response = self._raw_client.admin_rotate_encryption_keys(request_options=request_options)
+ return _response.data
+
+
+class AsyncSecretsAdminClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawSecretsAdminClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawSecretsAdminClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawSecretsAdminClient
+ """
+ return self._raw_client
+
+ async def admin_rotate_encryption_keys(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> PlatformSecretAdminRotationResponse:
+ """
+ Rotate encryption keys for all platform secrets.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ PlatformSecretAdminRotationResponse
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.secrets_admin.admin_rotate_encryption_keys()
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.admin_rotate_encryption_keys(request_options=request_options)
+ return _response.data
diff --git a/sdks/python/secrets_admin/raw_client.py b/sdks/python/secrets_admin/raw_client.py
new file mode 100644
index 0000000000..8eefd99ee9
--- /dev/null
+++ b/sdks/python/secrets_admin/raw_client.py
@@ -0,0 +1,103 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..types.platform_secret_admin_rotation_response import PlatformSecretAdminRotationResponse
+from pydantic import ValidationError
+
+
+class RawSecretsAdminClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def admin_rotate_encryption_keys(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[PlatformSecretAdminRotationResponse]:
+ """
+ Rotate encryption keys for all platform secrets.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[PlatformSecretAdminRotationResponse]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ "apis/secrets/v2/rotate-encryption-keys",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretAdminRotationResponse,
+ parse_obj_as(
+ type_=PlatformSecretAdminRotationResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawSecretsAdminClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def admin_rotate_encryption_keys(
+ self, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[PlatformSecretAdminRotationResponse]:
+ """
+ Rotate encryption keys for all platform secrets.
+
+ Parameters
+ ----------
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[PlatformSecretAdminRotationResponse]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ "apis/secrets/v2/rotate-encryption-keys",
+ method="POST",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ PlatformSecretAdminRotationResponse,
+ parse_obj_as(
+ type_=PlatformSecretAdminRotationResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/spans/__init__.py b/sdks/python/spans/__init__.py
new file mode 100644
index 0000000000..7375ed2980
--- /dev/null
+++ b/sdks/python/spans/__init__.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode
+_dynamic_imports: typing.Dict[str, str] = {"ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode": ".types"}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode"]
diff --git a/sdks/python/spans/client.py b/sdks/python/spans/client.py
new file mode 100644
index 0000000000..bfc7d2c465
--- /dev/null
+++ b/sdks/python/spans/client.py
@@ -0,0 +1,246 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.span import Span
+from ..types.span_filter import SpanFilter
+from ..types.span_sort_field import SpanSortField
+from ..types.spans_page import SpansPage
+from .raw_client import AsyncRawSpansClient, RawSpansClient
+from .types.list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode import (
+ ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode,
+)
+
+
+class SpansClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawSpansClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawSpansClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawSpansClient
+ """
+ return self._raw_client
+
+ def list_spans(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[SpanSortField] = None,
+ mode: typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode] = None,
+ filter: typing.Optional[SpanFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SpansPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[SpanSortField]
+
+ mode : typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode]
+
+ filter : typing.Optional[SpanFilter]
+ Filter spans by session_id, trace_id, parent_span_id, project, evaluation context fields, source, kind, status, model, tool_name, provider, agent_id, agent_name, prompt_name, prompt_version, and started_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SpansPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.spans.list_spans(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_spans(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ mode=mode,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Span:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Span
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.spans.get_span(
+ workspace="workspace",
+ span_id="span_id",
+ )
+ """
+ _response = self._raw_client.get_span(workspace, span_id, request_options=request_options)
+ return _response.data
+
+
+class AsyncSpansClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawSpansClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawSpansClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawSpansClient
+ """
+ return self._raw_client
+
+ async def list_spans(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[SpanSortField] = None,
+ mode: typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode] = None,
+ filter: typing.Optional[SpanFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SpansPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[SpanSortField]
+
+ mode : typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode]
+
+ filter : typing.Optional[SpanFilter]
+ Filter spans by session_id, trace_id, parent_span_id, project, evaluation context fields, source, kind, status, model, tool_name, provider, agent_id, agent_name, prompt_name, prompt_version, and started_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SpansPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.spans.list_spans(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_spans(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ mode=mode,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> Span:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Span
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.spans.get_span(
+ workspace="workspace",
+ span_id="span_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_span(workspace, span_id, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/spans/raw_client.py b/sdks/python/spans/raw_client.py
new file mode 100644
index 0000000000..21d7998e10
--- /dev/null
+++ b/sdks/python/spans/raw_client.py
@@ -0,0 +1,300 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.span import Span
+from ..types.span_filter import SpanFilter
+from ..types.span_sort_field import SpanSortField
+from ..types.spans_page import SpansPage
+from .types.list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode import (
+ ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode,
+)
+from pydantic import ValidationError
+
+
+class RawSpansClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_spans(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[SpanSortField] = None,
+ mode: typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode] = None,
+ filter: typing.Optional[SpanFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[SpansPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[SpanSortField]
+
+ mode : typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode]
+
+ filter : typing.Optional[SpanFilter]
+ Filter spans by session_id, trace_id, parent_span_id, project, evaluation context fields, source, kind, status, model, tool_name, provider, agent_id, agent_name, prompt_name, prompt_version, and started_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[SpansPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "mode": mode,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=SpanFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ SpansPage,
+ parse_obj_as(
+ type_=SpansPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[Span]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Span]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans/{encode_path_param(span_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Span,
+ parse_obj_as(
+ type_=Span, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawSpansClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_spans(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[SpanSortField] = None,
+ mode: typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode] = None,
+ filter: typing.Optional[SpanFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[SpansPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[SpanSortField]
+
+ mode : typing.Optional[ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode]
+
+ filter : typing.Optional[SpanFilter]
+ Filter spans by session_id, trace_id, parent_span_id, project, evaluation context fields, source, kind, status, model, tool_name, provider, agent_id, agent_name, prompt_name, prompt_version, and started_at.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[SpansPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "mode": mode,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=SpanFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ SpansPage,
+ parse_obj_as(
+ type_=SpansPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_span(
+ self, workspace: str, span_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[Span]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ span_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Span]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/spans/{encode_path_param(span_id)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Span,
+ parse_obj_as(
+ type_=Span, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/spans/types/__init__.py b/sdks/python/spans/types/__init__.py
new file mode 100644
index 0000000000..3ef30a5e36
--- /dev/null
+++ b/sdks/python/spans/types/__init__.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode import (
+ ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode": ".list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode"
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = ["ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode"]
diff --git a/sdks/python/spans/types/list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode.py b/sdks/python/spans/types/list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode.py
new file mode 100644
index 0000000000..83ab5033ac
--- /dev/null
+++ b/sdks/python/spans/types/list_spans_apis_intake_v2workspaces_workspace_spans_get_request_mode.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ListSpansApisIntakeV2WorkspacesWorkspaceSpansGetRequestMode = typing.Union[
+ typing.Literal["summary", "detailed"], typing.Any
+]
diff --git a/sdks/python/tests/conftest.py b/sdks/python/tests/conftest.py
new file mode 100644
index 0000000000..25710dbe62
--- /dev/null
+++ b/sdks/python/tests/conftest.py
@@ -0,0 +1,21 @@
+import pytest
+
+
+def _has_httpx_aiohttp() -> bool:
+ """Check if httpx_aiohttp is importable."""
+ try:
+ import httpx_aiohttp # type: ignore[import-not-found] # noqa: F401
+
+ return True
+ except ImportError:
+ return False
+
+
+def pytest_collection_modifyitems(config: pytest.Config, items: list) -> None:
+ """Auto-skip @pytest.mark.aiohttp tests when httpx_aiohttp is not installed."""
+ if _has_httpx_aiohttp():
+ return
+ skip_aiohttp = pytest.mark.skip(reason="httpx_aiohttp not installed")
+ for item in items:
+ if "aiohttp" in item.keywords:
+ item.add_marker(skip_aiohttp)
diff --git a/sdks/python/tests/test_aiohttp_autodetect.py b/sdks/python/tests/test_aiohttp_autodetect.py
new file mode 100644
index 0000000000..f066076fd8
--- /dev/null
+++ b/sdks/python/tests/test_aiohttp_autodetect.py
@@ -0,0 +1,113 @@
+import importlib
+import sys
+import unittest
+from unittest import mock
+
+import httpx
+import pytest
+
+
+class TestMakeDefaultAsyncClientWithoutAiohttp(unittest.TestCase):
+ """Tests for _make_default_async_client when httpx_aiohttp is NOT installed."""
+
+ def test_returns_httpx_async_client(self) -> None:
+ """When httpx_aiohttp is not installed, returns plain httpx.AsyncClient."""
+ with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}):
+ from nvidia.client import _make_default_async_client
+
+ client = _make_default_async_client(timeout=60, follow_redirects=True)
+ self.assertIsInstance(client, httpx.AsyncClient)
+ self.assertEqual(client.timeout.read, 60)
+ self.assertTrue(client.follow_redirects)
+
+ def test_follow_redirects_none(self) -> None:
+ """When follow_redirects is None, omits it from httpx.AsyncClient."""
+ with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}):
+ from nvidia.client import _make_default_async_client
+
+ client = _make_default_async_client(timeout=60, follow_redirects=None)
+ self.assertIsInstance(client, httpx.AsyncClient)
+ self.assertFalse(client.follow_redirects)
+
+ def test_explicit_httpx_client_bypasses_autodetect(self) -> None:
+ """When user passes httpx_client explicitly, _make_default_async_client is not called."""
+
+ explicit_client = httpx.AsyncClient(timeout=120)
+ with mock.patch("nvidia.client._make_default_async_client") as mock_make:
+ # Replicate the generated conditional: httpx_client if httpx_client is not None else _make_default_async_client(...)
+ result = explicit_client if explicit_client is not None else mock_make(timeout=60, follow_redirects=True)
+ mock_make.assert_not_called()
+ self.assertIs(result, explicit_client)
+
+
+@pytest.mark.aiohttp
+class TestMakeDefaultAsyncClientWithAiohttp(unittest.TestCase):
+ """Tests for _make_default_async_client when httpx_aiohttp IS installed."""
+
+ def test_returns_aiohttp_client(self) -> None:
+ """When httpx_aiohttp is installed, returns HttpxAiohttpClient."""
+ import httpx_aiohttp # type: ignore[import-not-found]
+ from nvidia.client import _make_default_async_client
+
+ client = _make_default_async_client(timeout=60, follow_redirects=True)
+ self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient)
+ self.assertEqual(client.timeout.read, 60)
+ self.assertTrue(client.follow_redirects)
+
+ def test_follow_redirects_none(self) -> None:
+ """When httpx_aiohttp is installed and follow_redirects is None, omits it."""
+ import httpx_aiohttp # type: ignore[import-not-found]
+ from nvidia.client import _make_default_async_client
+
+ client = _make_default_async_client(timeout=60, follow_redirects=None)
+ self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient)
+ self.assertFalse(client.follow_redirects)
+
+
+class TestDefaultClientsWithoutAiohttp(unittest.TestCase):
+ """Tests for _default_clients.py convenience classes (no aiohttp)."""
+
+ def test_default_async_httpx_client_defaults(self) -> None:
+ """DefaultAsyncHttpxClient applies SDK defaults."""
+ from nvidia._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAsyncHttpxClient
+
+ client = DefaultAsyncHttpxClient()
+ self.assertIsInstance(client, httpx.AsyncClient)
+ self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT)
+ self.assertTrue(client.follow_redirects)
+
+ def test_default_async_httpx_client_overrides(self) -> None:
+ """DefaultAsyncHttpxClient allows overriding defaults."""
+ from nvidia._default_clients import DefaultAsyncHttpxClient
+
+ client = DefaultAsyncHttpxClient(timeout=30, follow_redirects=False)
+ self.assertEqual(client.timeout.read, 30)
+ self.assertFalse(client.follow_redirects)
+
+ def test_default_aiohttp_client_raises_without_package(self) -> None:
+ """DefaultAioHttpClient raises RuntimeError when httpx_aiohttp not installed."""
+ import nvidia._default_clients
+
+ with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}):
+ importlib.reload(nvidia._default_clients)
+
+ with self.assertRaises(RuntimeError) as ctx:
+ nvidia._default_clients.DefaultAioHttpClient()
+ self.assertIn("pip install nvidia[aiohttp]", str(ctx.exception))
+
+ importlib.reload(nvidia._default_clients)
+
+
+@pytest.mark.aiohttp
+class TestDefaultClientsWithAiohttp(unittest.TestCase):
+ """Tests for _default_clients.py when httpx_aiohttp IS installed."""
+
+ def test_default_aiohttp_client_defaults(self) -> None:
+ """DefaultAioHttpClient works when httpx_aiohttp is installed."""
+ import httpx_aiohttp # type: ignore[import-not-found]
+ from nvidia._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAioHttpClient
+
+ client = DefaultAioHttpClient()
+ self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient)
+ self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT)
+ self.assertTrue(client.follow_redirects)
diff --git a/sdks/python/traces/__init__.py b/sdks/python/traces/__init__.py
new file mode 100644
index 0000000000..5e72a2c9f3
--- /dev/null
+++ b/sdks/python/traces/__init__.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .types import (
+ GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode,
+ ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode": ".types",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode": ".types",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode",
+]
diff --git a/sdks/python/traces/client.py b/sdks/python/traces/client.py
new file mode 100644
index 0000000000..138ed26a76
--- /dev/null
+++ b/sdks/python/traces/client.py
@@ -0,0 +1,267 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.trace import Trace
+from ..types.trace_filter import TraceFilter
+from ..types.trace_sort_field import TraceSortField
+from ..types.traces_page import TracesPage
+from .raw_client import AsyncRawTracesClient, RawTracesClient
+from .types.get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode import (
+ GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode,
+)
+from .types.list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode import (
+ ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode,
+)
+
+
+class TracesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawTracesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawTracesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawTracesClient
+ """
+ return self._raw_client
+
+ def list_traces(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[TraceSortField] = None,
+ mode: typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode] = None,
+ filter: typing.Optional[TraceFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> TracesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[TraceSortField]
+
+ mode : typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ filter : typing.Optional[TraceFilter]
+ Filter root-span-backed traces by id, session_id, rolled-up status, root span started_at, and root-span evaluation context fields.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ TracesPage
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.traces.list_traces(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_traces(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ mode=mode,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_trace(
+ self,
+ workspace: str,
+ id: str,
+ *,
+ mode: typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Trace:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ id : str
+
+ mode : typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Trace
+ Successful Response
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.traces.get_trace(
+ workspace="workspace",
+ id="id",
+ )
+ """
+ _response = self._raw_client.get_trace(workspace, id, mode=mode, request_options=request_options)
+ return _response.data
+
+
+class AsyncTracesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawTracesClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawTracesClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawTracesClient
+ """
+ return self._raw_client
+
+ async def list_traces(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[TraceSortField] = None,
+ mode: typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode] = None,
+ filter: typing.Optional[TraceFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> TracesPage:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[TraceSortField]
+
+ mode : typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ filter : typing.Optional[TraceFilter]
+ Filter root-span-backed traces by id, session_id, rolled-up status, root span started_at, and root-span evaluation context fields.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ TracesPage
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.traces.list_traces(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_traces(
+ workspace,
+ page=page,
+ page_size=page_size,
+ sort=sort,
+ mode=mode,
+ filter=filter,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_trace(
+ self,
+ workspace: str,
+ id: str,
+ *,
+ mode: typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> Trace:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ id : str
+
+ mode : typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ Trace
+ Successful Response
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.traces.get_trace(
+ workspace="workspace",
+ id="id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_trace(workspace, id, mode=mode, request_options=request_options)
+ return _response.data
diff --git a/sdks/python/traces/raw_client.py b/sdks/python/traces/raw_client.py
new file mode 100644
index 0000000000..5d42f6408c
--- /dev/null
+++ b/sdks/python/traces/raw_client.py
@@ -0,0 +1,327 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.trace import Trace
+from ..types.trace_filter import TraceFilter
+from ..types.trace_sort_field import TraceSortField
+from ..types.traces_page import TracesPage
+from .types.get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode import (
+ GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode,
+)
+from .types.list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode import (
+ ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode,
+)
+from pydantic import ValidationError
+
+
+class RawTracesClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_traces(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[TraceSortField] = None,
+ mode: typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode] = None,
+ filter: typing.Optional[TraceFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[TracesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[TraceSortField]
+
+ mode : typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ filter : typing.Optional[TraceFilter]
+ Filter root-span-backed traces by id, session_id, rolled-up status, root span started_at, and root-span evaluation context fields.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[TracesPage]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/traces",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "mode": mode,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=TraceFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ TracesPage,
+ parse_obj_as(
+ type_=TracesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_trace(
+ self,
+ workspace: str,
+ id: str,
+ *,
+ mode: typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[Trace]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ id : str
+
+ mode : typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[Trace]
+ Successful Response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/traces/{encode_path_param(id)}",
+ method="GET",
+ params={
+ "mode": mode,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Trace,
+ parse_obj_as(
+ type_=Trace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawTracesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_traces(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[TraceSortField] = None,
+ mode: typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode] = None,
+ filter: typing.Optional[TraceFilter] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[TracesPage]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number.
+
+ page_size : typing.Optional[int]
+ Page size.
+
+ sort : typing.Optional[TraceSortField]
+
+ mode : typing.Optional[ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ filter : typing.Optional[TraceFilter]
+ Filter root-span-backed traces by id, session_id, rolled-up status, root span started_at, and root-span evaluation context fields.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[TracesPage]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/traces",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ "mode": mode,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=TraceFilter, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ TracesPage,
+ parse_obj_as(
+ type_=TracesPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_trace(
+ self,
+ workspace: str,
+ id: str,
+ *,
+ mode: typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[Trace]:
+ """
+ Parameters
+ ----------
+ workspace : str
+
+ id : str
+
+ mode : typing.Optional[GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode]
+ Use summary for root-span trace fields only, or detailed to include token, cost, and span-count rollups.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[Trace]
+ Successful Response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/intake/v2/workspaces/{encode_path_param(workspace)}/traces/{encode_path_param(id)}",
+ method="GET",
+ params={
+ "mode": mode,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ Trace,
+ parse_obj_as(
+ type_=Trace, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
diff --git a/sdks/python/traces/types/__init__.py b/sdks/python/traces/types/__init__.py
new file mode 100644
index 0000000000..12eefd3281
--- /dev/null
+++ b/sdks/python/traces/types/__init__.py
@@ -0,0 +1,45 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode import (
+ GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode,
+ )
+ from .list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode import (
+ ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode,
+ )
+_dynamic_imports: typing.Dict[str, str] = {
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode": ".get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode": ".list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode",
+ "ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode",
+]
diff --git a/sdks/python/traces/types/get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode.py b/sdks/python/traces/types/get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode.py
new file mode 100644
index 0000000000..d74dddb468
--- /dev/null
+++ b/sdks/python/traces/types/get_trace_apis_intake_v2workspaces_workspace_traces_id_get_request_mode.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GetTraceApisIntakeV2WorkspacesWorkspaceTracesIdGetRequestMode = typing.Union[
+ typing.Literal["summary", "detailed"], typing.Any
+]
diff --git a/sdks/python/traces/types/list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode.py b/sdks/python/traces/types/list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode.py
new file mode 100644
index 0000000000..3bee2a78fc
--- /dev/null
+++ b/sdks/python/traces/types/list_traces_apis_intake_v2workspaces_workspace_traces_get_request_mode.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ListTracesApisIntakeV2WorkspacesWorkspaceTracesGetRequestMode = typing.Union[
+ typing.Literal["summary", "detailed"], typing.Any
+]
diff --git a/sdks/python/types/__init__.py b/sdks/python/types/__init__.py
new file mode 100644
index 0000000000..f7a18f3a38
--- /dev/null
+++ b/sdks/python/types/__init__.py
@@ -0,0 +1,1209 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
+import typing
+from importlib import import_module
+
+if typing.TYPE_CHECKING:
+ from .action_rails import ActionRails
+ from .activated_rail import ActivatedRail
+ from .adapter import Adapter
+ from .adapter_entity_filter import AdapterEntityFilter
+ from .adapter_entity_filter_description import AdapterEntityFilterDescription
+ from .adapter_entity_filter_model import AdapterEntityFilterModel
+ from .adapter_entity_filter_name import AdapterEntityFilterName
+ from .adapters_page import AdaptersPage
+ from .ai_defense_rail_config import AiDefenseRailConfig
+ from .annotation import Annotation, Annotation_Feedback, Annotation_Label, Annotation_Metadata, Annotation_Note
+ from .annotation_filter import AnnotationFilter
+ from .annotation_input import (
+ AnnotationInput,
+ AnnotationInput_Feedback,
+ AnnotationInput_Label,
+ AnnotationInput_Metadata,
+ AnnotationInput_Note,
+ )
+ from .annotation_kind import AnnotationKind
+ from .annotation_sort_field import AnnotationSortField
+ from .annotations_page import AnnotationsPage
+ from .api_endpoint_data import ApiEndpointData
+ from .atif_agent import AtifAgent
+ from .atif_content_part import AtifContentPart, AtifContentPart_Image, AtifContentPart_Text
+ from .atif_content_part_image import AtifContentPartImage
+ from .atif_content_part_text import AtifContentPartText
+ from .atif_final_metrics import AtifFinalMetrics
+ from .atif_image_source import AtifImageSource
+ from .atif_image_source_media_type import AtifImageSourceMediaType
+ from .atif_metrics import AtifMetrics
+ from .atif_observation import AtifObservation
+ from .atif_observation_result import AtifObservationResult
+ from .atif_observation_result_content import AtifObservationResultContent
+ from .atif_step import AtifStep, AtifStep_Agent, AtifStep_System, AtifStep_User
+ from .atif_step_agent import AtifStepAgent
+ from .atif_step_agent_message import AtifStepAgentMessage
+ from .atif_step_agent_reasoning_effort import AtifStepAgentReasoningEffort
+ from .atif_step_system import AtifStepSystem
+ from .atif_step_system_message import AtifStepSystemMessage
+ from .atif_step_user import AtifStepUser
+ from .atif_step_user_message import AtifStepUserMessage
+ from .atif_subagent_trajectory_ref import AtifSubagentTrajectoryRef
+ from .atif_tool_call import AtifToolCall
+ from .auth_context import AuthContext
+ from .auth_discovery_response import AuthDiscoveryResponse
+ from .auto_align_options import AutoAlignOptions
+ from .auto_align_rail_config import AutoAlignRailConfig
+ from .backend_format import BackendFormat
+ from .base_model_filter import BaseModelFilter
+ from .base_model_filter_name import BaseModelFilterName
+ from .cache_stats_config import CacheStatsConfig
+ from .cache_status import CacheStatus
+ from .captured_chat_completions_request import CapturedChatCompletionsRequest
+ from .captured_chat_completions_response import CapturedChatCompletionsResponse
+ from .captured_chat_message import CapturedChatMessage
+ from .chat_completion_assistant_message_param import ChatCompletionAssistantMessageParam
+ from .chat_completion_content_part_image_param import ChatCompletionContentPartImageParam
+ from .chat_completion_content_part_text_param import ChatCompletionContentPartTextParam
+ from .chat_completion_function_message_param import ChatCompletionFunctionMessageParam
+ from .chat_completion_message_tool_call_param import ChatCompletionMessageToolCallParam
+ from .chat_completion_message_tool_call_param_type import ChatCompletionMessageToolCallParamType
+ from .chat_completion_system_message_param import ChatCompletionSystemMessageParam
+ from .chat_completion_tool_message_param import ChatCompletionToolMessageParam
+ from .chat_completion_user_message_param import ChatCompletionUserMessageParam
+ from .chat_completion_user_message_param_content import ChatCompletionUserMessageParamContent
+ from .chat_completion_user_message_param_content_one_item import (
+ ChatCompletionUserMessageParamContentOneItem,
+ ChatCompletionUserMessageParamContentOneItem_ImageUrl,
+ ChatCompletionUserMessageParamContentOneItem_Text,
+ )
+ from .chat_completions_ingest_response import ChatCompletionsIngestResponse
+ from .chat_message_role import ChatMessageRole
+ from .clavata_rail_config import ClavataRailConfig
+ from .clavata_rail_config_label_match_logic import ClavataRailConfigLabelMatchLogic
+ from .clavata_rail_options import ClavataRailOptions
+ from .compute_resource_spec import ComputeResourceSpec
+ from .compute_resources import ComputeResources
+ from .container_executor_config import ContainerExecutorConfig
+ from .container_spec import ContainerSpec
+ from .content_safety_config import ContentSafetyConfig
+ from .cpu_execution_provider_input import CpuExecutionProviderInput
+ from .cpu_execution_provider_output import CpuExecutionProviderOutput
+ from .crowd_strike_aidr_rail_config import CrowdStrikeAidrRailConfig
+ from .dataset_metadata_content import DatasetMetadataContent
+ from .dataset_metadata_content_schema import DatasetMetadataContentSchema
+ from .dataset_metadata_content_schemas_by_path_value import DatasetMetadataContentSchemasByPathValue
+ from .date_range_filter import DateRangeFilter
+ from .datetime_filter import DatetimeFilter
+ from .delete_response import DeleteResponse
+ from .dialog_rails import DialogRails
+ from .distributed_gpu_execution_provider_input import DistributedGpuExecutionProviderInput
+ from .distributed_gpu_execution_provider_output import DistributedGpuExecutionProviderOutput
+ from .docker_job_execution_profile import DockerJobExecutionProfile
+ from .docker_job_execution_profile_config import DockerJobExecutionProfileConfig
+ from .docker_job_network_config import DockerJobNetworkConfig
+ from .docker_job_storage_config import DockerJobStorageConfig
+ from .docker_volume_mount import DockerVolumeMount
+ from .docker_volume_mount_kind import DockerVolumeMountKind
+ from .e2e_job_execution_profile import E2EJobExecutionProfile
+ from .engine import Engine
+ from .entities_page import EntitiesPage
+ from .entity import Entity
+ from .evaluation_context import EvaluationContext
+ from .evaluator_aggregate import EvaluatorAggregate
+ from .evaluator_result import EvaluatorResult
+ from .evaluator_result_data_type import EvaluatorResultDataType
+ from .evaluator_result_filter import EvaluatorResultFilter
+ from .evaluator_result_sort_field import EvaluatorResultSortField
+ from .evaluator_results_page import EvaluatorResultsPage
+ from .executed_action import ExecutedAction
+ from .experiment_context import ExperimentContext
+ from .experiment_filter import ExperimentFilter
+ from .experiment_group_filter import ExperimentGroupFilter
+ from .experiment_group_request import ExperimentGroupRequest
+ from .experiment_group_response import ExperimentGroupResponse
+ from .experiment_group_responses_page import ExperimentGroupResponsesPage
+ from .experiment_request import ExperimentRequest
+ from .experiment_response import ExperimentResponse
+ from .experiment_responses_page import ExperimentResponsesPage
+ from .experiment_session_filter import ExperimentSessionFilter
+ from .experiment_session_response import ExperimentSessionResponse
+ from .experiment_session_responses_page import ExperimentSessionResponsesPage
+ from .fact_checking_rail_config import FactCheckingRailConfig
+ from .feedback_annotation import FeedbackAnnotation
+ from .feedback_annotation_input import FeedbackAnnotationInput
+ from .feedback_annotation_input_value import FeedbackAnnotationInputValue
+ from .feedback_annotation_value import FeedbackAnnotationValue
+ from .fiddler_guardrails import FiddlerGuardrails
+ from .file_storage_type import FileStorageType
+ from .fileset_file_output import FilesetFileOutput
+ from .fileset_filter import FilesetFilter
+ from .fileset_filter_description import FilesetFilterDescription
+ from .fileset_filter_name import FilesetFilterName
+ from .fileset_metadata_input import FilesetMetadataInput
+ from .fileset_metadata_output import FilesetMetadataOutput
+ from .fileset_output import FilesetOutput
+ from .fileset_output_storage import (
+ FilesetOutputStorage,
+ FilesetOutputStorage_Huggingface,
+ FilesetOutputStorage_Local,
+ FilesetOutputStorage_Ngc,
+ FilesetOutputStorage_S3,
+ )
+ from .fileset_outputs_page import FilesetOutputsPage
+ from .fileset_purpose import FilesetPurpose
+ from .finetuning_type import FinetuningType
+ from .finetuning_type_filter import FinetuningTypeFilter
+ from .float_filter import FloatFilter
+ from .function import Function
+ from .function_call import FunctionCall
+ from .g_li_ner_detection import GLiNerDetection
+ from .g_li_ner_detection_options import GLiNerDetectionOptions
+ from .generation_log import GenerationLog
+ from .generation_log_options import GenerationLogOptions
+ from .generation_options import GenerationOptions
+ from .generation_options_output_vars import GenerationOptionsOutputVars
+ from .generation_rails_options import GenerationRailsOptions
+ from .generation_rails_options_input import GenerationRailsOptionsInput
+ from .generation_rails_options_output import GenerationRailsOptionsOutput
+ from .generation_rails_options_retrieval import GenerationRailsOptionsRetrieval
+ from .generation_stats import GenerationStats
+ from .generic_sort_field import GenericSortField
+ from .gpu_execution_provider_input import GpuExecutionProviderInput
+ from .gpu_execution_provider_output import GpuExecutionProviderOutput
+ from .guardrail_check_response import GuardrailCheckResponse
+ from .guardrail_config import GuardrailConfig
+ from .guardrail_config_data import GuardrailConfigData
+ from .guardrail_config_filter import GuardrailConfigFilter
+ from .guardrail_config_filter_description import GuardrailConfigFilterDescription
+ from .guardrail_config_filter_name import GuardrailConfigFilterName
+ from .guardrail_configs_page import GuardrailConfigsPage
+ from .guardrails_ai_rail_config import GuardrailsAiRailConfig
+ from .guardrails_ai_validator_config import GuardrailsAiValidatorConfig
+ from .guardrails_data_input import GuardrailsDataInput
+ from .guardrails_data_input_config import GuardrailsDataInputConfig
+ from .guardrails_data_output import GuardrailsDataOutput
+ from .http_validation_error import HttpValidationError
+ from .huggingface_storage_config import HuggingfaceStorageConfig
+ from .huggingface_storage_config_repo_type import HuggingfaceStorageConfigRepoType
+ from .image_pull_secret import ImagePullSecret
+ from .image_url import ImageUrl
+ from .image_url_detail import ImageUrlDetail
+ from .inference_params import InferenceParams
+ from .ingest_response import IngestResponse
+ from .injection_detection import InjectionDetection
+ from .input_rails import InputRails
+ from .instruction import Instruction
+ from .jailbreak_detection_config import JailbreakDetectionConfig
+ from .job_execution_profile_config import JobExecutionProfileConfig
+ from .k8s_nim_operator_config import K8SNimOperatorConfig
+ from .kubernetes_empty_dir_volume import KubernetesEmptyDirVolume
+ from .kubernetes_job_execution_profile import KubernetesJobExecutionProfile
+ from .kubernetes_job_execution_profile_config import KubernetesJobExecutionProfileConfig
+ from .kubernetes_job_storage_config import KubernetesJobStorageConfig
+ from .kubernetes_object_metadata import KubernetesObjectMetadata
+ from .kubernetes_persistent_volume_claim import KubernetesPersistentVolumeClaim
+ from .kubernetes_volume import KubernetesVolume
+ from .kubernetes_volume_mount import KubernetesVolumeMount
+ from .label_annotation import LabelAnnotation
+ from .label_annotation_input import LabelAnnotationInput
+ from .label_annotation_input_value import LabelAnnotationInputValue
+ from .label_annotation_input_value_type import LabelAnnotationInputValueType
+ from .label_annotation_value import LabelAnnotationValue
+ from .label_annotation_value_type import LabelAnnotationValueType
+ from .linear_layer_spec import LinearLayerSpec
+ from .list_fileset_files_response import ListFilesetFilesResponse
+ from .llm_call_info import LlmCallInfo
+ from .local_storage_config import LocalStorageConfig
+ from .log_adapter_config import LogAdapterConfig
+ from .lora import Lora
+ from .mamba_config import MambaConfig
+ from .message_template import MessageTemplate
+ from .metadata_annotation import MetadataAnnotation
+ from .metadata_annotation_input import MetadataAnnotationInput
+ from .middleware_call import MiddlewareCall
+ from .mo_e_config import MoEConfig
+ from .model import Model
+ from .model_cache_config import ModelCacheConfig
+ from .model_deployment import ModelDeployment
+ from .model_deployment_config import ModelDeploymentConfig
+ from .model_deployment_config_filter import ModelDeploymentConfigFilter
+ from .model_deployment_config_filter_description import ModelDeploymentConfigFilterDescription
+ from .model_deployment_config_filter_name import ModelDeploymentConfigFilterName
+ from .model_deployment_config_model_spec import ModelDeploymentConfigModelSpec
+ from .model_deployment_configs_page import ModelDeploymentConfigsPage
+ from .model_deployment_filter import ModelDeploymentFilter
+ from .model_deployment_filter_config import ModelDeploymentFilterConfig
+ from .model_deployment_filter_name import ModelDeploymentFilterName
+ from .model_deployment_filter_status_message import ModelDeploymentFilterStatusMessage
+ from .model_deployment_status import ModelDeploymentStatus
+ from .model_deployment_status_history_item import ModelDeploymentStatusHistoryItem
+ from .model_deployments_page import ModelDeploymentsPage
+ from .model_entity import ModelEntity
+ from .model_entity_filter import ModelEntityFilter
+ from .model_entity_filter_adapters import ModelEntityFilterAdapters
+ from .model_entity_filter_base_model import ModelEntityFilterBaseModel
+ from .model_entity_filter_description import ModelEntityFilterDescription
+ from .model_entity_filter_finetuning_type import ModelEntityFilterFinetuningType
+ from .model_entity_filter_name import ModelEntityFilterName
+ from .model_entity_sort_field import ModelEntitySortField
+ from .model_entitys_page import ModelEntitysPage
+ from .model_metadata_content import ModelMetadataContent
+ from .model_mode import ModelMode
+ from .model_parameters import ModelParameters
+ from .model_provider import ModelProvider
+ from .model_provider_filter import ModelProviderFilter
+ from .model_provider_filter_description import ModelProviderFilterDescription
+ from .model_provider_filter_host_url import ModelProviderFilterHostUrl
+ from .model_provider_filter_name import ModelProviderFilterName
+ from .model_provider_sort import ModelProviderSort
+ from .model_provider_status import ModelProviderStatus
+ from .model_providers_page import ModelProvidersPage
+ from .model_spec import ModelSpec
+ from .model_type import ModelType
+ from .multilingual_config import MultilingualConfig
+ from .ngc_storage_config import NgcStorageConfig
+ from .ngc_storage_config_target_type import NgcStorageConfigTargetType
+ from .note_annotation import NoteAnnotation
+ from .note_annotation_input import NoteAnnotationInput
+ from .numeric_filter import NumericFilter
+ from .oidc_discovery_response import OidcDiscoveryResponse
+ from .open_ai_list_models_resp import OpenAiListModelsResp
+ from .open_ai_model_resp import OpenAiModelResp
+ from .otel_export_logs_partial_success import OtelExportLogsPartialSuccess
+ from .otel_export_logs_service_response import OtelExportLogsServiceResponse
+ from .output_rails import OutputRails
+ from .output_rails_streaming_config import OutputRailsStreamingConfig
+ from .pagination_data import PaginationData
+ from .pangea_rail_config import PangeaRailConfig
+ from .pangea_rail_options import PangeaRailOptions
+ from .patronus_evaluate_api_params import PatronusEvaluateApiParams
+ from .patronus_evaluate_config_input import PatronusEvaluateConfigInput
+ from .patronus_evaluate_config_output import PatronusEvaluateConfigOutput
+ from .patronus_evaluation_success_strategy import PatronusEvaluationSuccessStrategy
+ from .patronus_rail_config_input import PatronusRailConfigInput
+ from .patronus_rail_config_output import PatronusRailConfigOutput
+ from .platform_job_environment_variable import PlatformJobEnvironmentVariable
+ from .platform_job_list_result_response import PlatformJobListResultResponse
+ from .platform_job_list_task_response import PlatformJobListTaskResponse
+ from .platform_job_log import PlatformJobLog
+ from .platform_job_log_page import PlatformJobLogPage
+ from .platform_job_response import PlatformJobResponse
+ from .platform_job_responses_page import PlatformJobResponsesPage
+ from .platform_job_result_response import PlatformJobResultResponse
+ from .platform_job_secret_environment_variable_ref import PlatformJobSecretEnvironmentVariableRef
+ from .platform_job_sort_field import PlatformJobSortField
+ from .platform_job_spec_input import PlatformJobSpecInput
+ from .platform_job_spec_output import PlatformJobSpecOutput
+ from .platform_job_status import PlatformJobStatus
+ from .platform_job_status_response import PlatformJobStatusResponse
+ from .platform_job_step import PlatformJobStep
+ from .platform_job_step_spec_input import PlatformJobStepSpecInput
+ from .platform_job_step_spec_input_executor import (
+ PlatformJobStepSpecInputExecutor,
+ PlatformJobStepSpecInputExecutor_Cpu,
+ PlatformJobStepSpecInputExecutor_Gpu,
+ PlatformJobStepSpecInputExecutor_GpuDistributed,
+ PlatformJobStepSpecInputExecutor_Subprocess,
+ )
+ from .platform_job_step_spec_output import PlatformJobStepSpecOutput
+ from .platform_job_step_spec_output_executor import (
+ PlatformJobStepSpecOutputExecutor,
+ PlatformJobStepSpecOutputExecutor_Cpu,
+ PlatformJobStepSpecOutputExecutor_Gpu,
+ PlatformJobStepSpecOutputExecutor_GpuDistributed,
+ PlatformJobStepSpecOutputExecutor_Subprocess,
+ )
+ from .platform_job_step_status_response import PlatformJobStepStatusResponse
+ from .platform_job_step_with_context import PlatformJobStepWithContext
+ from .platform_job_step_with_contexts_page import PlatformJobStepWithContextsPage
+ from .platform_job_steps_list_filter import PlatformJobStepsListFilter
+ from .platform_job_task import PlatformJobTask
+ from .platform_job_task_status_response import PlatformJobTaskStatusResponse
+ from .platform_jobs_list_filter import PlatformJobsListFilter
+ from .platform_jobs_list_filter_name import PlatformJobsListFilterName
+ from .platform_jobs_list_filter_source import PlatformJobsListFilterSource
+ from .platform_jobs_list_filter_status import PlatformJobsListFilterStatus
+ from .platform_secret_access_response import PlatformSecretAccessResponse
+ from .platform_secret_admin_rotation_response import PlatformSecretAdminRotationResponse
+ from .platform_secret_response import PlatformSecretResponse
+ from .platform_secret_responses_page import PlatformSecretResponsesPage
+ from .private_ai_detection import PrivateAiDetection
+ from .private_ai_detection_options import PrivateAiDetectionOptions
+ from .project import Project
+ from .project_sort_field import ProjectSortField
+ from .projects_page import ProjectsPage
+ from .prompt_data import PromptData
+ from .rail_status import RailStatus
+ from .rails_config_data_input import RailsConfigDataInput
+ from .rails_config_data_output import RailsConfigDataOutput
+ from .rails_config_input import RailsConfigInput
+ from .rails_config_output import RailsConfigOutput
+ from .rails_input import RailsInput
+ from .rails_output import RailsOutput
+ from .reasoning_config import ReasoningConfig
+ from .regex_detection import RegexDetection
+ from .regex_detection_options import RegexDetectionOptions
+ from .retrieval_rails import RetrievalRails
+ from .role_binding import RoleBinding
+ from .role_binding_filter import RoleBindingFilter
+ from .role_binding_filter_granted_by import RoleBindingFilterGrantedBy
+ from .role_binding_filter_principal import RoleBindingFilterPrincipal
+ from .role_binding_filter_role import RoleBindingFilterRole
+ from .role_bindings_page import RoleBindingsPage
+ from .s3storage_config import S3StorageConfig
+ from .s3storage_config_signature_version import S3StorageConfigSignatureVersion
+ from .secret_ref import SecretRef
+ from .sensitive_data_detection import SensitiveDataDetection
+ from .sensitive_data_detection_options import SensitiveDataDetectionOptions
+ from .served_model_mapping import ServedModelMapping
+ from .single_call_config import SingleCallConfig
+ from .sliding_window_config import SlidingWindowConfig
+ from .span import Span
+ from .span_evaluation_context import SpanEvaluationContext
+ from .span_filter import SpanFilter
+ from .span_kind import SpanKind
+ from .span_sort_field import SpanSortField
+ from .span_status import SpanStatus
+ from .spans_page import SpansPage
+ from .status_enum import StatusEnum
+ from .step_lifecycle import StepLifecycle
+ from .storage_config_type import StorageConfigType
+ from .string_filter import StringFilter
+ from .subprocess_execution_provider import SubprocessExecutionProvider
+ from .subprocess_job_execution_profile import SubprocessJobExecutionProfile
+ from .subprocess_job_execution_profile_config import SubprocessJobExecutionProfileConfig
+ from .subprocess_job_execution_profile_provider import SubprocessJobExecutionProfileProvider
+ from .task_prompt import TaskPrompt
+ from .task_prompt_messages_item import TaskPromptMessagesItem
+ from .tool_call_config import ToolCallConfig
+ from .tool_calling_metadata_content import ToolCallingMetadataContent
+ from .tool_input_rails import ToolInputRails
+ from .tool_output_rails import ToolOutputRails
+ from .trace import Trace
+ from .trace_filter import TraceFilter
+ from .trace_sort_field import TraceSortField
+ from .traces_page import TracesPage
+ from .tracing_config import TracingConfig
+ from .trend_micro_rail_config import TrendMicroRailConfig
+ from .update_adapter_request import UpdateAdapterRequest
+ from .user_messages_config import UserMessagesConfig
+ from .validation_error import ValidationError
+ from .validation_error_loc_item import ValidationErrorLocItem
+ from .virtual_model import VirtualModel
+ from .virtual_model_inference_config import VirtualModelInferenceConfig
+ from .virtual_models_page import VirtualModelsPage
+ from .volcano_job_execution_profile import VolcanoJobExecutionProfile
+ from .volcano_job_execution_profile_config import VolcanoJobExecutionProfileConfig
+ from .workspace import Workspace
+ from .workspace_member import WorkspaceMember
+ from .workspace_member_list_response import WorkspaceMemberListResponse
+ from .workspaces_page import WorkspacesPage
+_dynamic_imports: typing.Dict[str, str] = {
+ "ActionRails": ".action_rails",
+ "ActivatedRail": ".activated_rail",
+ "Adapter": ".adapter",
+ "AdapterEntityFilter": ".adapter_entity_filter",
+ "AdapterEntityFilterDescription": ".adapter_entity_filter_description",
+ "AdapterEntityFilterModel": ".adapter_entity_filter_model",
+ "AdapterEntityFilterName": ".adapter_entity_filter_name",
+ "AdaptersPage": ".adapters_page",
+ "AiDefenseRailConfig": ".ai_defense_rail_config",
+ "Annotation": ".annotation",
+ "AnnotationFilter": ".annotation_filter",
+ "AnnotationInput": ".annotation_input",
+ "AnnotationInput_Feedback": ".annotation_input",
+ "AnnotationInput_Label": ".annotation_input",
+ "AnnotationInput_Metadata": ".annotation_input",
+ "AnnotationInput_Note": ".annotation_input",
+ "AnnotationKind": ".annotation_kind",
+ "AnnotationSortField": ".annotation_sort_field",
+ "Annotation_Feedback": ".annotation",
+ "Annotation_Label": ".annotation",
+ "Annotation_Metadata": ".annotation",
+ "Annotation_Note": ".annotation",
+ "AnnotationsPage": ".annotations_page",
+ "ApiEndpointData": ".api_endpoint_data",
+ "AtifAgent": ".atif_agent",
+ "AtifContentPart": ".atif_content_part",
+ "AtifContentPartImage": ".atif_content_part_image",
+ "AtifContentPartText": ".atif_content_part_text",
+ "AtifContentPart_Image": ".atif_content_part",
+ "AtifContentPart_Text": ".atif_content_part",
+ "AtifFinalMetrics": ".atif_final_metrics",
+ "AtifImageSource": ".atif_image_source",
+ "AtifImageSourceMediaType": ".atif_image_source_media_type",
+ "AtifMetrics": ".atif_metrics",
+ "AtifObservation": ".atif_observation",
+ "AtifObservationResult": ".atif_observation_result",
+ "AtifObservationResultContent": ".atif_observation_result_content",
+ "AtifStep": ".atif_step",
+ "AtifStepAgent": ".atif_step_agent",
+ "AtifStepAgentMessage": ".atif_step_agent_message",
+ "AtifStepAgentReasoningEffort": ".atif_step_agent_reasoning_effort",
+ "AtifStepSystem": ".atif_step_system",
+ "AtifStepSystemMessage": ".atif_step_system_message",
+ "AtifStepUser": ".atif_step_user",
+ "AtifStepUserMessage": ".atif_step_user_message",
+ "AtifStep_Agent": ".atif_step",
+ "AtifStep_System": ".atif_step",
+ "AtifStep_User": ".atif_step",
+ "AtifSubagentTrajectoryRef": ".atif_subagent_trajectory_ref",
+ "AtifToolCall": ".atif_tool_call",
+ "AuthContext": ".auth_context",
+ "AuthDiscoveryResponse": ".auth_discovery_response",
+ "AutoAlignOptions": ".auto_align_options",
+ "AutoAlignRailConfig": ".auto_align_rail_config",
+ "BackendFormat": ".backend_format",
+ "BaseModelFilter": ".base_model_filter",
+ "BaseModelFilterName": ".base_model_filter_name",
+ "CacheStatsConfig": ".cache_stats_config",
+ "CacheStatus": ".cache_status",
+ "CapturedChatCompletionsRequest": ".captured_chat_completions_request",
+ "CapturedChatCompletionsResponse": ".captured_chat_completions_response",
+ "CapturedChatMessage": ".captured_chat_message",
+ "ChatCompletionAssistantMessageParam": ".chat_completion_assistant_message_param",
+ "ChatCompletionContentPartImageParam": ".chat_completion_content_part_image_param",
+ "ChatCompletionContentPartTextParam": ".chat_completion_content_part_text_param",
+ "ChatCompletionFunctionMessageParam": ".chat_completion_function_message_param",
+ "ChatCompletionMessageToolCallParam": ".chat_completion_message_tool_call_param",
+ "ChatCompletionMessageToolCallParamType": ".chat_completion_message_tool_call_param_type",
+ "ChatCompletionSystemMessageParam": ".chat_completion_system_message_param",
+ "ChatCompletionToolMessageParam": ".chat_completion_tool_message_param",
+ "ChatCompletionUserMessageParam": ".chat_completion_user_message_param",
+ "ChatCompletionUserMessageParamContent": ".chat_completion_user_message_param_content",
+ "ChatCompletionUserMessageParamContentOneItem": ".chat_completion_user_message_param_content_one_item",
+ "ChatCompletionUserMessageParamContentOneItem_ImageUrl": ".chat_completion_user_message_param_content_one_item",
+ "ChatCompletionUserMessageParamContentOneItem_Text": ".chat_completion_user_message_param_content_one_item",
+ "ChatCompletionsIngestResponse": ".chat_completions_ingest_response",
+ "ChatMessageRole": ".chat_message_role",
+ "ClavataRailConfig": ".clavata_rail_config",
+ "ClavataRailConfigLabelMatchLogic": ".clavata_rail_config_label_match_logic",
+ "ClavataRailOptions": ".clavata_rail_options",
+ "ComputeResourceSpec": ".compute_resource_spec",
+ "ComputeResources": ".compute_resources",
+ "ContainerExecutorConfig": ".container_executor_config",
+ "ContainerSpec": ".container_spec",
+ "ContentSafetyConfig": ".content_safety_config",
+ "CpuExecutionProviderInput": ".cpu_execution_provider_input",
+ "CpuExecutionProviderOutput": ".cpu_execution_provider_output",
+ "CrowdStrikeAidrRailConfig": ".crowd_strike_aidr_rail_config",
+ "DatasetMetadataContent": ".dataset_metadata_content",
+ "DatasetMetadataContentSchema": ".dataset_metadata_content_schema",
+ "DatasetMetadataContentSchemasByPathValue": ".dataset_metadata_content_schemas_by_path_value",
+ "DateRangeFilter": ".date_range_filter",
+ "DatetimeFilter": ".datetime_filter",
+ "DeleteResponse": ".delete_response",
+ "DialogRails": ".dialog_rails",
+ "DistributedGpuExecutionProviderInput": ".distributed_gpu_execution_provider_input",
+ "DistributedGpuExecutionProviderOutput": ".distributed_gpu_execution_provider_output",
+ "DockerJobExecutionProfile": ".docker_job_execution_profile",
+ "DockerJobExecutionProfileConfig": ".docker_job_execution_profile_config",
+ "DockerJobNetworkConfig": ".docker_job_network_config",
+ "DockerJobStorageConfig": ".docker_job_storage_config",
+ "DockerVolumeMount": ".docker_volume_mount",
+ "DockerVolumeMountKind": ".docker_volume_mount_kind",
+ "E2EJobExecutionProfile": ".e2e_job_execution_profile",
+ "Engine": ".engine",
+ "EntitiesPage": ".entities_page",
+ "Entity": ".entity",
+ "EvaluationContext": ".evaluation_context",
+ "EvaluatorAggregate": ".evaluator_aggregate",
+ "EvaluatorResult": ".evaluator_result",
+ "EvaluatorResultDataType": ".evaluator_result_data_type",
+ "EvaluatorResultFilter": ".evaluator_result_filter",
+ "EvaluatorResultSortField": ".evaluator_result_sort_field",
+ "EvaluatorResultsPage": ".evaluator_results_page",
+ "ExecutedAction": ".executed_action",
+ "ExperimentContext": ".experiment_context",
+ "ExperimentFilter": ".experiment_filter",
+ "ExperimentGroupFilter": ".experiment_group_filter",
+ "ExperimentGroupRequest": ".experiment_group_request",
+ "ExperimentGroupResponse": ".experiment_group_response",
+ "ExperimentGroupResponsesPage": ".experiment_group_responses_page",
+ "ExperimentRequest": ".experiment_request",
+ "ExperimentResponse": ".experiment_response",
+ "ExperimentResponsesPage": ".experiment_responses_page",
+ "ExperimentSessionFilter": ".experiment_session_filter",
+ "ExperimentSessionResponse": ".experiment_session_response",
+ "ExperimentSessionResponsesPage": ".experiment_session_responses_page",
+ "FactCheckingRailConfig": ".fact_checking_rail_config",
+ "FeedbackAnnotation": ".feedback_annotation",
+ "FeedbackAnnotationInput": ".feedback_annotation_input",
+ "FeedbackAnnotationInputValue": ".feedback_annotation_input_value",
+ "FeedbackAnnotationValue": ".feedback_annotation_value",
+ "FiddlerGuardrails": ".fiddler_guardrails",
+ "FileStorageType": ".file_storage_type",
+ "FilesetFileOutput": ".fileset_file_output",
+ "FilesetFilter": ".fileset_filter",
+ "FilesetFilterDescription": ".fileset_filter_description",
+ "FilesetFilterName": ".fileset_filter_name",
+ "FilesetMetadataInput": ".fileset_metadata_input",
+ "FilesetMetadataOutput": ".fileset_metadata_output",
+ "FilesetOutput": ".fileset_output",
+ "FilesetOutputStorage": ".fileset_output_storage",
+ "FilesetOutputStorage_Huggingface": ".fileset_output_storage",
+ "FilesetOutputStorage_Local": ".fileset_output_storage",
+ "FilesetOutputStorage_Ngc": ".fileset_output_storage",
+ "FilesetOutputStorage_S3": ".fileset_output_storage",
+ "FilesetOutputsPage": ".fileset_outputs_page",
+ "FilesetPurpose": ".fileset_purpose",
+ "FinetuningType": ".finetuning_type",
+ "FinetuningTypeFilter": ".finetuning_type_filter",
+ "FloatFilter": ".float_filter",
+ "Function": ".function",
+ "FunctionCall": ".function_call",
+ "GLiNerDetection": ".g_li_ner_detection",
+ "GLiNerDetectionOptions": ".g_li_ner_detection_options",
+ "GenerationLog": ".generation_log",
+ "GenerationLogOptions": ".generation_log_options",
+ "GenerationOptions": ".generation_options",
+ "GenerationOptionsOutputVars": ".generation_options_output_vars",
+ "GenerationRailsOptions": ".generation_rails_options",
+ "GenerationRailsOptionsInput": ".generation_rails_options_input",
+ "GenerationRailsOptionsOutput": ".generation_rails_options_output",
+ "GenerationRailsOptionsRetrieval": ".generation_rails_options_retrieval",
+ "GenerationStats": ".generation_stats",
+ "GenericSortField": ".generic_sort_field",
+ "GpuExecutionProviderInput": ".gpu_execution_provider_input",
+ "GpuExecutionProviderOutput": ".gpu_execution_provider_output",
+ "GuardrailCheckResponse": ".guardrail_check_response",
+ "GuardrailConfig": ".guardrail_config",
+ "GuardrailConfigData": ".guardrail_config_data",
+ "GuardrailConfigFilter": ".guardrail_config_filter",
+ "GuardrailConfigFilterDescription": ".guardrail_config_filter_description",
+ "GuardrailConfigFilterName": ".guardrail_config_filter_name",
+ "GuardrailConfigsPage": ".guardrail_configs_page",
+ "GuardrailsAiRailConfig": ".guardrails_ai_rail_config",
+ "GuardrailsAiValidatorConfig": ".guardrails_ai_validator_config",
+ "GuardrailsDataInput": ".guardrails_data_input",
+ "GuardrailsDataInputConfig": ".guardrails_data_input_config",
+ "GuardrailsDataOutput": ".guardrails_data_output",
+ "HttpValidationError": ".http_validation_error",
+ "HuggingfaceStorageConfig": ".huggingface_storage_config",
+ "HuggingfaceStorageConfigRepoType": ".huggingface_storage_config_repo_type",
+ "ImagePullSecret": ".image_pull_secret",
+ "ImageUrl": ".image_url",
+ "ImageUrlDetail": ".image_url_detail",
+ "InferenceParams": ".inference_params",
+ "IngestResponse": ".ingest_response",
+ "InjectionDetection": ".injection_detection",
+ "InputRails": ".input_rails",
+ "Instruction": ".instruction",
+ "JailbreakDetectionConfig": ".jailbreak_detection_config",
+ "JobExecutionProfileConfig": ".job_execution_profile_config",
+ "K8SNimOperatorConfig": ".k8s_nim_operator_config",
+ "KubernetesEmptyDirVolume": ".kubernetes_empty_dir_volume",
+ "KubernetesJobExecutionProfile": ".kubernetes_job_execution_profile",
+ "KubernetesJobExecutionProfileConfig": ".kubernetes_job_execution_profile_config",
+ "KubernetesJobStorageConfig": ".kubernetes_job_storage_config",
+ "KubernetesObjectMetadata": ".kubernetes_object_metadata",
+ "KubernetesPersistentVolumeClaim": ".kubernetes_persistent_volume_claim",
+ "KubernetesVolume": ".kubernetes_volume",
+ "KubernetesVolumeMount": ".kubernetes_volume_mount",
+ "LabelAnnotation": ".label_annotation",
+ "LabelAnnotationInput": ".label_annotation_input",
+ "LabelAnnotationInputValue": ".label_annotation_input_value",
+ "LabelAnnotationInputValueType": ".label_annotation_input_value_type",
+ "LabelAnnotationValue": ".label_annotation_value",
+ "LabelAnnotationValueType": ".label_annotation_value_type",
+ "LinearLayerSpec": ".linear_layer_spec",
+ "ListFilesetFilesResponse": ".list_fileset_files_response",
+ "LlmCallInfo": ".llm_call_info",
+ "LocalStorageConfig": ".local_storage_config",
+ "LogAdapterConfig": ".log_adapter_config",
+ "Lora": ".lora",
+ "MambaConfig": ".mamba_config",
+ "MessageTemplate": ".message_template",
+ "MetadataAnnotation": ".metadata_annotation",
+ "MetadataAnnotationInput": ".metadata_annotation_input",
+ "MiddlewareCall": ".middleware_call",
+ "MoEConfig": ".mo_e_config",
+ "Model": ".model",
+ "ModelCacheConfig": ".model_cache_config",
+ "ModelDeployment": ".model_deployment",
+ "ModelDeploymentConfig": ".model_deployment_config",
+ "ModelDeploymentConfigFilter": ".model_deployment_config_filter",
+ "ModelDeploymentConfigFilterDescription": ".model_deployment_config_filter_description",
+ "ModelDeploymentConfigFilterName": ".model_deployment_config_filter_name",
+ "ModelDeploymentConfigModelSpec": ".model_deployment_config_model_spec",
+ "ModelDeploymentConfigsPage": ".model_deployment_configs_page",
+ "ModelDeploymentFilter": ".model_deployment_filter",
+ "ModelDeploymentFilterConfig": ".model_deployment_filter_config",
+ "ModelDeploymentFilterName": ".model_deployment_filter_name",
+ "ModelDeploymentFilterStatusMessage": ".model_deployment_filter_status_message",
+ "ModelDeploymentStatus": ".model_deployment_status",
+ "ModelDeploymentStatusHistoryItem": ".model_deployment_status_history_item",
+ "ModelDeploymentsPage": ".model_deployments_page",
+ "ModelEntity": ".model_entity",
+ "ModelEntityFilter": ".model_entity_filter",
+ "ModelEntityFilterAdapters": ".model_entity_filter_adapters",
+ "ModelEntityFilterBaseModel": ".model_entity_filter_base_model",
+ "ModelEntityFilterDescription": ".model_entity_filter_description",
+ "ModelEntityFilterFinetuningType": ".model_entity_filter_finetuning_type",
+ "ModelEntityFilterName": ".model_entity_filter_name",
+ "ModelEntitySortField": ".model_entity_sort_field",
+ "ModelEntitysPage": ".model_entitys_page",
+ "ModelMetadataContent": ".model_metadata_content",
+ "ModelMode": ".model_mode",
+ "ModelParameters": ".model_parameters",
+ "ModelProvider": ".model_provider",
+ "ModelProviderFilter": ".model_provider_filter",
+ "ModelProviderFilterDescription": ".model_provider_filter_description",
+ "ModelProviderFilterHostUrl": ".model_provider_filter_host_url",
+ "ModelProviderFilterName": ".model_provider_filter_name",
+ "ModelProviderSort": ".model_provider_sort",
+ "ModelProviderStatus": ".model_provider_status",
+ "ModelProvidersPage": ".model_providers_page",
+ "ModelSpec": ".model_spec",
+ "ModelType": ".model_type",
+ "MultilingualConfig": ".multilingual_config",
+ "NgcStorageConfig": ".ngc_storage_config",
+ "NgcStorageConfigTargetType": ".ngc_storage_config_target_type",
+ "NoteAnnotation": ".note_annotation",
+ "NoteAnnotationInput": ".note_annotation_input",
+ "NumericFilter": ".numeric_filter",
+ "OidcDiscoveryResponse": ".oidc_discovery_response",
+ "OpenAiListModelsResp": ".open_ai_list_models_resp",
+ "OpenAiModelResp": ".open_ai_model_resp",
+ "OtelExportLogsPartialSuccess": ".otel_export_logs_partial_success",
+ "OtelExportLogsServiceResponse": ".otel_export_logs_service_response",
+ "OutputRails": ".output_rails",
+ "OutputRailsStreamingConfig": ".output_rails_streaming_config",
+ "PaginationData": ".pagination_data",
+ "PangeaRailConfig": ".pangea_rail_config",
+ "PangeaRailOptions": ".pangea_rail_options",
+ "PatronusEvaluateApiParams": ".patronus_evaluate_api_params",
+ "PatronusEvaluateConfigInput": ".patronus_evaluate_config_input",
+ "PatronusEvaluateConfigOutput": ".patronus_evaluate_config_output",
+ "PatronusEvaluationSuccessStrategy": ".patronus_evaluation_success_strategy",
+ "PatronusRailConfigInput": ".patronus_rail_config_input",
+ "PatronusRailConfigOutput": ".patronus_rail_config_output",
+ "PlatformJobEnvironmentVariable": ".platform_job_environment_variable",
+ "PlatformJobListResultResponse": ".platform_job_list_result_response",
+ "PlatformJobListTaskResponse": ".platform_job_list_task_response",
+ "PlatformJobLog": ".platform_job_log",
+ "PlatformJobLogPage": ".platform_job_log_page",
+ "PlatformJobResponse": ".platform_job_response",
+ "PlatformJobResponsesPage": ".platform_job_responses_page",
+ "PlatformJobResultResponse": ".platform_job_result_response",
+ "PlatformJobSecretEnvironmentVariableRef": ".platform_job_secret_environment_variable_ref",
+ "PlatformJobSortField": ".platform_job_sort_field",
+ "PlatformJobSpecInput": ".platform_job_spec_input",
+ "PlatformJobSpecOutput": ".platform_job_spec_output",
+ "PlatformJobStatus": ".platform_job_status",
+ "PlatformJobStatusResponse": ".platform_job_status_response",
+ "PlatformJobStep": ".platform_job_step",
+ "PlatformJobStepSpecInput": ".platform_job_step_spec_input",
+ "PlatformJobStepSpecInputExecutor": ".platform_job_step_spec_input_executor",
+ "PlatformJobStepSpecInputExecutor_Cpu": ".platform_job_step_spec_input_executor",
+ "PlatformJobStepSpecInputExecutor_Gpu": ".platform_job_step_spec_input_executor",
+ "PlatformJobStepSpecInputExecutor_GpuDistributed": ".platform_job_step_spec_input_executor",
+ "PlatformJobStepSpecInputExecutor_Subprocess": ".platform_job_step_spec_input_executor",
+ "PlatformJobStepSpecOutput": ".platform_job_step_spec_output",
+ "PlatformJobStepSpecOutputExecutor": ".platform_job_step_spec_output_executor",
+ "PlatformJobStepSpecOutputExecutor_Cpu": ".platform_job_step_spec_output_executor",
+ "PlatformJobStepSpecOutputExecutor_Gpu": ".platform_job_step_spec_output_executor",
+ "PlatformJobStepSpecOutputExecutor_GpuDistributed": ".platform_job_step_spec_output_executor",
+ "PlatformJobStepSpecOutputExecutor_Subprocess": ".platform_job_step_spec_output_executor",
+ "PlatformJobStepStatusResponse": ".platform_job_step_status_response",
+ "PlatformJobStepWithContext": ".platform_job_step_with_context",
+ "PlatformJobStepWithContextsPage": ".platform_job_step_with_contexts_page",
+ "PlatformJobStepsListFilter": ".platform_job_steps_list_filter",
+ "PlatformJobTask": ".platform_job_task",
+ "PlatformJobTaskStatusResponse": ".platform_job_task_status_response",
+ "PlatformJobsListFilter": ".platform_jobs_list_filter",
+ "PlatformJobsListFilterName": ".platform_jobs_list_filter_name",
+ "PlatformJobsListFilterSource": ".platform_jobs_list_filter_source",
+ "PlatformJobsListFilterStatus": ".platform_jobs_list_filter_status",
+ "PlatformSecretAccessResponse": ".platform_secret_access_response",
+ "PlatformSecretAdminRotationResponse": ".platform_secret_admin_rotation_response",
+ "PlatformSecretResponse": ".platform_secret_response",
+ "PlatformSecretResponsesPage": ".platform_secret_responses_page",
+ "PrivateAiDetection": ".private_ai_detection",
+ "PrivateAiDetectionOptions": ".private_ai_detection_options",
+ "Project": ".project",
+ "ProjectSortField": ".project_sort_field",
+ "ProjectsPage": ".projects_page",
+ "PromptData": ".prompt_data",
+ "RailStatus": ".rail_status",
+ "RailsConfigDataInput": ".rails_config_data_input",
+ "RailsConfigDataOutput": ".rails_config_data_output",
+ "RailsConfigInput": ".rails_config_input",
+ "RailsConfigOutput": ".rails_config_output",
+ "RailsInput": ".rails_input",
+ "RailsOutput": ".rails_output",
+ "ReasoningConfig": ".reasoning_config",
+ "RegexDetection": ".regex_detection",
+ "RegexDetectionOptions": ".regex_detection_options",
+ "RetrievalRails": ".retrieval_rails",
+ "RoleBinding": ".role_binding",
+ "RoleBindingFilter": ".role_binding_filter",
+ "RoleBindingFilterGrantedBy": ".role_binding_filter_granted_by",
+ "RoleBindingFilterPrincipal": ".role_binding_filter_principal",
+ "RoleBindingFilterRole": ".role_binding_filter_role",
+ "RoleBindingsPage": ".role_bindings_page",
+ "S3StorageConfig": ".s3storage_config",
+ "S3StorageConfigSignatureVersion": ".s3storage_config_signature_version",
+ "SecretRef": ".secret_ref",
+ "SensitiveDataDetection": ".sensitive_data_detection",
+ "SensitiveDataDetectionOptions": ".sensitive_data_detection_options",
+ "ServedModelMapping": ".served_model_mapping",
+ "SingleCallConfig": ".single_call_config",
+ "SlidingWindowConfig": ".sliding_window_config",
+ "Span": ".span",
+ "SpanEvaluationContext": ".span_evaluation_context",
+ "SpanFilter": ".span_filter",
+ "SpanKind": ".span_kind",
+ "SpanSortField": ".span_sort_field",
+ "SpanStatus": ".span_status",
+ "SpansPage": ".spans_page",
+ "StatusEnum": ".status_enum",
+ "StepLifecycle": ".step_lifecycle",
+ "StorageConfigType": ".storage_config_type",
+ "StringFilter": ".string_filter",
+ "SubprocessExecutionProvider": ".subprocess_execution_provider",
+ "SubprocessJobExecutionProfile": ".subprocess_job_execution_profile",
+ "SubprocessJobExecutionProfileConfig": ".subprocess_job_execution_profile_config",
+ "SubprocessJobExecutionProfileProvider": ".subprocess_job_execution_profile_provider",
+ "TaskPrompt": ".task_prompt",
+ "TaskPromptMessagesItem": ".task_prompt_messages_item",
+ "ToolCallConfig": ".tool_call_config",
+ "ToolCallingMetadataContent": ".tool_calling_metadata_content",
+ "ToolInputRails": ".tool_input_rails",
+ "ToolOutputRails": ".tool_output_rails",
+ "Trace": ".trace",
+ "TraceFilter": ".trace_filter",
+ "TraceSortField": ".trace_sort_field",
+ "TracesPage": ".traces_page",
+ "TracingConfig": ".tracing_config",
+ "TrendMicroRailConfig": ".trend_micro_rail_config",
+ "UpdateAdapterRequest": ".update_adapter_request",
+ "UserMessagesConfig": ".user_messages_config",
+ "ValidationError": ".validation_error",
+ "ValidationErrorLocItem": ".validation_error_loc_item",
+ "VirtualModel": ".virtual_model",
+ "VirtualModelInferenceConfig": ".virtual_model_inference_config",
+ "VirtualModelsPage": ".virtual_models_page",
+ "VolcanoJobExecutionProfile": ".volcano_job_execution_profile",
+ "VolcanoJobExecutionProfileConfig": ".volcano_job_execution_profile_config",
+ "Workspace": ".workspace",
+ "WorkspaceMember": ".workspace_member",
+ "WorkspaceMemberListResponse": ".workspace_member_list_response",
+ "WorkspacesPage": ".workspaces_page",
+}
+
+
+def __getattr__(attr_name: str) -> typing.Any:
+ module_name = _dynamic_imports.get(attr_name)
+ if module_name is None:
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
+ try:
+ module = import_module(module_name, __package__)
+ if module_name == f".{attr_name}":
+ return module
+ else:
+ return getattr(module, attr_name)
+ except ImportError as e:
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
+ except AttributeError as e:
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
+
+
+def __dir__():
+ lazy_attrs = list(_dynamic_imports.keys())
+ return sorted(lazy_attrs)
+
+
+__all__ = [
+ "ActionRails",
+ "ActivatedRail",
+ "Adapter",
+ "AdapterEntityFilter",
+ "AdapterEntityFilterDescription",
+ "AdapterEntityFilterModel",
+ "AdapterEntityFilterName",
+ "AdaptersPage",
+ "AiDefenseRailConfig",
+ "Annotation",
+ "AnnotationFilter",
+ "AnnotationInput",
+ "AnnotationInput_Feedback",
+ "AnnotationInput_Label",
+ "AnnotationInput_Metadata",
+ "AnnotationInput_Note",
+ "AnnotationKind",
+ "AnnotationSortField",
+ "Annotation_Feedback",
+ "Annotation_Label",
+ "Annotation_Metadata",
+ "Annotation_Note",
+ "AnnotationsPage",
+ "ApiEndpointData",
+ "AtifAgent",
+ "AtifContentPart",
+ "AtifContentPartImage",
+ "AtifContentPartText",
+ "AtifContentPart_Image",
+ "AtifContentPart_Text",
+ "AtifFinalMetrics",
+ "AtifImageSource",
+ "AtifImageSourceMediaType",
+ "AtifMetrics",
+ "AtifObservation",
+ "AtifObservationResult",
+ "AtifObservationResultContent",
+ "AtifStep",
+ "AtifStepAgent",
+ "AtifStepAgentMessage",
+ "AtifStepAgentReasoningEffort",
+ "AtifStepSystem",
+ "AtifStepSystemMessage",
+ "AtifStepUser",
+ "AtifStepUserMessage",
+ "AtifStep_Agent",
+ "AtifStep_System",
+ "AtifStep_User",
+ "AtifSubagentTrajectoryRef",
+ "AtifToolCall",
+ "AuthContext",
+ "AuthDiscoveryResponse",
+ "AutoAlignOptions",
+ "AutoAlignRailConfig",
+ "BackendFormat",
+ "BaseModelFilter",
+ "BaseModelFilterName",
+ "CacheStatsConfig",
+ "CacheStatus",
+ "CapturedChatCompletionsRequest",
+ "CapturedChatCompletionsResponse",
+ "CapturedChatMessage",
+ "ChatCompletionAssistantMessageParam",
+ "ChatCompletionContentPartImageParam",
+ "ChatCompletionContentPartTextParam",
+ "ChatCompletionFunctionMessageParam",
+ "ChatCompletionMessageToolCallParam",
+ "ChatCompletionMessageToolCallParamType",
+ "ChatCompletionSystemMessageParam",
+ "ChatCompletionToolMessageParam",
+ "ChatCompletionUserMessageParam",
+ "ChatCompletionUserMessageParamContent",
+ "ChatCompletionUserMessageParamContentOneItem",
+ "ChatCompletionUserMessageParamContentOneItem_ImageUrl",
+ "ChatCompletionUserMessageParamContentOneItem_Text",
+ "ChatCompletionsIngestResponse",
+ "ChatMessageRole",
+ "ClavataRailConfig",
+ "ClavataRailConfigLabelMatchLogic",
+ "ClavataRailOptions",
+ "ComputeResourceSpec",
+ "ComputeResources",
+ "ContainerExecutorConfig",
+ "ContainerSpec",
+ "ContentSafetyConfig",
+ "CpuExecutionProviderInput",
+ "CpuExecutionProviderOutput",
+ "CrowdStrikeAidrRailConfig",
+ "DatasetMetadataContent",
+ "DatasetMetadataContentSchema",
+ "DatasetMetadataContentSchemasByPathValue",
+ "DateRangeFilter",
+ "DatetimeFilter",
+ "DeleteResponse",
+ "DialogRails",
+ "DistributedGpuExecutionProviderInput",
+ "DistributedGpuExecutionProviderOutput",
+ "DockerJobExecutionProfile",
+ "DockerJobExecutionProfileConfig",
+ "DockerJobNetworkConfig",
+ "DockerJobStorageConfig",
+ "DockerVolumeMount",
+ "DockerVolumeMountKind",
+ "E2EJobExecutionProfile",
+ "Engine",
+ "EntitiesPage",
+ "Entity",
+ "EvaluationContext",
+ "EvaluatorAggregate",
+ "EvaluatorResult",
+ "EvaluatorResultDataType",
+ "EvaluatorResultFilter",
+ "EvaluatorResultSortField",
+ "EvaluatorResultsPage",
+ "ExecutedAction",
+ "ExperimentContext",
+ "ExperimentFilter",
+ "ExperimentGroupFilter",
+ "ExperimentGroupRequest",
+ "ExperimentGroupResponse",
+ "ExperimentGroupResponsesPage",
+ "ExperimentRequest",
+ "ExperimentResponse",
+ "ExperimentResponsesPage",
+ "ExperimentSessionFilter",
+ "ExperimentSessionResponse",
+ "ExperimentSessionResponsesPage",
+ "FactCheckingRailConfig",
+ "FeedbackAnnotation",
+ "FeedbackAnnotationInput",
+ "FeedbackAnnotationInputValue",
+ "FeedbackAnnotationValue",
+ "FiddlerGuardrails",
+ "FileStorageType",
+ "FilesetFileOutput",
+ "FilesetFilter",
+ "FilesetFilterDescription",
+ "FilesetFilterName",
+ "FilesetMetadataInput",
+ "FilesetMetadataOutput",
+ "FilesetOutput",
+ "FilesetOutputStorage",
+ "FilesetOutputStorage_Huggingface",
+ "FilesetOutputStorage_Local",
+ "FilesetOutputStorage_Ngc",
+ "FilesetOutputStorage_S3",
+ "FilesetOutputsPage",
+ "FilesetPurpose",
+ "FinetuningType",
+ "FinetuningTypeFilter",
+ "FloatFilter",
+ "Function",
+ "FunctionCall",
+ "GLiNerDetection",
+ "GLiNerDetectionOptions",
+ "GenerationLog",
+ "GenerationLogOptions",
+ "GenerationOptions",
+ "GenerationOptionsOutputVars",
+ "GenerationRailsOptions",
+ "GenerationRailsOptionsInput",
+ "GenerationRailsOptionsOutput",
+ "GenerationRailsOptionsRetrieval",
+ "GenerationStats",
+ "GenericSortField",
+ "GpuExecutionProviderInput",
+ "GpuExecutionProviderOutput",
+ "GuardrailCheckResponse",
+ "GuardrailConfig",
+ "GuardrailConfigData",
+ "GuardrailConfigFilter",
+ "GuardrailConfigFilterDescription",
+ "GuardrailConfigFilterName",
+ "GuardrailConfigsPage",
+ "GuardrailsAiRailConfig",
+ "GuardrailsAiValidatorConfig",
+ "GuardrailsDataInput",
+ "GuardrailsDataInputConfig",
+ "GuardrailsDataOutput",
+ "HttpValidationError",
+ "HuggingfaceStorageConfig",
+ "HuggingfaceStorageConfigRepoType",
+ "ImagePullSecret",
+ "ImageUrl",
+ "ImageUrlDetail",
+ "InferenceParams",
+ "IngestResponse",
+ "InjectionDetection",
+ "InputRails",
+ "Instruction",
+ "JailbreakDetectionConfig",
+ "JobExecutionProfileConfig",
+ "K8SNimOperatorConfig",
+ "KubernetesEmptyDirVolume",
+ "KubernetesJobExecutionProfile",
+ "KubernetesJobExecutionProfileConfig",
+ "KubernetesJobStorageConfig",
+ "KubernetesObjectMetadata",
+ "KubernetesPersistentVolumeClaim",
+ "KubernetesVolume",
+ "KubernetesVolumeMount",
+ "LabelAnnotation",
+ "LabelAnnotationInput",
+ "LabelAnnotationInputValue",
+ "LabelAnnotationInputValueType",
+ "LabelAnnotationValue",
+ "LabelAnnotationValueType",
+ "LinearLayerSpec",
+ "ListFilesetFilesResponse",
+ "LlmCallInfo",
+ "LocalStorageConfig",
+ "LogAdapterConfig",
+ "Lora",
+ "MambaConfig",
+ "MessageTemplate",
+ "MetadataAnnotation",
+ "MetadataAnnotationInput",
+ "MiddlewareCall",
+ "MoEConfig",
+ "Model",
+ "ModelCacheConfig",
+ "ModelDeployment",
+ "ModelDeploymentConfig",
+ "ModelDeploymentConfigFilter",
+ "ModelDeploymentConfigFilterDescription",
+ "ModelDeploymentConfigFilterName",
+ "ModelDeploymentConfigModelSpec",
+ "ModelDeploymentConfigsPage",
+ "ModelDeploymentFilter",
+ "ModelDeploymentFilterConfig",
+ "ModelDeploymentFilterName",
+ "ModelDeploymentFilterStatusMessage",
+ "ModelDeploymentStatus",
+ "ModelDeploymentStatusHistoryItem",
+ "ModelDeploymentsPage",
+ "ModelEntity",
+ "ModelEntityFilter",
+ "ModelEntityFilterAdapters",
+ "ModelEntityFilterBaseModel",
+ "ModelEntityFilterDescription",
+ "ModelEntityFilterFinetuningType",
+ "ModelEntityFilterName",
+ "ModelEntitySortField",
+ "ModelEntitysPage",
+ "ModelMetadataContent",
+ "ModelMode",
+ "ModelParameters",
+ "ModelProvider",
+ "ModelProviderFilter",
+ "ModelProviderFilterDescription",
+ "ModelProviderFilterHostUrl",
+ "ModelProviderFilterName",
+ "ModelProviderSort",
+ "ModelProviderStatus",
+ "ModelProvidersPage",
+ "ModelSpec",
+ "ModelType",
+ "MultilingualConfig",
+ "NgcStorageConfig",
+ "NgcStorageConfigTargetType",
+ "NoteAnnotation",
+ "NoteAnnotationInput",
+ "NumericFilter",
+ "OidcDiscoveryResponse",
+ "OpenAiListModelsResp",
+ "OpenAiModelResp",
+ "OtelExportLogsPartialSuccess",
+ "OtelExportLogsServiceResponse",
+ "OutputRails",
+ "OutputRailsStreamingConfig",
+ "PaginationData",
+ "PangeaRailConfig",
+ "PangeaRailOptions",
+ "PatronusEvaluateApiParams",
+ "PatronusEvaluateConfigInput",
+ "PatronusEvaluateConfigOutput",
+ "PatronusEvaluationSuccessStrategy",
+ "PatronusRailConfigInput",
+ "PatronusRailConfigOutput",
+ "PlatformJobEnvironmentVariable",
+ "PlatformJobListResultResponse",
+ "PlatformJobListTaskResponse",
+ "PlatformJobLog",
+ "PlatformJobLogPage",
+ "PlatformJobResponse",
+ "PlatformJobResponsesPage",
+ "PlatformJobResultResponse",
+ "PlatformJobSecretEnvironmentVariableRef",
+ "PlatformJobSortField",
+ "PlatformJobSpecInput",
+ "PlatformJobSpecOutput",
+ "PlatformJobStatus",
+ "PlatformJobStatusResponse",
+ "PlatformJobStep",
+ "PlatformJobStepSpecInput",
+ "PlatformJobStepSpecInputExecutor",
+ "PlatformJobStepSpecInputExecutor_Cpu",
+ "PlatformJobStepSpecInputExecutor_Gpu",
+ "PlatformJobStepSpecInputExecutor_GpuDistributed",
+ "PlatformJobStepSpecInputExecutor_Subprocess",
+ "PlatformJobStepSpecOutput",
+ "PlatformJobStepSpecOutputExecutor",
+ "PlatformJobStepSpecOutputExecutor_Cpu",
+ "PlatformJobStepSpecOutputExecutor_Gpu",
+ "PlatformJobStepSpecOutputExecutor_GpuDistributed",
+ "PlatformJobStepSpecOutputExecutor_Subprocess",
+ "PlatformJobStepStatusResponse",
+ "PlatformJobStepWithContext",
+ "PlatformJobStepWithContextsPage",
+ "PlatformJobStepsListFilter",
+ "PlatformJobTask",
+ "PlatformJobTaskStatusResponse",
+ "PlatformJobsListFilter",
+ "PlatformJobsListFilterName",
+ "PlatformJobsListFilterSource",
+ "PlatformJobsListFilterStatus",
+ "PlatformSecretAccessResponse",
+ "PlatformSecretAdminRotationResponse",
+ "PlatformSecretResponse",
+ "PlatformSecretResponsesPage",
+ "PrivateAiDetection",
+ "PrivateAiDetectionOptions",
+ "Project",
+ "ProjectSortField",
+ "ProjectsPage",
+ "PromptData",
+ "RailStatus",
+ "RailsConfigDataInput",
+ "RailsConfigDataOutput",
+ "RailsConfigInput",
+ "RailsConfigOutput",
+ "RailsInput",
+ "RailsOutput",
+ "ReasoningConfig",
+ "RegexDetection",
+ "RegexDetectionOptions",
+ "RetrievalRails",
+ "RoleBinding",
+ "RoleBindingFilter",
+ "RoleBindingFilterGrantedBy",
+ "RoleBindingFilterPrincipal",
+ "RoleBindingFilterRole",
+ "RoleBindingsPage",
+ "S3StorageConfig",
+ "S3StorageConfigSignatureVersion",
+ "SecretRef",
+ "SensitiveDataDetection",
+ "SensitiveDataDetectionOptions",
+ "ServedModelMapping",
+ "SingleCallConfig",
+ "SlidingWindowConfig",
+ "Span",
+ "SpanEvaluationContext",
+ "SpanFilter",
+ "SpanKind",
+ "SpanSortField",
+ "SpanStatus",
+ "SpansPage",
+ "StatusEnum",
+ "StepLifecycle",
+ "StorageConfigType",
+ "StringFilter",
+ "SubprocessExecutionProvider",
+ "SubprocessJobExecutionProfile",
+ "SubprocessJobExecutionProfileConfig",
+ "SubprocessJobExecutionProfileProvider",
+ "TaskPrompt",
+ "TaskPromptMessagesItem",
+ "ToolCallConfig",
+ "ToolCallingMetadataContent",
+ "ToolInputRails",
+ "ToolOutputRails",
+ "Trace",
+ "TraceFilter",
+ "TraceSortField",
+ "TracesPage",
+ "TracingConfig",
+ "TrendMicroRailConfig",
+ "UpdateAdapterRequest",
+ "UserMessagesConfig",
+ "ValidationError",
+ "ValidationErrorLocItem",
+ "VirtualModel",
+ "VirtualModelInferenceConfig",
+ "VirtualModelsPage",
+ "VolcanoJobExecutionProfile",
+ "VolcanoJobExecutionProfileConfig",
+ "Workspace",
+ "WorkspaceMember",
+ "WorkspaceMemberListResponse",
+ "WorkspacesPage",
+]
diff --git a/sdks/python/types/action_rails.py b/sdks/python/types/action_rails.py
new file mode 100644
index 0000000000..d7112a813b
--- /dev/null
+++ b/sdks/python/types/action_rails.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ActionRails(UniversalBaseModel):
+ """
+ Configuration of action rails.
+
+ Action rails control various options related to the execution of actions.
+ Currently, only
+
+ In the future multiple options will be added, e.g., what input validation should be
+ performed per action, output validation, throttling, disabling, etc.
+ """
+
+ instant_actions: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all actions which should finish instantly.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/activated_rail.py b/sdks/python/types/activated_rail.py
new file mode 100644
index 0000000000..10eaf353d0
--- /dev/null
+++ b/sdks/python/types/activated_rail.py
@@ -0,0 +1,67 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .executed_action import ExecutedAction
+
+
+class ActivatedRail(UniversalBaseModel):
+ """
+ A rail that was activated during the generation.
+ """
+
+ type: str = pydantic.Field()
+ """
+ The type of the rail that was activated, e.g., input, output, dialog.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the rail, i.e., the name of the flow implementing the rail.
+ """
+
+ decisions: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ A sequence of decisions made by the rail, e.g., 'bot refuse to respond', 'stop', 'continue'.
+ """
+
+ executed_actions: typing.Optional[typing.List[ExecutedAction]] = pydantic.Field(default=None)
+ """
+ The list of actions executed by the rail.
+ """
+
+ stop: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the rail decided to stop any further processing.
+ """
+
+ additional_info: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Additional information coming from rail.
+ """
+
+ started_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timestamp for when the rail started.
+ """
+
+ finished_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timestamp for when the rail finished.
+ """
+
+ duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The duration in seconds for applying the rail. Some rails are applied instantly, e.g., dialog rails, so they don't have a duration.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/adapter.py b/sdks/python/types/adapter.py
new file mode 100644
index 0000000000..f8c60068d9
--- /dev/null
+++ b/sdks/python/types/adapter.py
@@ -0,0 +1,63 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .finetuning_type import FinetuningType
+from .lora import Lora
+
+
+class Adapter(UniversalBaseModel):
+ name: str = pydantic.Field()
+ """
+ Name of the adapter. Name must be unique in the workspace for all Adapters and match the following regex: Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace of the adapter. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description of the adapter
+ """
+
+ fileset: str = pydantic.Field()
+ """
+ Fileset where the adapter files are stored expected format {workspace}/{fileset_name}
+ """
+
+ finetuning_type: FinetuningType = pydantic.Field()
+ """
+ Type of finetuning (LORA, P_TUNING, etc.)
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to make this adapter available for inference post training
+ """
+
+ lora_config: typing.Optional[Lora] = pydantic.Field(default=None)
+ """
+ Lora configuration specifics
+ """
+
+ model: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent model entity reference. A single name (2-63 characters) or 'workspace/model_name' where each segment is a valid name (lowercase, digits, hyphens, and temporarily @ . + _; no leading/trailing or consecutive hyphens). If one slash, both sides must be non-empty.
+ """
+
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/adapter_entity_filter.py b/sdks/python/types/adapter_entity_filter.py
new file mode 100644
index 0000000000..ebb659d1b0
--- /dev/null
+++ b/sdks/python/types/adapter_entity_filter.py
@@ -0,0 +1,66 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .adapter_entity_filter_description import AdapterEntityFilterDescription
+from .adapter_entity_filter_model import AdapterEntityFilterModel
+from .adapter_entity_filter_name import AdapterEntityFilterName
+from .datetime_filter import DatetimeFilter
+from .finetuning_type import FinetuningType
+
+
+class AdapterEntityFilter(UniversalBaseModel):
+ """
+ Filter for Adapter list queries.
+ """
+
+ name: typing.Optional[AdapterEntityFilterName] = pydantic.Field(default=None)
+ """
+ Filter by adapter name.
+ """
+
+ model: typing.Optional[AdapterEntityFilterModel] = pydantic.Field(default=None)
+ """
+ Filter by parent (base) model entity reference in the form {workspace}/{model_name}.
+ """
+
+ description: typing.Optional[AdapterEntityFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by description.
+ """
+
+ fileset: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by fileset reference in the form {workspace}/{fileset_name}.
+ """
+
+ finetuning_type: typing.Optional[FinetuningType] = pydantic.Field(default=None)
+ """
+ Filter by fine-tuning / PEFT type.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Filter by whether the adapter is enabled for inference after training.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter entities based on creation date.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter entities based on update date.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/adapter_entity_filter_description.py b/sdks/python/types/adapter_entity_filter_description.py
new file mode 100644
index 0000000000..a1e609035f
--- /dev/null
+++ b/sdks/python/types/adapter_entity_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+AdapterEntityFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/adapter_entity_filter_model.py b/sdks/python/types/adapter_entity_filter_model.py
new file mode 100644
index 0000000000..4ae36aee7d
--- /dev/null
+++ b/sdks/python/types/adapter_entity_filter_model.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+AdapterEntityFilterModel = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/adapter_entity_filter_name.py b/sdks/python/types/adapter_entity_filter_name.py
new file mode 100644
index 0000000000..6ec1734eda
--- /dev/null
+++ b/sdks/python/types/adapter_entity_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+AdapterEntityFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/adapters_page.py b/sdks/python/types/adapters_page.py
new file mode 100644
index 0000000000..d92575f01f
--- /dev/null
+++ b/sdks/python/types/adapters_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .adapter import Adapter
+from .pagination_data import PaginationData
+
+
+class AdaptersPage(UniversalBaseModel):
+ data: typing.List[Adapter]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/ai_defense_rail_config.py b/sdks/python/types/ai_defense_rail_config.py
new file mode 100644
index 0000000000..b80b9d0fc9
--- /dev/null
+++ b/sdks/python/types/ai_defense_rail_config.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AiDefenseRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the Cisco AI Defense API
+ """
+
+ timeout: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timeout in seconds for API requests to AI Defense service
+ """
+
+ fail_open: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, allow content when AI Defense API call fails (fail open). If False, block content when API call fails (fail closed). Does not affect missing configuration validation.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/annotation.py b/sdks/python/types/annotation.py
new file mode 100644
index 0000000000..1481ba825e
--- /dev/null
+++ b/sdks/python/types/annotation.py
@@ -0,0 +1,121 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import datetime as dt
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .feedback_annotation_value import FeedbackAnnotationValue
+from .label_annotation_value import LabelAnnotationValue
+from .label_annotation_value_type import LabelAnnotationValueType
+
+
+class Annotation_Feedback(UniversalBaseModel):
+ """
+ Discriminated annotation read response. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["feedback"] = "feedback"
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = None
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ value: FeedbackAnnotationValue
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class Annotation_Label(UniversalBaseModel):
+ """
+ Discriminated annotation read response. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["label"] = "label"
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = None
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ value_type: LabelAnnotationValueType
+ value: LabelAnnotationValue
+ name: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class Annotation_Metadata(UniversalBaseModel):
+ """
+ Discriminated annotation read response. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["metadata"] = "metadata"
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = None
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ metadata: typing.Dict[str, typing.Any]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class Annotation_Note(UniversalBaseModel):
+ """
+ Discriminated annotation read response. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["note"] = "note"
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = None
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ text: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+Annotation = typing_extensions.Annotated[
+ typing.Union[Annotation_Feedback, Annotation_Label, Annotation_Metadata, Annotation_Note],
+ pydantic.Field(discriminator="kind"),
+]
diff --git a/sdks/python/types/annotation_filter.py b/sdks/python/types/annotation_filter.py
new file mode 100644
index 0000000000..658f643ddb
--- /dev/null
+++ b/sdks/python/types/annotation_filter.py
@@ -0,0 +1,60 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .annotation_kind import AnnotationKind
+from .datetime_filter import DatetimeFilter
+from .numeric_filter import NumericFilter
+
+
+class AnnotationFilter(UniversalBaseModel):
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Return only annotations attached to this span.
+ """
+
+ session_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Return only annotations attached to this session.
+ """
+
+ kind: typing.Optional[AnnotationKind] = pydantic.Field(default=None)
+ """
+ Return only annotations of this kind (`feedback`, `note`, `label`, or `metadata`).
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Return only `label` annotations with this `name` (e.g., `severity`, `helpfulness`).
+ """
+
+ value_text: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Return only annotations with this text value. For `feedback` annotations this is `positive` or `negative`; for `label` annotations with `value_type=text` this is the label's value.
+ """
+
+ value_numeric: typing.Optional[NumericFilter] = pydantic.Field(default=None)
+ """
+ Return only `label` annotations whose numeric value falls within the given range. Applies to labels with `value_type=numeric`.
+ """
+
+ created_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Return only annotations created by this user.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Return only annotations created within the given time range.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/annotation_input.py b/sdks/python/types/annotation_input.py
new file mode 100644
index 0000000000..3b3a6de161
--- /dev/null
+++ b/sdks/python/types/annotation_input.py
@@ -0,0 +1,100 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .feedback_annotation_input_value import FeedbackAnnotationInputValue
+from .label_annotation_input_value import LabelAnnotationInputValue
+from .label_annotation_input_value_type import LabelAnnotationInputValueType
+
+
+class AnnotationInput_Feedback(UniversalBaseModel):
+ """
+ Discriminated annotation create body. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["feedback"] = "feedback"
+ span_id: typing.Optional[str] = None
+ session_id: str
+ value: FeedbackAnnotationInputValue
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AnnotationInput_Label(UniversalBaseModel):
+ """
+ Discriminated annotation create body. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["label"] = "label"
+ span_id: typing.Optional[str] = None
+ session_id: str
+ value_type: LabelAnnotationInputValueType
+ value: LabelAnnotationInputValue
+ name: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AnnotationInput_Metadata(UniversalBaseModel):
+ """
+ Discriminated annotation create body. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["metadata"] = "metadata"
+ span_id: typing.Optional[str] = None
+ session_id: str
+ metadata: typing.Dict[str, typing.Any]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AnnotationInput_Note(UniversalBaseModel):
+ """
+ Discriminated annotation create body. The shape varies by `kind`.
+ """
+
+ kind: typing.Literal["note"] = "note"
+ span_id: typing.Optional[str] = None
+ session_id: str
+ text: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+AnnotationInput = typing_extensions.Annotated[
+ typing.Union[AnnotationInput_Feedback, AnnotationInput_Label, AnnotationInput_Metadata, AnnotationInput_Note],
+ pydantic.Field(discriminator="kind"),
+]
diff --git a/sdks/python/types/annotation_kind.py b/sdks/python/types/annotation_kind.py
new file mode 100644
index 0000000000..88355a6741
--- /dev/null
+++ b/sdks/python/types/annotation_kind.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AnnotationKind = typing.Union[typing.Literal["feedback", "label", "note", "metadata"], typing.Any]
diff --git a/sdks/python/types/annotation_sort_field.py b/sdks/python/types/annotation_sort_field.py
new file mode 100644
index 0000000000..cba611c24e
--- /dev/null
+++ b/sdks/python/types/annotation_sort_field.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AnnotationSortField = typing.Union[typing.Literal["created_at", "-created_at"], typing.Any]
diff --git a/sdks/python/types/annotations_page.py b/sdks/python/types/annotations_page.py
new file mode 100644
index 0000000000..d935258bbd
--- /dev/null
+++ b/sdks/python/types/annotations_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .annotation import Annotation
+from .pagination_data import PaginationData
+
+
+class AnnotationsPage(UniversalBaseModel):
+ data: typing.List[Annotation]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/api_endpoint_data.py b/sdks/python/types/api_endpoint_data.py
new file mode 100644
index 0000000000..6d874c362e
--- /dev/null
+++ b/sdks/python/types/api_endpoint_data.py
@@ -0,0 +1,41 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ApiEndpointData(UniversalBaseModel):
+ """
+ Data about an inference endpoint.
+ """
+
+ url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Endpoint URL
+ """
+
+ model_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Model identifier at the endpoint
+ """
+
+ api_key: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ API key for authentication
+ """
+
+ format: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ API format (e.g., openai, nvidia)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_agent.py b/sdks/python/types/atif_agent.py
new file mode 100644
index 0000000000..473b67ac9b
--- /dev/null
+++ b/sdks/python/types/atif_agent.py
@@ -0,0 +1,23 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AtifAgent(UniversalBaseModel):
+ name: str
+ version: str
+ model_name: typing.Optional[str] = None
+ tool_definitions: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_content_part.py b/sdks/python/types/atif_content_part.py
new file mode 100644
index 0000000000..f271d46253
--- /dev/null
+++ b/sdks/python/types/atif_content_part.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_image_source import AtifImageSource
+
+
+class AtifContentPart_Image(UniversalBaseModel):
+ type: typing.Literal["image"] = "image"
+ source: AtifImageSource
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AtifContentPart_Text(UniversalBaseModel):
+ type: typing.Literal["text"] = "text"
+ text: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+AtifContentPart = typing_extensions.Annotated[
+ typing.Union[AtifContentPart_Image, AtifContentPart_Text], pydantic.Field(discriminator="type")
+]
diff --git a/sdks/python/types/atif_content_part_image.py b/sdks/python/types/atif_content_part_image.py
new file mode 100644
index 0000000000..5e7d5cf1cc
--- /dev/null
+++ b/sdks/python/types/atif_content_part_image.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_image_source import AtifImageSource
+
+
+class AtifContentPartImage(UniversalBaseModel):
+ source: AtifImageSource
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_content_part_text.py b/sdks/python/types/atif_content_part_text.py
new file mode 100644
index 0000000000..b6a65a29b1
--- /dev/null
+++ b/sdks/python/types/atif_content_part_text.py
@@ -0,0 +1,19 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AtifContentPartText(UniversalBaseModel):
+ text: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_final_metrics.py b/sdks/python/types/atif_final_metrics.py
new file mode 100644
index 0000000000..5258bfffac
--- /dev/null
+++ b/sdks/python/types/atif_final_metrics.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AtifFinalMetrics(UniversalBaseModel):
+ total_prompt_tokens: typing.Optional[int] = None
+ total_completion_tokens: typing.Optional[int] = None
+ total_cached_tokens: typing.Optional[int] = None
+ total_cost_usd: typing.Optional[float] = None
+ total_steps: typing.Optional[int] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_image_source.py b/sdks/python/types/atif_image_source.py
new file mode 100644
index 0000000000..094648f5e9
--- /dev/null
+++ b/sdks/python/types/atif_image_source.py
@@ -0,0 +1,21 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_image_source_media_type import AtifImageSourceMediaType
+
+
+class AtifImageSource(UniversalBaseModel):
+ media_type: AtifImageSourceMediaType
+ path: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_image_source_media_type.py b/sdks/python/types/atif_image_source_media_type.py
new file mode 100644
index 0000000000..d62c42ebce
--- /dev/null
+++ b/sdks/python/types/atif_image_source_media_type.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AtifImageSourceMediaType = typing.Union[
+ typing.Literal["image/jpeg", "image/png", "image/gif", "image/webp"], typing.Any
+]
diff --git a/sdks/python/types/atif_metrics.py b/sdks/python/types/atif_metrics.py
new file mode 100644
index 0000000000..33cd94d3d3
--- /dev/null
+++ b/sdks/python/types/atif_metrics.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AtifMetrics(UniversalBaseModel):
+ prompt_tokens: typing.Optional[int] = None
+ completion_tokens: typing.Optional[int] = None
+ cached_tokens: typing.Optional[int] = None
+ cost_usd: typing.Optional[float] = None
+ prompt_token_ids: typing.Optional[typing.List[int]] = None
+ completion_token_ids: typing.Optional[typing.List[int]] = None
+ logprobs: typing.Optional[typing.List[float]] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_observation.py b/sdks/python/types/atif_observation.py
new file mode 100644
index 0000000000..3aba9e0e8d
--- /dev/null
+++ b/sdks/python/types/atif_observation.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_observation_result import AtifObservationResult
+
+
+class AtifObservation(UniversalBaseModel):
+ results: typing.Optional[typing.List[AtifObservationResult]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_observation_result.py b/sdks/python/types/atif_observation_result.py
new file mode 100644
index 0000000000..6f7fb5da66
--- /dev/null
+++ b/sdks/python/types/atif_observation_result.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_observation_result_content import AtifObservationResultContent
+from .atif_subagent_trajectory_ref import AtifSubagentTrajectoryRef
+
+
+class AtifObservationResult(UniversalBaseModel):
+ source_call_id: typing.Optional[str] = None
+ content: typing.Optional[AtifObservationResultContent] = None
+ subagent_trajectory_ref: typing.Optional[typing.List[AtifSubagentTrajectoryRef]] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_observation_result_content.py b/sdks/python/types/atif_observation_result_content.py
new file mode 100644
index 0000000000..0ed8cb6e68
--- /dev/null
+++ b/sdks/python/types/atif_observation_result_content.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .atif_content_part import AtifContentPart
+
+AtifObservationResultContent = typing.Union[str, typing.List[AtifContentPart]]
diff --git a/sdks/python/types/atif_step.py b/sdks/python/types/atif_step.py
new file mode 100644
index 0000000000..3685500404
--- /dev/null
+++ b/sdks/python/types/atif_step.py
@@ -0,0 +1,85 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import datetime as dt
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_metrics import AtifMetrics
+from .atif_observation import AtifObservation
+from .atif_step_agent_message import AtifStepAgentMessage
+from .atif_step_agent_reasoning_effort import AtifStepAgentReasoningEffort
+from .atif_step_system_message import AtifStepSystemMessage
+from .atif_step_user_message import AtifStepUserMessage
+from .atif_tool_call import AtifToolCall
+
+
+class AtifStep_Agent(UniversalBaseModel):
+ source: typing.Literal["agent"] = "agent"
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepAgentMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+ model_name: typing.Optional[str] = None
+ reasoning_effort: typing.Optional[AtifStepAgentReasoningEffort] = None
+ reasoning_content: typing.Optional[str] = None
+ tool_calls: typing.Optional[typing.List[AtifToolCall]] = None
+ observation: typing.Optional[AtifObservation] = None
+ metrics: typing.Optional[AtifMetrics] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AtifStep_System(UniversalBaseModel):
+ source: typing.Literal["system"] = "system"
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepSystemMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class AtifStep_User(UniversalBaseModel):
+ source: typing.Literal["user"] = "user"
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepUserMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+AtifStep = typing_extensions.Annotated[
+ typing.Union[AtifStep_Agent, AtifStep_System, AtifStep_User], pydantic.Field(discriminator="source")
+]
diff --git a/sdks/python/types/atif_step_agent.py b/sdks/python/types/atif_step_agent.py
new file mode 100644
index 0000000000..b81d3d05d1
--- /dev/null
+++ b/sdks/python/types/atif_step_agent.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_metrics import AtifMetrics
+from .atif_observation import AtifObservation
+from .atif_step_agent_message import AtifStepAgentMessage
+from .atif_step_agent_reasoning_effort import AtifStepAgentReasoningEffort
+from .atif_tool_call import AtifToolCall
+
+
+class AtifStepAgent(UniversalBaseModel):
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepAgentMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+ model_name: typing.Optional[str] = None
+ reasoning_effort: typing.Optional[AtifStepAgentReasoningEffort] = None
+ reasoning_content: typing.Optional[str] = None
+ tool_calls: typing.Optional[typing.List[AtifToolCall]] = None
+ observation: typing.Optional[AtifObservation] = None
+ metrics: typing.Optional[AtifMetrics] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_step_agent_message.py b/sdks/python/types/atif_step_agent_message.py
new file mode 100644
index 0000000000..986903fa3c
--- /dev/null
+++ b/sdks/python/types/atif_step_agent_message.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .atif_content_part import AtifContentPart
+
+AtifStepAgentMessage = typing.Union[str, typing.List[AtifContentPart]]
diff --git a/sdks/python/types/atif_step_agent_reasoning_effort.py b/sdks/python/types/atif_step_agent_reasoning_effort.py
new file mode 100644
index 0000000000..960a99b64f
--- /dev/null
+++ b/sdks/python/types/atif_step_agent_reasoning_effort.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AtifStepAgentReasoningEffort = typing.Union[str, float]
diff --git a/sdks/python/types/atif_step_system.py b/sdks/python/types/atif_step_system.py
new file mode 100644
index 0000000000..79e58635f4
--- /dev/null
+++ b/sdks/python/types/atif_step_system.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_step_system_message import AtifStepSystemMessage
+
+
+class AtifStepSystem(UniversalBaseModel):
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepSystemMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_step_system_message.py b/sdks/python/types/atif_step_system_message.py
new file mode 100644
index 0000000000..bfa6a16736
--- /dev/null
+++ b/sdks/python/types/atif_step_system_message.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .atif_content_part import AtifContentPart
+
+AtifStepSystemMessage = typing.Union[str, typing.List[AtifContentPart]]
diff --git a/sdks/python/types/atif_step_user.py b/sdks/python/types/atif_step_user.py
new file mode 100644
index 0000000000..d70fb57833
--- /dev/null
+++ b/sdks/python/types/atif_step_user.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .atif_step_user_message import AtifStepUserMessage
+
+
+class AtifStepUser(UniversalBaseModel):
+ step_id: int
+ timestamp: typing.Optional[dt.datetime] = None
+ message: typing.Optional[AtifStepUserMessage] = None
+ is_copied_context: typing.Optional[bool] = None
+ extra: typing.Optional[typing.Dict[str, typing.Any]] = None
+ llm_call_count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/atif_step_user_message.py b/sdks/python/types/atif_step_user_message.py
new file mode 100644
index 0000000000..c235e5609e
--- /dev/null
+++ b/sdks/python/types/atif_step_user_message.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .atif_content_part import AtifContentPart
+
+AtifStepUserMessage = typing.Union[str, typing.List[AtifContentPart]]
diff --git a/sdks/python/types/atif_subagent_trajectory_ref.py b/sdks/python/types/atif_subagent_trajectory_ref.py
new file mode 100644
index 0000000000..a12ad46bdf
--- /dev/null
+++ b/sdks/python/types/atif_subagent_trajectory_ref.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+AtifSubagentTrajectoryRef = typing.Union[typing.Any]
diff --git a/sdks/python/types/atif_tool_call.py b/sdks/python/types/atif_tool_call.py
new file mode 100644
index 0000000000..d68115aeae
--- /dev/null
+++ b/sdks/python/types/atif_tool_call.py
@@ -0,0 +1,21 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AtifToolCall(UniversalBaseModel):
+ tool_call_id: str
+ function_name: str
+ arguments: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/auth_context.py b/sdks/python/types/auth_context.py
new file mode 100644
index 0000000000..86f85c681d
--- /dev/null
+++ b/sdks/python/types/auth_context.py
@@ -0,0 +1,54 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AuthContext(UniversalBaseModel):
+ """
+ Auth context captured at resource creation for delegated access.
+
+ Stores a snapshot of the creating principal's identity so that controllers
+ can later act on their behalf (e.g., accessing secrets).
+ """
+
+ principal_id: str = pydantic.Field()
+ """
+ The principal's unique identifier
+ """
+
+ principal_email: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The principal's email address
+ """
+
+ principal_groups: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Groups the principal belongs to
+ """
+
+ principal_on_behalf_of: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ If acting on behalf of another principal, their principal ID
+ """
+
+ principal_on_behalf_of_groups: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Groups the on-behalf-of principal belongs to
+ """
+
+ principal_on_behalf_of_email: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The on-behalf-of principal's email address
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/auth_discovery_response.py b/sdks/python/types/auth_discovery_response.py
new file mode 100644
index 0000000000..81ecea1e87
--- /dev/null
+++ b/sdks/python/types/auth_discovery_response.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .oidc_discovery_response import OidcDiscoveryResponse
+
+
+class AuthDiscoveryResponse(UniversalBaseModel):
+ """
+ Auth discovery response for CLI/SDK.
+ """
+
+ auth_enabled: bool
+ oidc: typing.Optional[OidcDiscoveryResponse] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/auto_align_options.py b/sdks/python/types/auto_align_options.py
new file mode 100644
index 0000000000..6c3e7696f9
--- /dev/null
+++ b/sdks/python/types/auto_align_options.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class AutoAlignOptions(UniversalBaseModel):
+ """
+ List of guardrails that are activated
+ """
+
+ guardrails_config: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ The guardrails configuration that is passed to the AutoAlign endpoint
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/auto_align_rail_config.py b/sdks/python/types/auto_align_rail_config.py
new file mode 100644
index 0000000000..c49d770081
--- /dev/null
+++ b/sdks/python/types/auto_align_rail_config.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .auto_align_options import AutoAlignOptions
+
+
+class AutoAlignRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the AutoAlign API
+ """
+
+ parameters: typing.Optional[typing.Dict[str, typing.Any]] = None
+ input: typing.Optional[AutoAlignOptions] = pydantic.Field(default=None)
+ """
+ Input configuration for AutoAlign guardrails
+ """
+
+ output: typing.Optional[AutoAlignOptions] = pydantic.Field(default=None)
+ """
+ Output configuration for AutoAlign guardrails
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/backend_format.py b/sdks/python/types/backend_format.py
new file mode 100644
index 0000000000..5ed6e47a5f
--- /dev/null
+++ b/sdks/python/types/backend_format.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+BackendFormat = typing.Union[typing.Literal["OPENAI_CHAT", "ANTHROPIC_MESSAGES"], typing.Any]
diff --git a/sdks/python/types/base_model_filter.py b/sdks/python/types/base_model_filter.py
new file mode 100644
index 0000000000..82f21a9c0c
--- /dev/null
+++ b/sdks/python/types/base_model_filter.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .base_model_filter_name import BaseModelFilterName
+
+
+class BaseModelFilter(UniversalBaseModel):
+ """
+ Filter for base model properties.
+ """
+
+ name: typing.Optional[BaseModelFilterName] = pydantic.Field(default=None)
+ """
+ Filter by name of the base model.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/base_model_filter_name.py b/sdks/python/types/base_model_filter_name.py
new file mode 100644
index 0000000000..2e79301ea5
--- /dev/null
+++ b/sdks/python/types/base_model_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+BaseModelFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/cache_stats_config.py b/sdks/python/types/cache_stats_config.py
new file mode 100644
index 0000000000..ddf33fff3a
--- /dev/null
+++ b/sdks/python/types/cache_stats_config.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class CacheStatsConfig(UniversalBaseModel):
+ """
+ Configuration for cache statistics tracking and logging.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether cache statistics tracking is enabled
+ """
+
+ log_interval: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Seconds between periodic cache stats logging to logs (None disables logging)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/cache_status.py b/sdks/python/types/cache_status.py
new file mode 100644
index 0000000000..bbe6a3d467
--- /dev/null
+++ b/sdks/python/types/cache_status.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+CacheStatus = typing.Union[typing.Literal["cached", "caching", "not_cached", "not_cacheable"], typing.Any]
diff --git a/sdks/python/types/captured_chat_completions_request.py b/sdks/python/types/captured_chat_completions_request.py
new file mode 100644
index 0000000000..c5f12d0d9a
--- /dev/null
+++ b/sdks/python/types/captured_chat_completions_request.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .captured_chat_message import CapturedChatMessage
+
+
+class CapturedChatCompletionsRequest(UniversalBaseModel):
+ """
+ Flexible captured chat-completions request.
+ """
+
+ messages: typing.List[CapturedChatMessage] = pydantic.Field()
+ """
+ Messages comprising the conversation.
+ """
+
+ model: str = pydantic.Field()
+ """
+ The model identifier used for this request.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/captured_chat_completions_response.py b/sdks/python/types/captured_chat_completions_response.py
new file mode 100644
index 0000000000..96895ea1fa
--- /dev/null
+++ b/sdks/python/types/captured_chat_completions_response.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+CapturedChatCompletionsResponse = typing.Union[typing.Any]
diff --git a/sdks/python/types/captured_chat_message.py b/sdks/python/types/captured_chat_message.py
new file mode 100644
index 0000000000..3f08112c1b
--- /dev/null
+++ b/sdks/python/types/captured_chat_message.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .chat_message_role import ChatMessageRole
+
+
+class CapturedChatMessage(UniversalBaseModel):
+ """
+ A flexible message model that requires a valid role field but allows provider-specific fields.
+ """
+
+ role: ChatMessageRole = pydantic.Field()
+ """
+ The role of the message sender.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_assistant_message_param.py b/sdks/python/types/chat_completion_assistant_message_param.py
new file mode 100644
index 0000000000..839111e7f7
--- /dev/null
+++ b/sdks/python/types/chat_completion_assistant_message_param.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .chat_completion_message_tool_call_param import ChatCompletionMessageToolCallParam
+from .function_call import FunctionCall
+
+
+class ChatCompletionAssistantMessageParam(UniversalBaseModel):
+ """
+ Assistant message parameter for chat completion.
+ """
+
+ content: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The contents of the assistant message.
+ """
+
+ function_call: typing.Optional[FunctionCall] = pydantic.Field(default=None)
+ """
+ Deprecated and replaced by `tool_calls`.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ An optional name for the participant.
+ """
+
+ tool_calls: typing.Optional[typing.List[ChatCompletionMessageToolCallParam]] = pydantic.Field(default=None)
+ """
+ The tool calls generated by the model, such as function calls.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_content_part_image_param.py b/sdks/python/types/chat_completion_content_part_image_param.py
new file mode 100644
index 0000000000..72891ba716
--- /dev/null
+++ b/sdks/python/types/chat_completion_content_part_image_param.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .image_url import ImageUrl
+
+
+class ChatCompletionContentPartImageParam(UniversalBaseModel):
+ """
+ Image content part for chat messages.
+ """
+
+ image_url: ImageUrl = pydantic.Field()
+ """
+ The image URL information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_content_part_text_param.py b/sdks/python/types/chat_completion_content_part_text_param.py
new file mode 100644
index 0000000000..2c9d83e71e
--- /dev/null
+++ b/sdks/python/types/chat_completion_content_part_text_param.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ChatCompletionContentPartTextParam(UniversalBaseModel):
+ """
+ Text content part for chat messages.
+ """
+
+ text: str = pydantic.Field()
+ """
+ The text content.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_function_message_param.py b/sdks/python/types/chat_completion_function_message_param.py
new file mode 100644
index 0000000000..b49c43686a
--- /dev/null
+++ b/sdks/python/types/chat_completion_function_message_param.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ChatCompletionFunctionMessageParam(UniversalBaseModel):
+ """
+ Function message parameter for chat completion.
+ """
+
+ content: str = pydantic.Field()
+ """
+ The contents of the function message.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the function to call.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_message_tool_call_param.py b/sdks/python/types/chat_completion_message_tool_call_param.py
new file mode 100644
index 0000000000..07a4eb5c19
--- /dev/null
+++ b/sdks/python/types/chat_completion_message_tool_call_param.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .chat_completion_message_tool_call_param_type import ChatCompletionMessageToolCallParamType
+from .function import Function
+
+
+class ChatCompletionMessageToolCallParam(UniversalBaseModel):
+ """
+ Tool call parameter for chat completion messages.
+ """
+
+ id: str = pydantic.Field()
+ """
+ The ID of the tool call.
+ """
+
+ function: Function = pydantic.Field()
+ """
+ The function that the model called.
+ """
+
+ type: ChatCompletionMessageToolCallParamType = pydantic.Field()
+ """
+ The type of the tool. Currently, only `function` is supported.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_message_tool_call_param_type.py b/sdks/python/types/chat_completion_message_tool_call_param_type.py
new file mode 100644
index 0000000000..a152fa64b3
--- /dev/null
+++ b/sdks/python/types/chat_completion_message_tool_call_param_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ChatCompletionMessageToolCallParamType = typing.Union[typing.Literal["function"], typing.Any]
diff --git a/sdks/python/types/chat_completion_system_message_param.py b/sdks/python/types/chat_completion_system_message_param.py
new file mode 100644
index 0000000000..4d4cb6e199
--- /dev/null
+++ b/sdks/python/types/chat_completion_system_message_param.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ChatCompletionSystemMessageParam(UniversalBaseModel):
+ """
+ System message parameter for chat completion.
+ """
+
+ content: str = pydantic.Field()
+ """
+ The contents of the system message.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ An optional name for the participant.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_tool_message_param.py b/sdks/python/types/chat_completion_tool_message_param.py
new file mode 100644
index 0000000000..e2d6b6b9c2
--- /dev/null
+++ b/sdks/python/types/chat_completion_tool_message_param.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ChatCompletionToolMessageParam(UniversalBaseModel):
+ """
+ Tool message parameter for chat completion.
+ """
+
+ content: str = pydantic.Field()
+ """
+ The contents of the tool message.
+ """
+
+ tool_call_id: str = pydantic.Field()
+ """
+ Tool call that this message is responding to.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_user_message_param.py b/sdks/python/types/chat_completion_user_message_param.py
new file mode 100644
index 0000000000..c89549c6e4
--- /dev/null
+++ b/sdks/python/types/chat_completion_user_message_param.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .chat_completion_user_message_param_content import ChatCompletionUserMessageParamContent
+
+
+class ChatCompletionUserMessageParam(UniversalBaseModel):
+ """
+ User message parameter for chat completion.
+ """
+
+ content: ChatCompletionUserMessageParamContent = pydantic.Field()
+ """
+ The contents of the user message.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ An optional name for the participant.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_completion_user_message_param_content.py b/sdks/python/types/chat_completion_user_message_param_content.py
new file mode 100644
index 0000000000..9f1264adc2
--- /dev/null
+++ b/sdks/python/types/chat_completion_user_message_param_content.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .chat_completion_user_message_param_content_one_item import ChatCompletionUserMessageParamContentOneItem
+
+ChatCompletionUserMessageParamContent = typing.Union[str, typing.List[ChatCompletionUserMessageParamContentOneItem]]
diff --git a/sdks/python/types/chat_completion_user_message_param_content_one_item.py b/sdks/python/types/chat_completion_user_message_param_content_one_item.py
new file mode 100644
index 0000000000..f8504e0fb8
--- /dev/null
+++ b/sdks/python/types/chat_completion_user_message_param_content_one_item.py
@@ -0,0 +1,46 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .image_url import ImageUrl
+
+
+class ChatCompletionUserMessageParamContentOneItem_Text(UniversalBaseModel):
+ type: typing.Literal["text"] = "text"
+ text: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class ChatCompletionUserMessageParamContentOneItem_ImageUrl(UniversalBaseModel):
+ type: typing.Literal["image_url"] = "image_url"
+ image_url: ImageUrl
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+ChatCompletionUserMessageParamContentOneItem = typing_extensions.Annotated[
+ typing.Union[
+ ChatCompletionUserMessageParamContentOneItem_Text, ChatCompletionUserMessageParamContentOneItem_ImageUrl
+ ],
+ pydantic.Field(discriminator="type"),
+]
diff --git a/sdks/python/types/chat_completions_ingest_response.py b/sdks/python/types/chat_completions_ingest_response.py
new file mode 100644
index 0000000000..c8e8c66bdf
--- /dev/null
+++ b/sdks/python/types/chat_completions_ingest_response.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ChatCompletionsIngestResponse(UniversalBaseModel):
+ session_id: str
+ span_id: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/chat_message_role.py b/sdks/python/types/chat_message_role.py
new file mode 100644
index 0000000000..32336a5180
--- /dev/null
+++ b/sdks/python/types/chat_message_role.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ChatMessageRole = typing.Union[
+ typing.Literal["user", "system", "assistant", "developer", "tool", "function"], typing.Any
+]
diff --git a/sdks/python/types/clavata_rail_config.py b/sdks/python/types/clavata_rail_config.py
new file mode 100644
index 0000000000..1c88e09583
--- /dev/null
+++ b/sdks/python/types/clavata_rail_config.py
@@ -0,0 +1,50 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .clavata_rail_config_label_match_logic import ClavataRailConfigLabelMatchLogic
+from .clavata_rail_options import ClavataRailOptions
+
+
+class ClavataRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the Clavata API
+ """
+
+ server_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The endpoint for the Clavata API
+ """
+
+ policies: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ A dictionary of policy aliases and their corresponding IDs.
+ """
+
+ label_match_logic: typing.Optional[ClavataRailConfigLabelMatchLogic] = pydantic.Field(default=None)
+ """
+ The logic to use when deciding whether the evaluation matched.
+ If ANY, only one of the configured labels needs to be found in the input or output.
+ If ALL, all configured labels must be found in the input or output.
+ """
+
+ input: typing.Optional[ClavataRailOptions] = pydantic.Field(default=None)
+ """
+ Clavata configuration for an Input Guardrail
+ """
+
+ output: typing.Optional[ClavataRailOptions] = pydantic.Field(default=None)
+ """
+ Clavata configuration for an Output Guardrail
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/clavata_rail_config_label_match_logic.py b/sdks/python/types/clavata_rail_config_label_match_logic.py
new file mode 100644
index 0000000000..6d8f8b3097
--- /dev/null
+++ b/sdks/python/types/clavata_rail_config_label_match_logic.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ClavataRailConfigLabelMatchLogic = typing.Union[typing.Literal["ANY", "ALL"], typing.Any]
diff --git a/sdks/python/types/clavata_rail_options.py b/sdks/python/types/clavata_rail_options.py
new file mode 100644
index 0000000000..2d08c1f934
--- /dev/null
+++ b/sdks/python/types/clavata_rail_options.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ClavataRailOptions(UniversalBaseModel):
+ """
+ Configuration data for the Clavata API
+ """
+
+ policy: str = pydantic.Field()
+ """
+ The policy alias to use when evaluating inputs or outputs.
+ """
+
+ labels: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ A list of labels to match against the policy.
+ If no labels are provided, the overall policy result will be returned.
+ If labels are provided, only hits on the provided labels will be considered a hit.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/compute_resource_spec.py b/sdks/python/types/compute_resource_spec.py
new file mode 100644
index 0000000000..d531a2a1cf
--- /dev/null
+++ b/sdks/python/types/compute_resource_spec.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ComputeResourceSpec(UniversalBaseModel):
+ """
+ Resource specification.
+ """
+
+ cpu: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ CPU specification (e.g., '250m', '1', '2.5').
+ """
+
+ memory: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Memory specification (e.g., '128Mi', '1Gi', '512M').
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/compute_resources.py b/sdks/python/types/compute_resources.py
new file mode 100644
index 0000000000..a48b15da24
--- /dev/null
+++ b/sdks/python/types/compute_resources.py
@@ -0,0 +1,47 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resource_spec import ComputeResourceSpec
+
+
+class ComputeResources(UniversalBaseModel):
+ """
+ Resource requirements matching k8s ResourceRequirements format.
+ """
+
+ requests: typing.Optional[ComputeResourceSpec] = pydantic.Field(default=None)
+ """
+ Minimum resources requested for the container.
+ """
+
+ limits: typing.Optional[ComputeResourceSpec] = pydantic.Field(default=None)
+ """
+ Maximum resources the container can use.
+ """
+
+ num_nodes: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of nodes to use.
+ """
+
+ num_gpus: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Step requesting number of GPUs.
+ """
+
+ shm_size: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Shared memory (/dev/shm) size as a Kubernetes quantity (e.g. '1Gi', '4Gi'). Used for GPU and distributed-GPU job executors. When unset, defaults to 1Gi per allocated GPU.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/container_executor_config.py b/sdks/python/types/container_executor_config.py
new file mode 100644
index 0000000000..08c4b4a1c6
--- /dev/null
+++ b/sdks/python/types/container_executor_config.py
@@ -0,0 +1,71 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .k8s_nim_operator_config import K8SNimOperatorConfig
+
+
+class ContainerExecutorConfig(UniversalBaseModel):
+ """
+ Compute + container settings shared by the docker and k8s executors.
+
+ Both the docker and k8s executors run containers and share this shape.
+ A future non-container executor (e.g. subprocess) would warrant turning
+ ``executor_config`` into a discriminated union.
+ """
+
+ gpu: int = pydantic.Field()
+ """
+ Number of GPUs required for the deployment. 0 = CPU-only.
+ """
+
+ disk_size: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Disk size for the deployment
+ """
+
+ image_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Container image name. If not specified, defaults to the engine's configured image (e.g. default_vllm_image / default_nimservice_image). Required for engine='generic'.
+ """
+
+ image_tag: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Container image tag. If not specified, defaults to the engine's configured image tag.
+ """
+
+ health_check_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ HTTP path used for the container readiness probe. If not specified, defaults to the engine's standard health endpoint (e.g. '/v1/health/ready' for NIM, '/health' for vLLM). Set this for engine='generic' containers that expose a non-standard health endpoint.
+ """
+
+ additional_envs: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Additional environment variables for the deployment
+ """
+
+ additional_args: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Raw container/`serve` args appended verbatim to the container's arg vector.
+ """
+
+ k8s_nim_operator_config: typing.Optional[K8SNimOperatorConfig] = pydantic.Field(default=None)
+ """
+ Typed Kubernetes configuration for common NIMService Spec fields (NIM engine on k8s). Applied after defaults but before override_config. Ignored by non-NIM engines.
+ """
+
+ override_config: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Raw NIMService spec configuration that takes precedence over generated config (NIM engine on k8s). Allows advanced configuration options directly. Ignored by non-NIM engines.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/container_spec.py b/sdks/python/types/container_spec.py
new file mode 100644
index 0000000000..cb6e6bee73
--- /dev/null
+++ b/sdks/python/types/container_spec.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ContainerSpec(UniversalBaseModel):
+ """
+ Specification for a container configuration.
+
+ Defines the container image and related configuration for job execution.
+ """
+
+ image: str
+ entrypoint: typing.Optional[typing.List[str]] = None
+ command: typing.Optional[typing.List[str]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/content_safety_config.py b/sdks/python/types/content_safety_config.py
new file mode 100644
index 0000000000..5755a22ee9
--- /dev/null
+++ b/sdks/python/types/content_safety_config.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .multilingual_config import MultilingualConfig
+from .reasoning_config import ReasoningConfig
+
+
+class ContentSafetyConfig(UniversalBaseModel):
+ """
+ Configuration data for content safety rails.
+ """
+
+ multilingual: typing.Optional[MultilingualConfig] = None
+ reasoning: typing.Optional[ReasoningConfig] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/cpu_execution_provider_input.py b/sdks/python/types/cpu_execution_provider_input.py
new file mode 100644
index 0000000000..96ed5c2d32
--- /dev/null
+++ b/sdks/python/types/cpu_execution_provider_input.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class CpuExecutionProviderInput(UniversalBaseModel):
+ """
+ CPU-based execution provider.
+
+ Provides configuration for running jobs on CPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for CPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/cpu_execution_provider_output.py b/sdks/python/types/cpu_execution_provider_output.py
new file mode 100644
index 0000000000..3577fc4741
--- /dev/null
+++ b/sdks/python/types/cpu_execution_provider_output.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class CpuExecutionProviderOutput(UniversalBaseModel):
+ """
+ CPU-based execution provider.
+
+ Provides configuration for running jobs on CPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for CPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/crowd_strike_aidr_rail_config.py b/sdks/python/types/crowd_strike_aidr_rail_config.py
new file mode 100644
index 0000000000..0bd0f8cd98
--- /dev/null
+++ b/sdks/python/types/crowd_strike_aidr_rail_config.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class CrowdStrikeAidrRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the CrowdStrike AIDR API
+ """
+
+ timeout: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timeout in seconds for API requests to CrowdStrike AIDR
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/dataset_metadata_content.py b/sdks/python/types/dataset_metadata_content.py
new file mode 100644
index 0000000000..f0bb191147
--- /dev/null
+++ b/sdks/python/types/dataset_metadata_content.py
@@ -0,0 +1,45 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+from .dataset_metadata_content_schema import DatasetMetadataContentSchema
+from .dataset_metadata_content_schemas_by_path_value import DatasetMetadataContentSchemasByPathValue
+
+
+class DatasetMetadataContent(UniversalBaseModel):
+ """
+ Content for dataset-type filesets.
+ """
+
+ schema_: typing_extensions.Annotated[
+ typing.Optional[DatasetMetadataContentSchema],
+ FieldMetadata(alias="schema"),
+ pydantic.Field(
+ alias="schema",
+ description="Default row schema for files in this fileset, either inline JSON Schema or a schema_defs key.",
+ ),
+ ] = None
+ schema_defs: typing.Optional[typing.Dict[str, typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ Reusable JSON Schema definitions keyed by name for deduplicating per-file dataset schemas.
+ """
+
+ schemas_by_path: typing.Optional[typing.Dict[str, DatasetMetadataContentSchemasByPathValue]] = pydantic.Field(
+ default=None
+ )
+ """
+ Optional per-file row schemas keyed by relative path within the fileset. Each value may be inline JSON Schema or a schema_defs key.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/dataset_metadata_content_schema.py b/sdks/python/types/dataset_metadata_content_schema.py
new file mode 100644
index 0000000000..2c2f9477ab
--- /dev/null
+++ b/sdks/python/types/dataset_metadata_content_schema.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+DatasetMetadataContentSchema = typing.Union[typing.Dict[str, typing.Any], str]
diff --git a/sdks/python/types/dataset_metadata_content_schemas_by_path_value.py b/sdks/python/types/dataset_metadata_content_schemas_by_path_value.py
new file mode 100644
index 0000000000..228e080ece
--- /dev/null
+++ b/sdks/python/types/dataset_metadata_content_schemas_by_path_value.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+DatasetMetadataContentSchemasByPathValue = typing.Union[typing.Dict[str, typing.Any], str]
diff --git a/sdks/python/types/date_range_filter.py b/sdks/python/types/date_range_filter.py
new file mode 100644
index 0000000000..09a290f982
--- /dev/null
+++ b/sdks/python/types/date_range_filter.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class DateRangeFilter(UniversalBaseModel):
+ """
+ Filter for date ranges.
+ """
+
+ gte: typing.Optional[dt.datetime] = pydantic.Field(default=None)
+ """
+ Greater than or equal to this date
+ """
+
+ lte: typing.Optional[dt.datetime] = pydantic.Field(default=None)
+ """
+ Less than or equal to this date
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/datetime_filter.py b/sdks/python/types/datetime_filter.py
new file mode 100644
index 0000000000..da56bf9fe0
--- /dev/null
+++ b/sdks/python/types/datetime_filter.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class DatetimeFilter(UniversalBaseModel):
+ gte: typing_extensions.Annotated[
+ typing.Optional[dt.datetime],
+ FieldMetadata(alias="$gte"),
+ pydantic.Field(alias="$gte", description="Filter for results greater than or equal to this datetime."),
+ ] = None
+ lte: typing_extensions.Annotated[
+ typing.Optional[dt.datetime],
+ FieldMetadata(alias="$lte"),
+ pydantic.Field(alias="$lte", description="Filter for results less than or equal to this datetime."),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/delete_response.py b/sdks/python/types/delete_response.py
new file mode 100644
index 0000000000..6d66d46267
--- /dev/null
+++ b/sdks/python/types/delete_response.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class DeleteResponse(UniversalBaseModel):
+ message: typing.Optional[str] = None
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The ID of the deleted resource.
+ """
+
+ deleted_at: typing.Optional[dt.datetime] = pydantic.Field(default=None)
+ """
+ The timestamp when the resource was deleted.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/dialog_rails.py b/sdks/python/types/dialog_rails.py
new file mode 100644
index 0000000000..c8a5214c9a
--- /dev/null
+++ b/sdks/python/types/dialog_rails.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .single_call_config import SingleCallConfig
+from .user_messages_config import UserMessagesConfig
+
+
+class DialogRails(UniversalBaseModel):
+ """
+ Configuration of topical rails.
+ """
+
+ single_call: typing.Optional[SingleCallConfig] = pydantic.Field(default=None)
+ """
+ Configuration for the single LLM call option.
+ """
+
+ user_messages: typing.Optional[UserMessagesConfig] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/distributed_gpu_execution_provider_input.py b/sdks/python/types/distributed_gpu_execution_provider_input.py
new file mode 100644
index 0000000000..362070dd4f
--- /dev/null
+++ b/sdks/python/types/distributed_gpu_execution_provider_input.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class DistributedGpuExecutionProviderInput(UniversalBaseModel):
+ """
+ GPU-based execution provider.
+
+ Provides configuration for running jobs on GPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for distributed GPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/distributed_gpu_execution_provider_output.py b/sdks/python/types/distributed_gpu_execution_provider_output.py
new file mode 100644
index 0000000000..2b4cc2698b
--- /dev/null
+++ b/sdks/python/types/distributed_gpu_execution_provider_output.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class DistributedGpuExecutionProviderOutput(UniversalBaseModel):
+ """
+ GPU-based execution provider.
+
+ Provides configuration for running jobs on GPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for distributed GPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_job_execution_profile.py b/sdks/python/types/docker_job_execution_profile.py
new file mode 100644
index 0000000000..aac9a72d1a
--- /dev/null
+++ b/sdks/python/types/docker_job_execution_profile.py
@@ -0,0 +1,39 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .docker_job_execution_profile_config import DockerJobExecutionProfileConfig
+
+
+class DockerJobExecutionProfile(UniversalBaseModel):
+ """
+ Execution configuration for a Docker Job.
+ This is used to define the executor type, provider, profile, and any additional configuration
+ required for the executor to run the job on Docker
+ """
+
+ provider: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The compute provider for the executor, e.g., cpu, gpu
+ """
+
+ profile: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The profile name for the executor, e.g., high_priority_a100, low_priority, etc.
+ """
+
+ config: DockerJobExecutionProfileConfig = pydantic.Field()
+ """
+ Additional configuration for the docker executor
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_job_execution_profile_config.py b/sdks/python/types/docker_job_execution_profile_config.py
new file mode 100644
index 0000000000..d140fd13bb
--- /dev/null
+++ b/sdks/python/types/docker_job_execution_profile_config.py
@@ -0,0 +1,47 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .docker_job_network_config import DockerJobNetworkConfig
+from .docker_job_storage_config import DockerJobStorageConfig
+
+
+class DockerJobExecutionProfileConfig(UniversalBaseModel):
+ """
+ Configuration for Docker Job execution profile.
+ """
+
+ ttl_seconds_before_active: typing.Optional[int] = None
+ ttl_seconds_active: typing.Optional[int] = None
+ ttl_seconds_after_finished: typing.Optional[int] = None
+ cleanup_completed_jobs_immediately: typing.Optional[bool] = None
+ launcher_tool_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Path to the jobs launcher tool
+ """
+
+ env: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Optional env vars applied to all jobs (e.g. HOME=/tmp). Keys must not conflict with platform-reserved names. Job steps may override these variables.
+ """
+
+ storage: typing.Optional[DockerJobStorageConfig] = pydantic.Field(default=None)
+ """
+ Docker storage configuration
+ """
+
+ networking: typing.Optional[DockerJobNetworkConfig] = pydantic.Field(default=None)
+ """
+ Docker networking configuration
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_job_network_config.py b/sdks/python/types/docker_job_network_config.py
new file mode 100644
index 0000000000..c44472ffd5
--- /dev/null
+++ b/sdks/python/types/docker_job_network_config.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class DockerJobNetworkConfig(UniversalBaseModel):
+ job_container_network: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Docker network for the job container
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_job_storage_config.py b/sdks/python/types/docker_job_storage_config.py
new file mode 100644
index 0000000000..709cf45ea2
--- /dev/null
+++ b/sdks/python/types/docker_job_storage_config.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .docker_volume_mount import DockerVolumeMount
+
+
+class DockerJobStorageConfig(UniversalBaseModel):
+ """
+ Configuration for persistent storage in Docker jobs.
+ """
+
+ volume_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Name of the Docker volume for persistent storage
+ """
+
+ volume_permissions_image: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Docker image used to set permissions on the volume
+ """
+
+ additional_volume_mounts: typing.Optional[typing.List[DockerVolumeMount]] = pydantic.Field(default=None)
+ """
+ List of additional Docker volume mounts for the job
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_volume_mount.py b/sdks/python/types/docker_volume_mount.py
new file mode 100644
index 0000000000..82746ee036
--- /dev/null
+++ b/sdks/python/types/docker_volume_mount.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .docker_volume_mount_kind import DockerVolumeMountKind
+
+
+class DockerVolumeMount(UniversalBaseModel):
+ volume_name: str = pydantic.Field()
+ """
+ Name of the Docker volume to mount
+ """
+
+ mount_path: str = pydantic.Field()
+ """
+ Path inside the container where the volume will be mounted
+ """
+
+ kind: typing.Optional[DockerVolumeMountKind] = pydantic.Field(default=None)
+ """
+ Type of the Docker volume to mount. Options are 'volume' or 'tmpfs' (default: 'volume'). tmpfs volumes are only supported on Linux hosts.
+ """
+
+ options: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Additional options for the volume
+ """
+
+ allow_create_volume: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to allow the creation of the volume if it does not exist (default: false).
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/docker_volume_mount_kind.py b/sdks/python/types/docker_volume_mount_kind.py
new file mode 100644
index 0000000000..97785d8734
--- /dev/null
+++ b/sdks/python/types/docker_volume_mount_kind.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+DockerVolumeMountKind = typing.Union[typing.Literal["volume", "tmpfs"], typing.Any]
diff --git a/sdks/python/types/e2e_job_execution_profile.py b/sdks/python/types/e2e_job_execution_profile.py
new file mode 100644
index 0000000000..eb7c24ca26
--- /dev/null
+++ b/sdks/python/types/e2e_job_execution_profile.py
@@ -0,0 +1,39 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .job_execution_profile_config import JobExecutionProfileConfig
+
+
+class E2EJobExecutionProfile(UniversalBaseModel):
+ """
+ Execution configuration for E2E testing.
+ This backend auto-completes jobs without actually running containers,
+ making tests fast and deterministic.
+ """
+
+ provider: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The compute provider for the executor, e.g., cpu, gpu
+ """
+
+ profile: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The profile name for the executor, e.g., high_priority_a100, low_priority, etc.
+ """
+
+ config: typing.Optional[JobExecutionProfileConfig] = pydantic.Field(default=None)
+ """
+ Configuration for the e2e test executor
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/engine.py b/sdks/python/types/engine.py
new file mode 100644
index 0000000000..e8d0b20240
--- /dev/null
+++ b/sdks/python/types/engine.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+Engine = typing.Union[typing.Literal["nim", "vllm", "generic"], typing.Any]
diff --git a/sdks/python/types/entities_page.py b/sdks/python/types/entities_page.py
new file mode 100644
index 0000000000..068f1aab9a
--- /dev/null
+++ b/sdks/python/types/entities_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .entity import Entity
+from .pagination_data import PaginationData
+
+
+class EntitiesPage(UniversalBaseModel):
+ data: typing.List[Entity]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/entity.py b/sdks/python/types/entity.py
new file mode 100644
index 0000000000..0f626884b0
--- /dev/null
+++ b/sdks/python/types/entity.py
@@ -0,0 +1,82 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Entity(UniversalBaseModel):
+ """
+ Entity schema for API responses.
+ """
+
+ entity_type: str = pydantic.Field()
+ """
+ Entity type identifier
+ """
+
+ id: str = pydantic.Field()
+ """
+ UUID identifier
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ parent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent entity ID for nested entities
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the project associated with this entity
+ """
+
+ name: str = pydantic.Field()
+ """
+ Entity name
+ """
+
+ data: typing.Dict[str, typing.Any] = pydantic.Field()
+ """
+ Entity data
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ Timestamp of entity creation
+ """
+
+ created_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Principal id for entity creator
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ Timestamp of last entity update
+ """
+
+ updated_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Principal id for last entity update
+ """
+
+ db_version: int = pydantic.Field()
+ """
+ Database version of the entity for optimistic locking.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/evaluation_context.py b/sdks/python/types/evaluation_context.py
new file mode 100644
index 0000000000..b8548be906
--- /dev/null
+++ b/sdks/python/types/evaluation_context.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class EvaluationContext(UniversalBaseModel):
+ evaluation_id: typing.Optional[str] = None
+ evaluation_sha: typing.Optional[str] = None
+ evaluation_run_id: typing.Optional[str] = None
+ dataset_id: typing.Optional[str] = None
+ dataset_name: typing.Optional[str] = None
+ dataset_version: typing.Optional[str] = None
+ test_case_id: typing.Optional[str] = None
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/evaluator_aggregate.py b/sdks/python/types/evaluator_aggregate.py
new file mode 100644
index 0000000000..05c85c7863
--- /dev/null
+++ b/sdks/python/types/evaluator_aggregate.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class EvaluatorAggregate(UniversalBaseModel):
+ """
+ Aggregate statistics over evaluator scores or session-level metric values.
+ """
+
+ sum: typing.Optional[float] = None
+ mean: typing.Optional[float] = None
+ median: typing.Optional[float] = None
+ p90: typing.Optional[float] = None
+ p95: typing.Optional[float] = None
+ p99: typing.Optional[float] = None
+ count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/evaluator_result.py b/sdks/python/types/evaluator_result.py
new file mode 100644
index 0000000000..303e069fa1
--- /dev/null
+++ b/sdks/python/types/evaluator_result.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .evaluator_result_data_type import EvaluatorResultDataType
+
+
+class EvaluatorResult(UniversalBaseModel):
+ """
+ Response model for evaluator_results read endpoints.
+ """
+
+ evaluator_result_id: str
+ span_id: str
+ session_id: str
+ workspace: str
+ name: str
+ value: typing.Optional[float] = None
+ string_value: typing.Optional[str] = None
+ data_type: EvaluatorResultDataType
+ comment: typing.Optional[str] = None
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/evaluator_result_data_type.py b/sdks/python/types/evaluator_result_data_type.py
new file mode 100644
index 0000000000..11d92e3387
--- /dev/null
+++ b/sdks/python/types/evaluator_result_data_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+EvaluatorResultDataType = typing.Union[typing.Literal["NUMERIC", "CATEGORICAL", "BOOLEAN", "TEXT"], typing.Any]
diff --git a/sdks/python/types/evaluator_result_filter.py b/sdks/python/types/evaluator_result_filter.py
new file mode 100644
index 0000000000..ee432229cd
--- /dev/null
+++ b/sdks/python/types/evaluator_result_filter.py
@@ -0,0 +1,55 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .evaluator_result_data_type import EvaluatorResultDataType
+from .float_filter import FloatFilter
+
+
+class EvaluatorResultFilter(UniversalBaseModel):
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by target span id.
+ """
+
+ session_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by target session id.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by evaluator/metric name.
+ """
+
+ data_type: typing.Optional[EvaluatorResultDataType] = pydantic.Field(default=None)
+ """
+ Filter by data_type.
+ """
+
+ created_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by principal/system that wrote the row.
+ """
+
+ value: typing.Optional[FloatFilter] = pydantic.Field(default=None)
+ """
+ Filter by numeric value (range supported).
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by row creation time (range supported).
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/evaluator_result_sort_field.py b/sdks/python/types/evaluator_result_sort_field.py
new file mode 100644
index 0000000000..e7b3b829e9
--- /dev/null
+++ b/sdks/python/types/evaluator_result_sort_field.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+EvaluatorResultSortField = typing.Union[typing.Literal["created_at", "-created_at", "value"], typing.Any]
diff --git a/sdks/python/types/evaluator_results_page.py b/sdks/python/types/evaluator_results_page.py
new file mode 100644
index 0000000000..a8db6ff474
--- /dev/null
+++ b/sdks/python/types/evaluator_results_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .evaluator_result import EvaluatorResult
+from .pagination_data import PaginationData
+
+
+class EvaluatorResultsPage(UniversalBaseModel):
+ data: typing.List[EvaluatorResult]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/executed_action.py b/sdks/python/types/executed_action.py
new file mode 100644
index 0000000000..374ec2edec
--- /dev/null
+++ b/sdks/python/types/executed_action.py
@@ -0,0 +1,57 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .llm_call_info import LlmCallInfo
+
+
+class ExecutedAction(UniversalBaseModel):
+ """
+ Information about an action that was executed.
+ """
+
+ action_name: str = pydantic.Field()
+ """
+ The name of the action that was executed.
+ """
+
+ action_params: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ The parameters for the action.
+ """
+
+ return_value: typing.Optional[typing.Any] = pydantic.Field(default=None)
+ """
+ The value returned by the action.
+ """
+
+ llm_calls: typing.Optional[typing.List[LlmCallInfo]] = pydantic.Field(default=None)
+ """
+ Information about the LLM calls made by the action.
+ """
+
+ started_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timestamp for when the action started.
+ """
+
+ finished_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Timestamp for when the action finished.
+ """
+
+ duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ How long the action took to execute, in seconds.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_context.py b/sdks/python/types/experiment_context.py
new file mode 100644
index 0000000000..2669dd0a30
--- /dev/null
+++ b/sdks/python/types/experiment_context.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentContext(UniversalBaseModel):
+ """
+ Experiment context accepted by ingest endpoints.
+ """
+
+ experiment_id: str = pydantic.Field()
+ """
+ Name of an existing Experiment entity.
+ """
+
+ test_case_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional producer-supplied test case id.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_filter.py b/sdks/python/types/experiment_filter.py
new file mode 100644
index 0000000000..34e0baa3b6
--- /dev/null
+++ b/sdks/python/types/experiment_filter.py
@@ -0,0 +1,67 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+
+
+class ExperimentFilter(UniversalBaseModel):
+ """
+ Filter for listing Experiments.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by name.
+ """
+
+ experiment_group_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by owning group id.
+ """
+
+ agent_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by agent name.
+ """
+
+ agent_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by agent version.
+ """
+
+ dataset_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by dataset name.
+ """
+
+ dataset_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by dataset version.
+ """
+
+ created_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter experiments by the principal that created them.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter experiments by creation timestamp; supports `$gte` and `$lte` for ranges.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter experiments by last-updated timestamp; supports `$gte` and `$lte` for ranges.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_group_filter.py b/sdks/python/types/experiment_group_filter.py
new file mode 100644
index 0000000000..4f31c9c3ff
--- /dev/null
+++ b/sdks/python/types/experiment_group_filter.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentGroupFilter(UniversalBaseModel):
+ """
+ Filter for listing ExperimentGroups.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter groups by name.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_group_request.py b/sdks/python/types/experiment_group_request.py
new file mode 100644
index 0000000000..169c01b8e0
--- /dev/null
+++ b/sdks/python/types/experiment_group_request.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentGroupRequest(UniversalBaseModel):
+ """
+ Request body for creating an ExperimentGroup.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Workspace-unique group name.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Human-readable purpose of the group.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_group_response.py b/sdks/python/types/experiment_group_response.py
new file mode 100644
index 0000000000..6f3642dd98
--- /dev/null
+++ b/sdks/python/types/experiment_group_response.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentGroupResponse(UniversalBaseModel):
+ """
+ ExperimentGroup as served by the API.
+ """
+
+ id: str
+ name: str
+ workspace: str
+ description: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_group_responses_page.py b/sdks/python/types/experiment_group_responses_page.py
new file mode 100644
index 0000000000..fcb3e460fd
--- /dev/null
+++ b/sdks/python/types/experiment_group_responses_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .experiment_group_response import ExperimentGroupResponse
+from .pagination_data import PaginationData
+
+
+class ExperimentGroupResponsesPage(UniversalBaseModel):
+ data: typing.List[ExperimentGroupResponse]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_request.py b/sdks/python/types/experiment_request.py
new file mode 100644
index 0000000000..548801db4d
--- /dev/null
+++ b/sdks/python/types/experiment_request.py
@@ -0,0 +1,71 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentRequest(UniversalBaseModel):
+ """
+ Request body for creating an Experiment.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Producer-supplied, workspace-unique experiment id.
+ """
+
+ experiment_group_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity id of the owning ExperimentGroup; optional. Soft reference, not validated.
+ """
+
+ agent_name: str = pydantic.Field()
+ """
+ Name of the agent under test.
+ """
+
+ agent_version: str = pydantic.Field()
+ """
+ Version of the agent under test.
+ """
+
+ dataset_name: str = pydantic.Field()
+ """
+ Producer-supplied dataset name.
+ """
+
+ dataset_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Producer-supplied dataset version.
+ """
+
+ source_link: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional URL for the source experiment.
+ """
+
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Free-form producer metadata.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Human-readable description.
+ """
+
+ summary: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Human-authored summary of results.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_response.py b/sdks/python/types/experiment_response.py
new file mode 100644
index 0000000000..cb484f4565
--- /dev/null
+++ b/sdks/python/types/experiment_response.py
@@ -0,0 +1,56 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .evaluator_aggregate import EvaluatorAggregate
+
+
+class ExperimentResponse(UniversalBaseModel):
+ """
+ Experiment as served by the API, including ClickHouse-hydrated rollups.
+ """
+
+ id: str
+ name: str
+ workspace: str
+ experiment_group_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity id of the owning ExperimentGroup; null when ungrouped. Soft reference, not validated.
+ """
+
+ agent_name: str
+ agent_version: str
+ dataset_name: str
+ dataset_version: typing.Optional[str] = None
+ source_link: typing.Optional[str] = None
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = None
+ description: typing.Optional[str] = None
+ summary: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ evaluator_names: typing.Optional[typing.List[str]] = None
+ model_names: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Distinct model names observed across ingested sessions for this experiment.
+ """
+
+ aggregate_scores: typing.Optional[typing.Dict[str, EvaluatorAggregate]] = None
+ run_count: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of distinct ingested experiment sessions; one session is treated as one run.
+ """
+
+ cost_usd: typing.Optional[EvaluatorAggregate] = None
+ latency_ms: typing.Optional[EvaluatorAggregate] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_responses_page.py b/sdks/python/types/experiment_responses_page.py
new file mode 100644
index 0000000000..7d25fbc995
--- /dev/null
+++ b/sdks/python/types/experiment_responses_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .experiment_response import ExperimentResponse
+from .pagination_data import PaginationData
+
+
+class ExperimentResponsesPage(UniversalBaseModel):
+ data: typing.List[ExperimentResponse]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_session_filter.py b/sdks/python/types/experiment_session_filter.py
new file mode 100644
index 0000000000..5ff7976206
--- /dev/null
+++ b/sdks/python/types/experiment_session_filter.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ExperimentSessionFilter(UniversalBaseModel):
+ """
+ Filter for listing ExperimentSessions.
+ """
+
+ test_case_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by producer-supplied test case id.
+ """
+
+ status: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span status (success, error, cancelled, unknown).
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_session_response.py b/sdks/python/types/experiment_session_response.py
new file mode 100644
index 0000000000..7b79779e1e
--- /dev/null
+++ b/sdks/python/types/experiment_session_response.py
@@ -0,0 +1,75 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .span_status import SpanStatus
+
+
+class ExperimentSessionResponse(UniversalBaseModel):
+ """
+ One ingested session of an Experiment — a single test case execution.
+
+ Hydrated from ClickHouse at read time by joining ``experiment_sessions`` with
+ the session's root span (for status, input, tokens, cost) and
+ ``evaluator_results`` (for per-evaluator session-mean scores).
+ """
+
+ workspace: str
+ experiment_name: str
+ session_id: str
+ test_case_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Producer-supplied test case identifier; null when the producer did not set one.
+ """
+
+ trace_id: str
+ root_span_id: str
+ started_at: dt.datetime
+ ended_at: typing.Optional[dt.datetime] = None
+ latency_ms: typing.Optional[float] = None
+ status: SpanStatus = pydantic.Field()
+ """
+ Root-span status: success, error, cancelled, or unknown.
+ """
+
+ input: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Root-span input text (the query).
+ """
+
+ input_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Sum of input tokens across this session's spans.
+ """
+
+ output_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Sum of output tokens across this session's spans.
+ """
+
+ cached_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Sum of cached tokens across this session's spans.
+ """
+
+ cost_total_usd: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Sum of cost across this session's spans.
+ """
+
+ evaluator_scores: typing.Optional[typing.Dict[str, float]] = pydantic.Field(default=None)
+ """
+ Per-evaluator session-mean score. Includes NUMERIC and BOOLEAN evaluator results only; text/categorical results are omitted.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/experiment_session_responses_page.py b/sdks/python/types/experiment_session_responses_page.py
new file mode 100644
index 0000000000..1b12c03f0c
--- /dev/null
+++ b/sdks/python/types/experiment_session_responses_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .experiment_session_response import ExperimentSessionResponse
+from .pagination_data import PaginationData
+
+
+class ExperimentSessionResponsesPage(UniversalBaseModel):
+ data: typing.List[ExperimentSessionResponse]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fact_checking_rail_config.py b/sdks/python/types/fact_checking_rail_config.py
new file mode 100644
index 0000000000..faa42c7215
--- /dev/null
+++ b/sdks/python/types/fact_checking_rail_config.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class FactCheckingRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the fact-checking rail.
+ """
+
+ parameters: typing.Optional[typing.Dict[str, typing.Any]] = None
+ fallback_to_self_check: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to fall back to self-check if another method fail.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/feedback_annotation.py b/sdks/python/types/feedback_annotation.py
new file mode 100644
index 0000000000..52ca2fa235
--- /dev/null
+++ b/sdks/python/types/feedback_annotation.py
@@ -0,0 +1,39 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .feedback_annotation_value import FeedbackAnnotationValue
+
+
+class FeedbackAnnotation(UniversalBaseModel):
+ """
+ Thumbs-up / thumbs-down feedback on a span or session.
+ """
+
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to, or omitted for session-level annotations.
+ """
+
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ value: FeedbackAnnotationValue = pydantic.Field()
+ """
+ Sentiment of the feedback.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/feedback_annotation_input.py b/sdks/python/types/feedback_annotation_input.py
new file mode 100644
index 0000000000..26f136e45a
--- /dev/null
+++ b/sdks/python/types/feedback_annotation_input.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .feedback_annotation_input_value import FeedbackAnnotationInputValue
+
+
+class FeedbackAnnotationInput(UniversalBaseModel):
+ """
+ Thumbs-up / thumbs-down feedback on a span or session.
+ """
+
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to. Omit to annotate the whole session instead of a specific span.
+ """
+
+ session_id: str = pydantic.Field()
+ """
+ Id of the session this annotation belongs to. Always required.
+ """
+
+ value: FeedbackAnnotationInputValue = pydantic.Field()
+ """
+ Sentiment of the feedback.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/feedback_annotation_input_value.py b/sdks/python/types/feedback_annotation_input_value.py
new file mode 100644
index 0000000000..65bbb76405
--- /dev/null
+++ b/sdks/python/types/feedback_annotation_input_value.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FeedbackAnnotationInputValue = typing.Union[typing.Literal["positive", "negative"], typing.Any]
diff --git a/sdks/python/types/feedback_annotation_value.py b/sdks/python/types/feedback_annotation_value.py
new file mode 100644
index 0000000000..369e816fc5
--- /dev/null
+++ b/sdks/python/types/feedback_annotation_value.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FeedbackAnnotationValue = typing.Union[typing.Literal["positive", "negative"], typing.Any]
diff --git a/sdks/python/types/fiddler_guardrails.py b/sdks/python/types/fiddler_guardrails.py
new file mode 100644
index 0000000000..6a121e9b8a
--- /dev/null
+++ b/sdks/python/types/fiddler_guardrails.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class FiddlerGuardrails(UniversalBaseModel):
+ """
+ Configuration for Fiddler Guardrails.
+ """
+
+ fiddler_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The global endpoint for Fiddler Guardrails requests.
+ """
+
+ safety_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Fiddler Guardrails safety detection threshold.
+ """
+
+ faithfulness_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Fiddler Guardrails faithfulness detection threshold.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/file_storage_type.py b/sdks/python/types/file_storage_type.py
new file mode 100644
index 0000000000..16eb5f43a3
--- /dev/null
+++ b/sdks/python/types/file_storage_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FileStorageType = typing.Union[typing.Literal["fileset"], typing.Any]
diff --git a/sdks/python/types/fileset_file_output.py b/sdks/python/types/fileset_file_output.py
new file mode 100644
index 0000000000..5509ae472e
--- /dev/null
+++ b/sdks/python/types/fileset_file_output.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .cache_status import CacheStatus
+
+
+class FilesetFileOutput(UniversalBaseModel):
+ file_ref: str
+ file_url: str
+ path: str
+ size: int
+ cache_status: typing.Optional[CacheStatus] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_filter.py b/sdks/python/types/fileset_filter.py
new file mode 100644
index 0000000000..e38d4456b7
--- /dev/null
+++ b/sdks/python/types/fileset_filter.py
@@ -0,0 +1,56 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .fileset_filter_description import FilesetFilterDescription
+from .fileset_filter_name import FilesetFilterName
+from .fileset_purpose import FilesetPurpose
+from .storage_config_type import StorageConfigType
+
+
+class FilesetFilter(UniversalBaseModel):
+ """
+ Filter schema for listing filesets.
+ """
+
+ name: typing.Optional[FilesetFilterName] = pydantic.Field(default=None)
+ """
+ Filter by fileset name.
+ """
+
+ description: typing.Optional[FilesetFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by fileset description.
+ """
+
+ purpose: typing.Optional[FilesetPurpose] = pydantic.Field(default=None)
+ """
+ Filter by the purpose of the fileset (e.g., 'dataset', 'generic').
+ """
+
+ storage_type: typing.Optional[StorageConfigType] = pydantic.Field(default=None)
+ """
+ Filter by the storage backend type (e.g., 'local', 'ngc').
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by creation date. Supports '$gte' (on or after) and '$lte' (on or before) datetime filters.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by update date. Supports '$gte' (on or after) and '$lte' (on or before) datetime filters.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_filter_description.py b/sdks/python/types/fileset_filter_description.py
new file mode 100644
index 0000000000..83f7079e96
--- /dev/null
+++ b/sdks/python/types/fileset_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+FilesetFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/fileset_filter_name.py b/sdks/python/types/fileset_filter_name.py
new file mode 100644
index 0000000000..505c08769d
--- /dev/null
+++ b/sdks/python/types/fileset_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+FilesetFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/fileset_metadata_input.py b/sdks/python/types/fileset_metadata_input.py
new file mode 100644
index 0000000000..3b81457fc3
--- /dev/null
+++ b/sdks/python/types/fileset_metadata_input.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .dataset_metadata_content import DatasetMetadataContent
+from .model_metadata_content import ModelMetadataContent
+
+
+class FilesetMetadataInput(UniversalBaseModel):
+ """
+ Tagged metadata container - the key indicates the type.
+
+ Example:
+ metadata = FilesetMetadata(
+ dataset=DatasetMetadataContent(
+ schema={"columns": ["id", "name"]},
+ )
+ )
+ """
+
+ dataset: typing.Optional[DatasetMetadataContent] = None
+ model: typing.Optional[ModelMetadataContent] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_metadata_output.py b/sdks/python/types/fileset_metadata_output.py
new file mode 100644
index 0000000000..22d483578f
--- /dev/null
+++ b/sdks/python/types/fileset_metadata_output.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .dataset_metadata_content import DatasetMetadataContent
+from .model_metadata_content import ModelMetadataContent
+
+
+class FilesetMetadataOutput(UniversalBaseModel):
+ """
+ Tagged metadata container - the key indicates the type.
+
+ Example:
+ metadata = FilesetMetadata(
+ dataset=DatasetMetadataContent(
+ schema={"columns": ["id", "name"]},
+ )
+ )
+ """
+
+ dataset: typing.Optional[DatasetMetadataContent] = None
+ model: typing.Optional[ModelMetadataContent] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_output.py b/sdks/python/types/fileset_output.py
new file mode 100644
index 0000000000..29cbc27f11
--- /dev/null
+++ b/sdks/python/types/fileset_output.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .fileset_metadata_output import FilesetMetadataOutput
+from .fileset_output_storage import FilesetOutputStorage
+from .fileset_purpose import FilesetPurpose
+
+
+class FilesetOutput(UniversalBaseModel):
+ """
+ Response DTO for fileset operations.
+ """
+
+ id: str
+ name: str
+ workspace: str
+ description: str
+ purpose: FilesetPurpose
+ storage: FilesetOutputStorage
+ metadata: FilesetMetadataOutput
+ custom_fields: typing.Dict[str, typing.Any]
+ project: str
+ created_at: str
+ updated_at: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_output_storage.py b/sdks/python/types/fileset_output_storage.py
new file mode 100644
index 0000000000..26fd85dd18
--- /dev/null
+++ b/sdks/python/types/fileset_output_storage.py
@@ -0,0 +1,101 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .huggingface_storage_config_repo_type import HuggingfaceStorageConfigRepoType
+from .ngc_storage_config_target_type import NgcStorageConfigTargetType
+from .s3storage_config_signature_version import S3StorageConfigSignatureVersion
+from .secret_ref import SecretRef
+
+
+class FilesetOutputStorage_Local(UniversalBaseModel):
+ type: typing.Literal["local"] = "local"
+ read_chunk_size: typing.Optional[int] = None
+ path: str
+ write_buffer_size: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class FilesetOutputStorage_Ngc(UniversalBaseModel):
+ type: typing.Literal["ngc"] = "ngc"
+ read_chunk_size: typing.Optional[int] = None
+ org: str
+ team: str
+ target: str
+ target_type: typing.Optional[NgcStorageConfigTargetType] = None
+ version: typing.Optional[str] = None
+ original_version: typing.Optional[str] = None
+ api_key_secret: SecretRef
+ host: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class FilesetOutputStorage_Huggingface(UniversalBaseModel):
+ type: typing.Literal["huggingface"] = "huggingface"
+ read_chunk_size: typing.Optional[int] = None
+ repo_id: str
+ repo_type: typing.Optional[HuggingfaceStorageConfigRepoType] = None
+ revision: typing.Optional[str] = None
+ original_revision: typing.Optional[str] = None
+ token_secret: typing.Optional[SecretRef] = None
+ endpoint: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class FilesetOutputStorage_S3(UniversalBaseModel):
+ type: typing.Literal["s3"] = "s3"
+ read_chunk_size: typing.Optional[int] = None
+ bucket: str
+ prefix: typing.Optional[str] = None
+ region: typing.Optional[str] = None
+ endpoint_url: typing.Optional[str] = None
+ use_sdk_auth: typing.Optional[bool] = None
+ access_key_id_secret: typing.Optional[SecretRef] = None
+ secret_access_key_secret: typing.Optional[SecretRef] = None
+ signature_version: typing.Optional[S3StorageConfigSignatureVersion] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+FilesetOutputStorage = typing_extensions.Annotated[
+ typing.Union[
+ FilesetOutputStorage_Local, FilesetOutputStorage_Ngc, FilesetOutputStorage_Huggingface, FilesetOutputStorage_S3
+ ],
+ pydantic.Field(discriminator="type"),
+]
diff --git a/sdks/python/types/fileset_outputs_page.py b/sdks/python/types/fileset_outputs_page.py
new file mode 100644
index 0000000000..7f6d7efa7e
--- /dev/null
+++ b/sdks/python/types/fileset_outputs_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .fileset_output import FilesetOutput
+from .pagination_data import PaginationData
+
+
+class FilesetOutputsPage(UniversalBaseModel):
+ data: typing.List[FilesetOutput]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/fileset_purpose.py b/sdks/python/types/fileset_purpose.py
new file mode 100644
index 0000000000..257557f5f7
--- /dev/null
+++ b/sdks/python/types/fileset_purpose.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FilesetPurpose = typing.Union[typing.Literal["dataset", "generic", "model"], typing.Any]
diff --git a/sdks/python/types/finetuning_type.py b/sdks/python/types/finetuning_type.py
new file mode 100644
index 0000000000..32ad68930f
--- /dev/null
+++ b/sdks/python/types/finetuning_type.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FinetuningType = typing.Union[
+ typing.Literal[
+ "lora_merged",
+ "all_weights",
+ "last_layer",
+ "top_layers",
+ "gradual_unfreezing",
+ "bias_only",
+ "attention_only",
+ "lora",
+ "qlora",
+ "adalora",
+ "dora",
+ "lora_plus",
+ "prompt_tuning",
+ "prefix_tuning",
+ "p_tuning",
+ "p_tuning_v2",
+ "soft_prompt",
+ "ppo",
+ "dpo",
+ "cdpo",
+ "ipo",
+ "orpo",
+ "kto",
+ "rrhf",
+ "grpo",
+ ],
+ typing.Any,
+]
diff --git a/sdks/python/types/finetuning_type_filter.py b/sdks/python/types/finetuning_type_filter.py
new file mode 100644
index 0000000000..929bdf204a
--- /dev/null
+++ b/sdks/python/types/finetuning_type_filter.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .finetuning_type import FinetuningType
+
+
+class FinetuningTypeFilter(UniversalBaseModel):
+ """
+ Filter for PEFT-related properties.
+ """
+
+ finetuning_type: typing.Optional[FinetuningType] = pydantic.Field(default=None)
+ """
+ Filter models with adapters with this fine-tuning type.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/float_filter.py b/sdks/python/types/float_filter.py
new file mode 100644
index 0000000000..47e44a20f7
--- /dev/null
+++ b/sdks/python/types/float_filter.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class FloatFilter(UniversalBaseModel):
+ gte: typing_extensions.Annotated[
+ typing.Optional[float],
+ FieldMetadata(alias="$gte"),
+ pydantic.Field(alias="$gte", description="Filter for results greater than or equal to this value."),
+ ] = None
+ lte: typing_extensions.Annotated[
+ typing.Optional[float],
+ FieldMetadata(alias="$lte"),
+ pydantic.Field(alias="$lte", description="Filter for results less than or equal to this value."),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/function.py b/sdks/python/types/function.py
new file mode 100644
index 0000000000..e78c7469ef
--- /dev/null
+++ b/sdks/python/types/function.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Function(UniversalBaseModel):
+ """
+ Function definition for tool calls.
+ """
+
+ arguments: str = pydantic.Field()
+ """
+ The arguments to call the function with, as generated by the model in JSON format.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the function to call.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/function_call.py b/sdks/python/types/function_call.py
new file mode 100644
index 0000000000..dd1661ab8d
--- /dev/null
+++ b/sdks/python/types/function_call.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class FunctionCall(UniversalBaseModel):
+ """
+ Function call information.
+ """
+
+ arguments: str = pydantic.Field()
+ """
+ The arguments to call the function with, as generated by the model in JSON format.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the function to call.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/g_li_ner_detection.py b/sdks/python/types/g_li_ner_detection.py
new file mode 100644
index 0000000000..f5a6680988
--- /dev/null
+++ b/sdks/python/types/g_li_ner_detection.py
@@ -0,0 +1,62 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .g_li_ner_detection_options import GLiNerDetectionOptions
+
+
+class GLiNerDetection(UniversalBaseModel):
+ """
+ Configuration for GLiNER PII detection.
+ """
+
+ server_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The endpoint for the GLiNER detection server.
+ """
+
+ threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Confidence threshold for entity detection (0.0 to 1.0).
+ """
+
+ chunk_length: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Length of text chunks for processing.
+ """
+
+ overlap: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Overlap between chunks.
+ """
+
+ flat_ner: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to use flat NER mode. Setting to False allows for nested entities.
+ """
+
+ input: typing.Optional[GLiNerDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the user input.
+ """
+
+ output: typing.Optional[GLiNerDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the bot output.
+ """
+
+ retrieval: typing.Optional[GLiNerDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on retrieved relevant chunks.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/g_li_ner_detection_options.py b/sdks/python/types/g_li_ner_detection_options.py
new file mode 100644
index 0000000000..6f6160cc9a
--- /dev/null
+++ b/sdks/python/types/g_li_ner_detection_options.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class GLiNerDetectionOptions(UniversalBaseModel):
+ """
+ Configuration options for GLiNER.
+ """
+
+ entities: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of entity labels to detect (e.g., 'email', 'phone_number', 'ssn').
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generation_log.py b/sdks/python/types/generation_log.py
new file mode 100644
index 0000000000..85f6e7dca7
--- /dev/null
+++ b/sdks/python/types/generation_log.py
@@ -0,0 +1,49 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .activated_rail import ActivatedRail
+from .generation_stats import GenerationStats
+from .llm_call_info import LlmCallInfo
+
+
+class GenerationLog(UniversalBaseModel):
+ """
+ Contains additional logging information associated with a generation call.
+ """
+
+ activated_rails: typing.Optional[typing.List[ActivatedRail]] = pydantic.Field(default=None)
+ """
+ The list of rails that were activated during generation.
+ """
+
+ stats: typing.Optional[GenerationStats] = pydantic.Field(default=None)
+ """
+ General stats about the generation process.
+ """
+
+ llm_calls: typing.Optional[typing.List[LlmCallInfo]] = pydantic.Field(default=None)
+ """
+ The list of LLM calls that have been made to fulfill the generation request.
+ """
+
+ internal_events: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ The complete sequence of internal events generated.
+ """
+
+ colang_history: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The Colang history associated with the generation.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generation_log_options.py b/sdks/python/types/generation_log_options.py
new file mode 100644
index 0000000000..5963ced09b
--- /dev/null
+++ b/sdks/python/types/generation_log_options.py
@@ -0,0 +1,46 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class GenerationLogOptions(UniversalBaseModel):
+ """
+ Options for what should be included in the generation log.
+ """
+
+ activated_rails: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Include detailed information about the rails that were activated during generation.
+ """
+
+ llm_calls: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Include information about all the LLM calls that were made. This includes: prompt, completion, token usage, raw response, etc.
+ """
+
+ internal_events: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Include the array of internal generated events.
+ """
+
+ colang_history: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Include the history of the conversation in Colang format.
+ """
+
+ stats: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Include generation statistics — rail durations, LLM call counts, and token usage.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generation_options.py b/sdks/python/types/generation_options.py
new file mode 100644
index 0000000000..15e56313aa
--- /dev/null
+++ b/sdks/python/types/generation_options.py
@@ -0,0 +1,53 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .generation_log_options import GenerationLogOptions
+from .generation_options_output_vars import GenerationOptionsOutputVars
+from .generation_rails_options import GenerationRailsOptions
+
+
+class GenerationOptions(UniversalBaseModel):
+ """
+ A set of options that should be applied during a generation.
+
+ The GenerationOptions control various things such as what rails are enabled,
+ additional parameters for the main LLM, whether the rails should be enforced or
+ ran in parallel, what to be included in the generation log, etc.
+ """
+
+ rails: typing.Optional[GenerationRailsOptions] = pydantic.Field(default=None)
+ """
+ Options for which rails should be applied for the generation. By default, all rails are enabled.
+ """
+
+ llm_params: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Additional parameters that should be used for the LLM call
+ """
+
+ llm_output: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the response should also include any custom LLM output.
+ """
+
+ output_vars: typing.Optional[GenerationOptionsOutputVars] = pydantic.Field(default=None)
+ """
+ Whether additional context information should be returned. When True is specified, the whole context is returned. Otherwise, a list of key names can be specified.
+ """
+
+ log: typing.Optional[GenerationLogOptions] = pydantic.Field(default=None)
+ """
+ Options about what to include in the log. By default, nothing is included.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generation_options_output_vars.py b/sdks/python/types/generation_options_output_vars.py
new file mode 100644
index 0000000000..db181dc322
--- /dev/null
+++ b/sdks/python/types/generation_options_output_vars.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GenerationOptionsOutputVars = typing.Union[bool, typing.List[str]]
diff --git a/sdks/python/types/generation_rails_options.py b/sdks/python/types/generation_rails_options.py
new file mode 100644
index 0000000000..2e88dffba2
--- /dev/null
+++ b/sdks/python/types/generation_rails_options.py
@@ -0,0 +1,44 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .generation_rails_options_input import GenerationRailsOptionsInput
+from .generation_rails_options_output import GenerationRailsOptionsOutput
+from .generation_rails_options_retrieval import GenerationRailsOptionsRetrieval
+
+
+class GenerationRailsOptions(UniversalBaseModel):
+ """
+ Options for what rails should be used during the generation.
+ """
+
+ input: typing.Optional[GenerationRailsOptionsInput] = pydantic.Field(default=None)
+ """
+ Whether the input rails are enabled or not. If a list of names is specified, then only the specified input rails will be applied.
+ """
+
+ output: typing.Optional[GenerationRailsOptionsOutput] = pydantic.Field(default=None)
+ """
+ Whether the output rails are enabled or not. If a list of names is specified, then only the specified output rails will be applied.
+ """
+
+ retrieval: typing.Optional[GenerationRailsOptionsRetrieval] = pydantic.Field(default=None)
+ """
+ Whether the retrieval rails are enabled or not. If a list of names is specified, then only the specified retrieval rails will be applied.
+ """
+
+ dialog: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the dialog rails are enabled or not.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generation_rails_options_input.py b/sdks/python/types/generation_rails_options_input.py
new file mode 100644
index 0000000000..bf7ca4b9c3
--- /dev/null
+++ b/sdks/python/types/generation_rails_options_input.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GenerationRailsOptionsInput = typing.Union[bool, typing.List[str]]
diff --git a/sdks/python/types/generation_rails_options_output.py b/sdks/python/types/generation_rails_options_output.py
new file mode 100644
index 0000000000..f2f6774f6a
--- /dev/null
+++ b/sdks/python/types/generation_rails_options_output.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GenerationRailsOptionsOutput = typing.Union[bool, typing.List[str]]
diff --git a/sdks/python/types/generation_rails_options_retrieval.py b/sdks/python/types/generation_rails_options_retrieval.py
new file mode 100644
index 0000000000..e6aa9c6f38
--- /dev/null
+++ b/sdks/python/types/generation_rails_options_retrieval.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GenerationRailsOptionsRetrieval = typing.Union[bool, typing.List[str]]
diff --git a/sdks/python/types/generation_stats.py b/sdks/python/types/generation_stats.py
new file mode 100644
index 0000000000..4be46cf6c5
--- /dev/null
+++ b/sdks/python/types/generation_stats.py
@@ -0,0 +1,71 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class GenerationStats(UniversalBaseModel):
+ """
+ General stats about the generation.
+ """
+
+ input_rails_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The time in seconds spent in processing the input rails.
+ """
+
+ dialog_rails_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The time in seconds spent in processing the dialog rails.
+ """
+
+ generation_rails_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The time in seconds spent in generation rails.
+ """
+
+ output_rails_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The time in seconds spent in processing the output rails.
+ """
+
+ total_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The total time in seconds.
+ """
+
+ llm_calls_duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The time in seconds spent in LLM calls.
+ """
+
+ llm_calls_count: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The number of LLM calls in total.
+ """
+
+ llm_calls_total_prompt_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The total number of prompt tokens.
+ """
+
+ llm_calls_total_completion_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The total number of completion tokens.
+ """
+
+ llm_calls_total_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The total number of tokens.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/generic_sort_field.py b/sdks/python/types/generic_sort_field.py
new file mode 100644
index 0000000000..26e99486ee
--- /dev/null
+++ b/sdks/python/types/generic_sort_field.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+GenericSortField = typing.Union[typing.Literal["created_at", "-created_at", "name"], typing.Any]
diff --git a/sdks/python/types/gpu_execution_provider_input.py b/sdks/python/types/gpu_execution_provider_input.py
new file mode 100644
index 0000000000..135c5de633
--- /dev/null
+++ b/sdks/python/types/gpu_execution_provider_input.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class GpuExecutionProviderInput(UniversalBaseModel):
+ """
+ GPU-based execution provider.
+
+ Provides configuration for running jobs on GPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for GPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/gpu_execution_provider_output.py b/sdks/python/types/gpu_execution_provider_output.py
new file mode 100644
index 0000000000..44e2c75034
--- /dev/null
+++ b/sdks/python/types/gpu_execution_provider_output.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class GpuExecutionProviderOutput(UniversalBaseModel):
+ """
+ GPU-based execution provider.
+
+ Provides configuration for running jobs on GPU resources with
+ resource requests and limits.
+ """
+
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for GPU execution.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrail_check_response.py b/sdks/python/types/guardrail_check_response.py
new file mode 100644
index 0000000000..1eaa816aeb
--- /dev/null
+++ b/sdks/python/types/guardrail_check_response.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .guardrails_data_output import GuardrailsDataOutput
+from .rail_status import RailStatus
+from .status_enum import StatusEnum
+
+
+class GuardrailCheckResponse(UniversalBaseModel):
+ status: StatusEnum = pydantic.Field()
+ """
+ Overall status indicating if all rails passed or if any failed.
+ """
+
+ rails_status: typing.Dict[str, RailStatus] = pydantic.Field()
+ """
+ Dictionary mapping each rail to its status.
+ """
+
+ guardrails_data: typing.Optional[GuardrailsDataOutput] = pydantic.Field(default=None)
+ """
+ Additional data related to guardrails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrail_config.py b/sdks/python/types/guardrail_config.py
new file mode 100644
index 0000000000..c073a04813
--- /dev/null
+++ b/sdks/python/types/guardrail_config.py
@@ -0,0 +1,63 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .guardrail_config_data import GuardrailConfigData
+
+
+class GuardrailConfig(UniversalBaseModel):
+ """
+ A guardrail configuration entity.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity name within the workspace
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the project associated with this entity.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Description of the guardrail config
+ """
+
+ data: typing.Optional[GuardrailConfigData] = pydantic.Field(default=None)
+ """
+ Guardrail configuration data
+ """
+
+ id: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ created_by: typing.Optional[str] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ updated_by: typing.Optional[str] = None
+ entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Alias for id for backwards compatibility.
+ """
+
+ parent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent entity ID for nested entities.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrail_config_data.py b/sdks/python/types/guardrail_config_data.py
new file mode 100644
index 0000000000..59a5454e66
--- /dev/null
+++ b/sdks/python/types/guardrail_config_data.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2
+from .rails_config_output import RailsConfigOutput
+
+
+class GuardrailConfigData(RailsConfigOutput):
+ """
+ Guardrail configuration data
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrail_config_filter.py b/sdks/python/types/guardrail_config_filter.py
new file mode 100644
index 0000000000..be89aa56dd
--- /dev/null
+++ b/sdks/python/types/guardrail_config_filter.py
@@ -0,0 +1,49 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .guardrail_config_filter_description import GuardrailConfigFilterDescription
+from .guardrail_config_filter_name import GuardrailConfigFilterName
+
+
+class GuardrailConfigFilter(UniversalBaseModel):
+ """
+ Filter schema for listing guardrail configs.
+ """
+
+ name: typing.Optional[GuardrailConfigFilterName] = pydantic.Field(default=None)
+ """
+ Filter by config name.
+ """
+
+ description: typing.Optional[GuardrailConfigFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by config description.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project name.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by creation date. Supports '$gte' (on or after) and '$lte' (on or before) datetime filters.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by update date. Supports '$gte' (on or after) and '$lte' (on or before) datetime filters.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrail_config_filter_description.py b/sdks/python/types/guardrail_config_filter_description.py
new file mode 100644
index 0000000000..2dc370d38a
--- /dev/null
+++ b/sdks/python/types/guardrail_config_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+GuardrailConfigFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/guardrail_config_filter_name.py b/sdks/python/types/guardrail_config_filter_name.py
new file mode 100644
index 0000000000..cdd0d8b9ee
--- /dev/null
+++ b/sdks/python/types/guardrail_config_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+GuardrailConfigFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/guardrail_configs_page.py b/sdks/python/types/guardrail_configs_page.py
new file mode 100644
index 0000000000..bad59ca31c
--- /dev/null
+++ b/sdks/python/types/guardrail_configs_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .guardrail_config import GuardrailConfig
+from .pagination_data import PaginationData
+
+
+class GuardrailConfigsPage(UniversalBaseModel):
+ data: typing.List[GuardrailConfig]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrails_ai_rail_config.py b/sdks/python/types/guardrails_ai_rail_config.py
new file mode 100644
index 0000000000..c813bcfe4f
--- /dev/null
+++ b/sdks/python/types/guardrails_ai_rail_config.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .guardrails_ai_validator_config import GuardrailsAiValidatorConfig
+
+
+class GuardrailsAiRailConfig(UniversalBaseModel):
+ """
+ Configuration data for Guardrails AI integration.
+ """
+
+ validators: typing.Optional[typing.List[GuardrailsAiValidatorConfig]] = pydantic.Field(default=None)
+ """
+ List of Guardrails AI validators to apply. Each validator can have its own parameters and metadata.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrails_ai_validator_config.py b/sdks/python/types/guardrails_ai_validator_config.py
new file mode 100644
index 0000000000..4f3503f226
--- /dev/null
+++ b/sdks/python/types/guardrails_ai_validator_config.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class GuardrailsAiValidatorConfig(UniversalBaseModel):
+ """
+ Configuration for a single Guardrails AI validator.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Unique identifier or import path for the Guardrails AI validator (e.g., 'toxic_language', 'pii', 'regex_match', or 'guardrails/competitor_check').
+ """
+
+ parameters: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Parameters to pass to the validator during initialization (e.g., threshold, regex pattern).
+ """
+
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Metadata to pass to the validator during validation (e.g., valid_topics, context).
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrails_data_input.py b/sdks/python/types/guardrails_data_input.py
new file mode 100644
index 0000000000..682a7e79b2
--- /dev/null
+++ b/sdks/python/types/guardrails_data_input.py
@@ -0,0 +1,59 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .generation_options import GenerationOptions
+from .guardrails_data_input_config import GuardrailsDataInputConfig
+
+
+class GuardrailsDataInput(UniversalBaseModel):
+ config: typing.Optional[GuardrailsDataInputConfig] = pydantic.Field(default=None)
+ """
+ The id of the configuration or its dict representation to be used.
+ """
+
+ config_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The id of the configuration to be used.
+ """
+
+ config_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of configuration ids to be used. If set, the configurations will be combined.
+ """
+
+ return_choice: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If set, guardrails data will be included as a JSON in the choices array.
+ """
+
+ context: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Additional context data to be added to the conversation.
+ """
+
+ stream: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If set, partial message deltas will be sent, like in ChatGPT. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message.
+ """
+
+ options: typing.Optional[GenerationOptions] = pydantic.Field(default=None)
+ """
+ Additional options for controlling the generation.
+ """
+
+ state: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ A state object that should be used to continue the interaction.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/guardrails_data_input_config.py b/sdks/python/types/guardrails_data_input_config.py
new file mode 100644
index 0000000000..cbd3655792
--- /dev/null
+++ b/sdks/python/types/guardrails_data_input_config.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .rails_config_input import RailsConfigInput
+
+GuardrailsDataInputConfig = typing.Union[str, RailsConfigInput]
diff --git a/sdks/python/types/guardrails_data_output.py b/sdks/python/types/guardrails_data_output.py
new file mode 100644
index 0000000000..1bbb4e6417
--- /dev/null
+++ b/sdks/python/types/guardrails_data_output.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .generation_log import GenerationLog
+
+
+class GuardrailsDataOutput(UniversalBaseModel):
+ llm_output: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Contains any additional output coming from the LLM.
+ """
+
+ config_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of configuration ids that were used.
+ """
+
+ output_data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ The output data, i.e. a dict with the values corresponding to the `output_vars`.
+ """
+
+ log: typing.Optional[GenerationLog] = pydantic.Field(default=None)
+ """
+ Additional logging information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/http_validation_error.py b/sdks/python/types/http_validation_error.py
new file mode 100644
index 0000000000..70a0f5f172
--- /dev/null
+++ b/sdks/python/types/http_validation_error.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .validation_error import ValidationError
+
+
+class HttpValidationError(UniversalBaseModel):
+ detail: typing.Optional[typing.List[ValidationError]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/huggingface_storage_config.py b/sdks/python/types/huggingface_storage_config.py
new file mode 100644
index 0000000000..0cbac4b731
--- /dev/null
+++ b/sdks/python/types/huggingface_storage_config.py
@@ -0,0 +1,54 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .huggingface_storage_config_repo_type import HuggingfaceStorageConfigRepoType
+from .secret_ref import SecretRef
+
+
+class HuggingfaceStorageConfig(UniversalBaseModel):
+ read_chunk_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Chunk size in bytes for reading/streaming files. Larger chunks reduce async overhead but increase memory per concurrent download. Default: 1MB.
+ """
+
+ repo_id: str = pydantic.Field()
+ """
+ Huggingface repository ID (e.g., 'meta-llama/Llama-2-7b')
+ """
+
+ repo_type: typing.Optional[HuggingfaceStorageConfigRepoType] = pydantic.Field(default=None)
+ """
+ Type of Huggingface repository: 'model', 'dataset', or 'space'
+ """
+
+ revision: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Branch, tag, or commit SHA. Defaults to 'main'
+ """
+
+ original_revision: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The original revision requested by the user before resolution (e.g., 'main'). The 'revision' field contains the resolved commit SHA.
+ """
+
+ token_secret: typing.Optional[SecretRef] = pydantic.Field(default=None)
+ """
+ Huggingface API `token` secret name for private repositories
+ """
+
+ endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Huggingface Hub endpoint URL. Use for self-hosted instances.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/huggingface_storage_config_repo_type.py b/sdks/python/types/huggingface_storage_config_repo_type.py
new file mode 100644
index 0000000000..3d9af9c65a
--- /dev/null
+++ b/sdks/python/types/huggingface_storage_config_repo_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+HuggingfaceStorageConfigRepoType = typing.Union[typing.Literal["model", "dataset", "space"], typing.Any]
diff --git a/sdks/python/types/image_pull_secret.py b/sdks/python/types/image_pull_secret.py
new file mode 100644
index 0000000000..03240e9ab2
--- /dev/null
+++ b/sdks/python/types/image_pull_secret.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ImagePullSecret(UniversalBaseModel):
+ """
+ Kubernetes image pull secret reference.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Kubernetes Secret name for pulling images
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/image_url.py b/sdks/python/types/image_url.py
new file mode 100644
index 0000000000..17cf0a3717
--- /dev/null
+++ b/sdks/python/types/image_url.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .image_url_detail import ImageUrlDetail
+
+
+class ImageUrl(UniversalBaseModel):
+ """
+ Image URL for vision requests.
+ """
+
+ url: str = pydantic.Field()
+ """
+ Either a URL of the image or the base64 encoded image data.
+ """
+
+ detail: typing.Optional[ImageUrlDetail] = pydantic.Field(default=None)
+ """
+ Specifies the detail level of the image.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/image_url_detail.py b/sdks/python/types/image_url_detail.py
new file mode 100644
index 0000000000..8513edd8cc
--- /dev/null
+++ b/sdks/python/types/image_url_detail.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ImageUrlDetail = typing.Union[typing.Literal["auto", "low", "high"], typing.Any]
diff --git a/sdks/python/types/inference_params.py b/sdks/python/types/inference_params.py
new file mode 100644
index 0000000000..cc36d7091f
--- /dev/null
+++ b/sdks/python/types/inference_params.py
@@ -0,0 +1,48 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class InferenceParams(UniversalBaseModel):
+ """
+ Parameters for model inference. Extra fields can be supplied for additional options applied to the inference request directly. Fields not supported by the model may cause inference errors during evaluation.
+ """
+
+ model: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Model identifier
+ """
+
+ temperature: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Float value between 0 and 1. temp of 0 indicates greedy decoding, where the token with highest prob is chosen. Temperature can't be set to 0.0 currently
+ """
+
+ max_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Max tokens to generate
+ """
+
+ max_completion_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Max tokens to generate
+ """
+
+ top_p: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ Float value between 0 and 1; limits to the top tokens within a certain probability. top_p=0 means the model will only consider the single most likely token for the next prediction
+ """
+
+ stop: typing.Optional[typing.List[str]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/ingest_response.py b/sdks/python/types/ingest_response.py
new file mode 100644
index 0000000000..caebd8a01f
--- /dev/null
+++ b/sdks/python/types/ingest_response.py
@@ -0,0 +1,19 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class IngestResponse(UniversalBaseModel):
+ errors: typing.Optional[typing.List[str]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/injection_detection.py b/sdks/python/types/injection_detection.py
new file mode 100644
index 0000000000..63a6375b16
--- /dev/null
+++ b/sdks/python/types/injection_detection.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class InjectionDetection(UniversalBaseModel):
+ injections: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of injection types to detect. Options are 'sqli', 'template', 'code', 'xss'.Currently, only SQL injection, template injection, code injection, and markdown cross-site scripting are supported. Custom rules can be added, provided they are in the `yara_path` and have a `.yara` file extension.
+ """
+
+ action: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Action to take. Options are 'reject' to offer a rejection message, 'omit' to mask the offending content, and 'sanitize' to pass the content as-is in the safest way. These options are listed in descending order of relative safety. 'sanitize' is not implemented at this time.
+ """
+
+ yara_rules: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Dictionary mapping rule names to YARA rule strings. If provided, these rules will be used instead of loading rules from yara_path. Each rule should be a valid YARA rule string.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/input_rails.py b/sdks/python/types/input_rails.py
new file mode 100644
index 0000000000..c51795c581
--- /dev/null
+++ b/sdks/python/types/input_rails.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class InputRails(UniversalBaseModel):
+ """
+ Configuration of input rails.
+ """
+
+ parallel: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, the input rails are executed in parallel.
+ """
+
+ flows: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all the flows that implement input rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/instruction.py b/sdks/python/types/instruction.py
new file mode 100644
index 0000000000..0d266d8c66
--- /dev/null
+++ b/sdks/python/types/instruction.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Instruction(UniversalBaseModel):
+ """
+ Configuration for instructions in natural language that should be passed to the LLM.
+ """
+
+ type: str
+ content: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/jailbreak_detection_config.py b/sdks/python/types/jailbreak_detection_config.py
new file mode 100644
index 0000000000..6e08a1a9ac
--- /dev/null
+++ b/sdks/python/types/jailbreak_detection_config.py
@@ -0,0 +1,68 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class JailbreakDetectionConfig(UniversalBaseModel):
+ """
+ Configuration data for jailbreak detection.
+ """
+
+ server_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The endpoint for the jailbreak detection heuristics/model container.
+ """
+
+ length_per_perplexity_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The length/perplexity threshold.
+ """
+
+ prefix_suffix_perplexity_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The prefix/suffix perplexity threshold.
+ """
+
+ nim_base_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Base URL for jailbreak detection model. Example: http://localhost:8000/v1
+ """
+
+ nim_server_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Classification path uri. Defaults to 'classify' for NemoGuard JailbreakDetect.
+ """
+
+ api_key: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Secret String with API key for use in Jailbreak requests. Takes precedence over api_key_env_var
+ """
+
+ api_key_env_var: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Environment variable containing API key for jailbreak detection model
+ """
+
+ nim_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ DEPRECATED: Use nim_base_url instead
+ """
+
+ nim_port: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ DEPRECATED: Include port in nim_base_url instead
+ """
+
+ embedding: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/job_execution_profile_config.py b/sdks/python/types/job_execution_profile_config.py
new file mode 100644
index 0000000000..a11fde09e8
--- /dev/null
+++ b/sdks/python/types/job_execution_profile_config.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class JobExecutionProfileConfig(UniversalBaseModel):
+ ttl_seconds_before_active: typing.Optional[int] = None
+ ttl_seconds_active: typing.Optional[int] = None
+ ttl_seconds_after_finished: typing.Optional[int] = None
+ cleanup_completed_jobs_immediately: typing.Optional[bool] = None
+ launcher_tool_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Path to the jobs launcher tool
+ """
+
+ env: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Optional env vars applied to all jobs (e.g. HOME=/tmp). Keys must not conflict with platform-reserved names. Job steps may override these variables.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/k8s_nim_operator_config.py b/sdks/python/types/k8s_nim_operator_config.py
new file mode 100644
index 0000000000..a4ee08ca47
--- /dev/null
+++ b/sdks/python/types/k8s_nim_operator_config.py
@@ -0,0 +1,44 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class K8SNimOperatorConfig(UniversalBaseModel):
+ """
+ Kubernetes configuration for NIM deployment via k8s-nim-operator.
+
+ These fields provide typed access to commonly-used NIMService Spec fields
+ and are applied before override_config in the compilation precedence.
+ """
+
+ resources: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Kubernetes resource requirements including requests and limits. Example: {'requests': {'cpu': '2', 'memory': '8Gi'}, 'limits': {'memory': '16Gi'}}
+ """
+
+ tolerations: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ Kubernetes tolerations for pod scheduling. Example: [{'key': 'nvidia.com/gpu', 'operator': 'Exists', 'effect': 'NoSchedule'}]
+ """
+
+ node_selector: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Kubernetes node selector for pod placement. Example: {'node-type': 'gpu-node', 'zone': 'us-west1-a'}
+ """
+
+ startup_probe_grace_seconds: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Grace period in seconds for NIM startup. Determines how long Kubernetes will wait for the NIM to become ready before restarting it. Example: 600 (10 minutes). Must be a positive integer.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_empty_dir_volume.py b/sdks/python/types/kubernetes_empty_dir_volume.py
new file mode 100644
index 0000000000..0049ad44ef
--- /dev/null
+++ b/sdks/python/types/kubernetes_empty_dir_volume.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class KubernetesEmptyDirVolume(UniversalBaseModel):
+ """
+ Kubernetes EmptyDir Volume definition.
+ """
+
+ medium: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The medium of the emptyDir volume (e.g., 'Memory')
+ """
+
+ size_limit: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The size limit of the emptyDir volume (e.g., '1Gi')
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_job_execution_profile.py b/sdks/python/types/kubernetes_job_execution_profile.py
new file mode 100644
index 0000000000..72ebb8d0c1
--- /dev/null
+++ b/sdks/python/types/kubernetes_job_execution_profile.py
@@ -0,0 +1,39 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .kubernetes_job_execution_profile_config import KubernetesJobExecutionProfileConfig
+
+
+class KubernetesJobExecutionProfile(UniversalBaseModel):
+ """
+ Execution configuration for a Kubernetes Job.
+ This is used to define the executor type, provider, profile, and any additional configuration
+ required for the executor to run the job on Kubernetes
+ """
+
+ provider: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The compute provider for the executor, e.g., cpu, gpu
+ """
+
+ profile: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The profile name for the executor, e.g., high_priority_a100, low_priority, etc.
+ """
+
+ config: KubernetesJobExecutionProfileConfig = pydantic.Field()
+ """
+ Additional configuration for the kubernetes executor
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_job_execution_profile_config.py b/sdks/python/types/kubernetes_job_execution_profile_config.py
new file mode 100644
index 0000000000..1a6de401d7
--- /dev/null
+++ b/sdks/python/types/kubernetes_job_execution_profile_config.py
@@ -0,0 +1,109 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .image_pull_secret import ImagePullSecret
+from .kubernetes_job_storage_config import KubernetesJobStorageConfig
+from .kubernetes_object_metadata import KubernetesObjectMetadata
+
+
+class KubernetesJobExecutionProfileConfig(UniversalBaseModel):
+ """
+ Configuration for Kubernetes execution environment.
+ """
+
+ ttl_seconds_before_active: typing.Optional[int] = None
+ ttl_seconds_active: typing.Optional[int] = None
+ ttl_seconds_after_finished: typing.Optional[int] = None
+ cleanup_completed_jobs_immediately: typing.Optional[bool] = None
+ launcher_tool_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Path to the jobs launcher tool
+ """
+
+ env: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Optional env vars applied to all jobs (e.g. HOME=/tmp). Keys must not conflict with platform-reserved names. Job steps may override these variables.
+ """
+
+ namespace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Kubernetes namespace to submit the job to. If not set, it will be determined from the environment.
+ """
+
+ service_account_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Kubernetes service account name for job pods. Uses the Kubernetes default service account when set to 'default'.
+ """
+
+ tolerations: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ Tolerations for the Kubernetes job pods.
+ """
+
+ node_selector: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Node selector for the Kubernetes job pods.
+ """
+
+ affinity: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Affinity for the Kubernetes job pods.
+ """
+
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for the Kubernetes job pods.
+ """
+
+ pod_security_context: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Pod security context for the Kubernetes job pods.
+ """
+
+ image_pull_secrets: typing.Optional[typing.List[ImagePullSecret]] = pydantic.Field(default=None)
+ """
+ Image pull secrets for the Kubernetes job pods.
+ """
+
+ job_metadata: typing.Optional[KubernetesObjectMetadata] = pydantic.Field(default=None)
+ """
+ Metadata to add to each job object in the Kubernetes job.
+ """
+
+ pod_metadata: typing.Optional[KubernetesObjectMetadata] = pydantic.Field(default=None)
+ """
+ Metadata to add to each pod in the Kubernetes job.
+ """
+
+ storage: typing.Optional[KubernetesJobStorageConfig] = pydantic.Field(default=None)
+ """
+ Storage configuration for the Kubernetes job pods.
+ """
+
+ num_gpus: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of GPUs to request for the job
+ """
+
+ scheduler_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The scheduler name to use for the pod spec. When non-empty, this value is applied to the pod's schedulerName field, enabling custom schedulers such as KAI Scheduler. Empty string omits schedulerName so the cluster default scheduler is used.
+ """
+
+ launcher_image: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Container image that contains the jobs-launcher binary.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_job_storage_config.py b/sdks/python/types/kubernetes_job_storage_config.py
new file mode 100644
index 0000000000..bf3828343d
--- /dev/null
+++ b/sdks/python/types/kubernetes_job_storage_config.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .kubernetes_volume import KubernetesVolume
+from .kubernetes_volume_mount import KubernetesVolumeMount
+
+
+class KubernetesJobStorageConfig(UniversalBaseModel):
+ """
+ Configuration for persistent storage in Kubernetes jobs.
+ """
+
+ pvc_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Persistent Volume Claim Name to use for job storage.
+ """
+
+ volume_permissions_image: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Image used to set volume permissions
+ """
+
+ additional_volumes: typing.Optional[typing.List[KubernetesVolume]] = pydantic.Field(default=None)
+ """
+ Additional volumes to mount
+ """
+
+ additional_volume_mounts: typing.Optional[typing.List[KubernetesVolumeMount]] = pydantic.Field(default=None)
+ """
+ Additional volume mounts
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_object_metadata.py b/sdks/python/types/kubernetes_object_metadata.py
new file mode 100644
index 0000000000..08ce0470c7
--- /dev/null
+++ b/sdks/python/types/kubernetes_object_metadata.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class KubernetesObjectMetadata(UniversalBaseModel):
+ labels: typing.Optional[typing.Dict[str, str]] = None
+ annotations: typing.Optional[typing.Dict[str, str]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_persistent_volume_claim.py b/sdks/python/types/kubernetes_persistent_volume_claim.py
new file mode 100644
index 0000000000..a31cffda53
--- /dev/null
+++ b/sdks/python/types/kubernetes_persistent_volume_claim.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class KubernetesPersistentVolumeClaim(UniversalBaseModel):
+ """
+ Kubernetes Persistent Volume Claim definition.
+ """
+
+ claim_name: str = pydantic.Field()
+ """
+ Persistent Volume Claim Name
+ """
+
+ read_only: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the volume is mounted read-only
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_volume.py b/sdks/python/types/kubernetes_volume.py
new file mode 100644
index 0000000000..6d17493f94
--- /dev/null
+++ b/sdks/python/types/kubernetes_volume.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .kubernetes_empty_dir_volume import KubernetesEmptyDirVolume
+from .kubernetes_persistent_volume_claim import KubernetesPersistentVolumeClaim
+
+
+class KubernetesVolume(UniversalBaseModel):
+ """
+ Kubernetes Volume definition.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Volume Name
+ """
+
+ persistent_volume_claim: typing.Optional[KubernetesPersistentVolumeClaim] = pydantic.Field(default=None)
+ """
+ Persistent Volume Claim configuration
+ """
+
+ empty_dir: typing.Optional[KubernetesEmptyDirVolume] = pydantic.Field(default=None)
+ """
+ EmptyDir Volume configuration
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/kubernetes_volume_mount.py b/sdks/python/types/kubernetes_volume_mount.py
new file mode 100644
index 0000000000..1fa6db3ae9
--- /dev/null
+++ b/sdks/python/types/kubernetes_volume_mount.py
@@ -0,0 +1,41 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class KubernetesVolumeMount(UniversalBaseModel):
+ """
+ Kubernetes Volume Mount definition.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Volume Name
+ """
+
+ mount_path: str = pydantic.Field()
+ """
+ Mount Path in the container
+ """
+
+ sub_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Sub-path within the volume to mount
+ """
+
+ read_only: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the volume mount is read-only
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/label_annotation.py b/sdks/python/types/label_annotation.py
new file mode 100644
index 0000000000..09f8cbe388
--- /dev/null
+++ b/sdks/python/types/label_annotation.py
@@ -0,0 +1,50 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .label_annotation_value import LabelAnnotationValue
+from .label_annotation_value_type import LabelAnnotationValueType
+
+
+class LabelAnnotation(UniversalBaseModel):
+ """
+ Categorical or numeric label attached to a span or session.
+ """
+
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to, or omitted for session-level annotations.
+ """
+
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ value_type: LabelAnnotationValueType = pydantic.Field()
+ """
+ Whether `value` is a text label (`text`) or a number (`numeric`).
+ """
+
+ value: LabelAnnotationValue = pydantic.Field()
+ """
+ The label's value. A string when `value_type=text`, a number when `value_type=numeric`.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Name identifying what the label measures, when set.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/label_annotation_input.py b/sdks/python/types/label_annotation_input.py
new file mode 100644
index 0000000000..7ec205a54b
--- /dev/null
+++ b/sdks/python/types/label_annotation_input.py
@@ -0,0 +1,52 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .label_annotation_input_value import LabelAnnotationInputValue
+from .label_annotation_input_value_type import LabelAnnotationInputValueType
+
+
+class LabelAnnotationInput(UniversalBaseModel):
+ """
+ Categorical or numeric label attached to a span or session.
+
+ Use `value_type=text` for tag-style labels (e.g., `regression`, `needs-review`) and
+ `value_type=numeric` for scored labels (e.g., a 1-5 helpfulness rating). Numeric labels
+ must include a `name` to identify what the score measures.
+ """
+
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to. Omit to annotate the whole session instead of a specific span.
+ """
+
+ session_id: str = pydantic.Field()
+ """
+ Id of the session this annotation belongs to. Always required.
+ """
+
+ value_type: LabelAnnotationInputValueType = pydantic.Field()
+ """
+ Whether `value` should be interpreted as text (`text`) or a number (`numeric`).
+ """
+
+ value: LabelAnnotationInputValue = pydantic.Field()
+ """
+ The label's value. Must be a string when `value_type=text` and a number when `value_type=numeric`.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Name identifying what the label measures (e.g., `severity`, `helpfulness`). Optional for text labels; required for numeric labels.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/label_annotation_input_value.py b/sdks/python/types/label_annotation_input_value.py
new file mode 100644
index 0000000000..df3707de7d
--- /dev/null
+++ b/sdks/python/types/label_annotation_input_value.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+LabelAnnotationInputValue = typing.Union[str, float]
diff --git a/sdks/python/types/label_annotation_input_value_type.py b/sdks/python/types/label_annotation_input_value_type.py
new file mode 100644
index 0000000000..2459c80725
--- /dev/null
+++ b/sdks/python/types/label_annotation_input_value_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+LabelAnnotationInputValueType = typing.Union[typing.Literal["text", "numeric"], typing.Any]
diff --git a/sdks/python/types/label_annotation_value.py b/sdks/python/types/label_annotation_value.py
new file mode 100644
index 0000000000..c2ea0a7092
--- /dev/null
+++ b/sdks/python/types/label_annotation_value.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+LabelAnnotationValue = typing.Union[str, float]
diff --git a/sdks/python/types/label_annotation_value_type.py b/sdks/python/types/label_annotation_value_type.py
new file mode 100644
index 0000000000..d683712119
--- /dev/null
+++ b/sdks/python/types/label_annotation_value_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+LabelAnnotationValueType = typing.Union[typing.Literal["text", "numeric"], typing.Any]
diff --git a/sdks/python/types/linear_layer_spec.py b/sdks/python/types/linear_layer_spec.py
new file mode 100644
index 0000000000..3fc285c1c0
--- /dev/null
+++ b/sdks/python/types/linear_layer_spec.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class LinearLayerSpec(UniversalBaseModel):
+ """
+ Specification for a single linear layer in the model.
+ """
+
+ name: str = pydantic.Field()
+ """
+ Module name (e.g., 'model.layers.0.self_attn.q_proj')
+ """
+
+ in_features: int = pydantic.Field()
+ """
+ Input feature dimension
+ """
+
+ out_features: int = pydantic.Field()
+ """
+ Output feature dimension
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/list_fileset_files_response.py b/sdks/python/types/list_fileset_files_response.py
new file mode 100644
index 0000000000..0f4c10eb5a
--- /dev/null
+++ b/sdks/python/types/list_fileset_files_response.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .fileset_file_output import FilesetFileOutput
+
+
+class ListFilesetFilesResponse(UniversalBaseModel):
+ data: typing.List[FilesetFileOutput]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/llm_call_info.py b/sdks/python/types/llm_call_info.py
new file mode 100644
index 0000000000..7ebcda07c3
--- /dev/null
+++ b/sdks/python/types/llm_call_info.py
@@ -0,0 +1,77 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class LlmCallInfo(UniversalBaseModel):
+ task: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The internal task that made the call.
+ """
+
+ duration: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The duration in seconds.
+ """
+
+ total_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The total number of used tokens.
+ """
+
+ prompt_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The number of input tokens.
+ """
+
+ completion_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The number of output tokens.
+ """
+
+ started_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The timestamp for when the LLM call started.
+ """
+
+ finished_at: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The timestamp for when the LLM call finished.
+ """
+
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The unique prompt identifier.
+ """
+
+ prompt: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The prompt that was used for the LLM call.
+ """
+
+ completion: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The completion generated by the LLM.
+ """
+
+ raw_response: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ The raw response received from the LLM. May contain additional information, e.g. logprobs.
+ """
+
+ llm_model_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the model use for the LLM call.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/local_storage_config.py b/sdks/python/types/local_storage_config.py
new file mode 100644
index 0000000000..760ee63c48
--- /dev/null
+++ b/sdks/python/types/local_storage_config.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class LocalStorageConfig(UniversalBaseModel):
+ read_chunk_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Chunk size in bytes for reading/streaming files. Larger chunks reduce async overhead but increase memory per concurrent download. Default: 1MB.
+ """
+
+ path: str
+ write_buffer_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ How many bytes to buffer before flushing to disk
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/log_adapter_config.py b/sdks/python/types/log_adapter_config.py
new file mode 100644
index 0000000000..07ac9da473
--- /dev/null
+++ b/sdks/python/types/log_adapter_config.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class LogAdapterConfig(UniversalBaseModel):
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the adapter.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/lora.py b/sdks/python/types/lora.py
new file mode 100644
index 0000000000..2249b67eec
--- /dev/null
+++ b/sdks/python/types/lora.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Lora(UniversalBaseModel):
+ alpha: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Alpha scaling used for this adapter
+ """
+
+ rank: int = pydantic.Field()
+ """
+ LoRA Rank
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/mamba_config.py b/sdks/python/types/mamba_config.py
new file mode 100644
index 0000000000..9ff2cf0ea2
--- /dev/null
+++ b/sdks/python/types/mamba_config.py
@@ -0,0 +1,51 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MambaConfig(UniversalBaseModel):
+ """
+ Mamba/State Space Model configuration.
+ """
+
+ is_hybrid: bool = pydantic.Field()
+ """
+ Whether model is Mamba-Transformer hybrid
+ """
+
+ num_mamba_layers: int = pydantic.Field()
+ """
+ Number of Mamba/SSM layers
+ """
+
+ num_attention_layers: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of attention layers (for hybrids)
+ """
+
+ num_mlp_layers: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of standalone MLP layers (for interleaved architectures)
+ """
+
+ state_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ SSM state expansion factor (d_state)
+ """
+
+ conv_kernel: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Convolution kernel size for Mamba (d_conv)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/message_template.py b/sdks/python/types/message_template.py
new file mode 100644
index 0000000000..590cbdf148
--- /dev/null
+++ b/sdks/python/types/message_template.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MessageTemplate(UniversalBaseModel):
+ """
+ Template for a message structure.
+ """
+
+ type: str = pydantic.Field()
+ """
+ The type of message, e.g., 'assistant', 'user', 'system'.
+ """
+
+ content: str = pydantic.Field()
+ """
+ The content of the message.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/metadata_annotation.py b/sdks/python/types/metadata_annotation.py
new file mode 100644
index 0000000000..f9d106bc78
--- /dev/null
+++ b/sdks/python/types/metadata_annotation.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MetadataAnnotation(UniversalBaseModel):
+ """
+ Structured key/value metadata attached to a span or session.
+ """
+
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to, or omitted for session-level annotations.
+ """
+
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ metadata: typing.Dict[str, typing.Any] = pydantic.Field()
+ """
+ The metadata key/value pairs.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/metadata_annotation_input.py b/sdks/python/types/metadata_annotation_input.py
new file mode 100644
index 0000000000..0cf4aee87d
--- /dev/null
+++ b/sdks/python/types/metadata_annotation_input.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MetadataAnnotationInput(UniversalBaseModel):
+ """
+ Structured key/value metadata attached to a span or session.
+ """
+
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to. Omit to annotate the whole session instead of a specific span.
+ """
+
+ session_id: str = pydantic.Field()
+ """
+ Id of the session this annotation belongs to. Always required.
+ """
+
+ metadata: typing.Dict[str, typing.Any] = pydantic.Field()
+ """
+ Arbitrary key/value pairs. Must contain at least one entry.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/middleware_call.py b/sdks/python/types/middleware_call.py
new file mode 100644
index 0000000000..364342fc62
--- /dev/null
+++ b/sdks/python/types/middleware_call.py
@@ -0,0 +1,46 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MiddlewareCall(UniversalBaseModel):
+ """
+ One entry in a VirtualModel middleware pipeline.
+
+ Declares which plugin to invoke and how to resolve its configuration.
+ Exactly one of ``config`` (inline dict) or ``config_id`` (entity reference)
+ should be provided. ``config_type`` is always required regardless of which
+ is used — it is the discriminator that tells IGW (and the plugin) which
+ config schema applies.
+
+ Attributes:
+ name: The entry-point key of the plugin to invoke
+ (e.g. ``"nemo-switchyard"``). Must match the plugin's
+ ``nemo.inference_middleware`` entry-point key.
+ config_type: Always required. Maps to the ``entity_type`` of the plugin's
+ config ``NemoEntity`` subclass (e.g. ``"routellm_config"``). Used by
+ IGW to call :meth:`~NemoInferenceMiddleware.validate_middleware_config`
+ with the right discriminator, and by the plugin to dispatch to the
+ correct schema when it supports multiple config types.
+ config: Inline config dict. Mutually exclusive with ``config_id``.
+ config_id: ``"workspace/name"`` reference to a stored config entity.
+ Mutually exclusive with ``config``. IGW resolves this by calling
+ :meth:`~NemoInferenceMiddleware.get_middleware_config` on the plugin.
+ """
+
+ name: str
+ config_type: str
+ config: typing.Optional[typing.Dict[str, typing.Any]] = None
+ config_id: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/mo_e_config.py b/sdks/python/types/mo_e_config.py
new file mode 100644
index 0000000000..a23ad5282c
--- /dev/null
+++ b/sdks/python/types/mo_e_config.py
@@ -0,0 +1,46 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MoEConfig(UniversalBaseModel):
+ """
+ Mixture of Experts configuration.
+ """
+
+ num_experts: int = pydantic.Field()
+ """
+ Total number of routed experts (sharded by EP)
+ """
+
+ num_experts_per_tok: int = pydantic.Field()
+ """
+ Number of experts activated per token (top-k routing)
+ """
+
+ num_expert_layers: int = pydantic.Field()
+ """
+ Number of layers with MoE
+ """
+
+ expert_ffn_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ FFN size for experts (if different from main FFN)
+ """
+
+ num_shared_experts: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of shared experts (replicated, not sharded by EP)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model.py b/sdks/python/types/model.py
new file mode 100644
index 0000000000..257cc09ac8
--- /dev/null
+++ b/sdks/python/types/model.py
@@ -0,0 +1,48 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_cache_config import ModelCacheConfig
+from .model_mode import ModelMode
+from .model_parameters import ModelParameters
+
+
+class Model(UniversalBaseModel):
+ """
+ Configuration of a model used by the rails engine.
+
+ If using Inference Gateway, the `model` field should be a Model Entity reference ('workspace/model_name').
+ """
+
+ type: str
+ engine: str
+ model: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The model name. If using Inference Gateway, this should be the Model Entity reference ('workspace/model_name').
+ """
+
+ parameters: typing.Optional[ModelParameters] = pydantic.Field(default=None)
+ """
+ Additional parameters to configure how to interact with the model.
+ """
+
+ mode: typing.Optional[ModelMode] = pydantic.Field(default=None)
+ """
+ Whether the mode is 'text' completion or 'chat' completion. Allowed values are 'chat' or 'text'.
+ """
+
+ cache: typing.Optional[ModelCacheConfig] = pydantic.Field(default=None)
+ """
+ Cache configuration for this specific model (primarily used for content safety models)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_cache_config.py b/sdks/python/types/model_cache_config.py
new file mode 100644
index 0000000000..ac6275d2f9
--- /dev/null
+++ b/sdks/python/types/model_cache_config.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .cache_stats_config import CacheStatsConfig
+
+
+class ModelCacheConfig(UniversalBaseModel):
+ """
+ Configuration for model caching.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether caching is enabled (default: False - no caching)
+ """
+
+ maxsize: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Maximum number of entries in the cache per model
+ """
+
+ stats: typing.Optional[CacheStatsConfig] = pydantic.Field(default=None)
+ """
+ Configuration for cache statistics tracking and logging
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment.py b/sdks/python/types/model_deployment.py
new file mode 100644
index 0000000000..7e22c6fba5
--- /dev/null
+++ b/sdks/python/types/model_deployment.py
@@ -0,0 +1,98 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .auth_context import AuthContext
+from .model_deployment_status import ModelDeploymentStatus
+from .model_deployment_status_history_item import ModelDeploymentStatusHistoryItem
+
+
+class ModelDeployment(UniversalBaseModel):
+ """
+ ModelDeployment represents a deployed instance of a model with a specific configuration.
+ These objects are immutable with automatic versioning, except for status updates.
+
+ The unique identifier is the combination of workspace/name/entity_version.
+ """
+
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Unique identifier for the deployment
+ """
+
+ name: str = pydantic.Field()
+ """
+ Name of the entity. Name/workspace combo must be unique across all entities. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace of the entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URN of the project associated with this entity.
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of model entity creation
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of the last model entity update
+ """
+
+ entity_version: int = pydantic.Field()
+ """
+ Version of this deployment. Automatically managed.
+ """
+
+ config: str = pydantic.Field()
+ """
+ Reference to the ModelDeploymentConfig name
+ """
+
+ config_version: int = pydantic.Field()
+ """
+ Reference to the specific ModelDeploymentConfig version
+ """
+
+ status: typing.Optional[ModelDeploymentStatus] = pydantic.Field(default=None)
+ """
+ Current status of the deployment, populated by models controller
+ """
+
+ status_message: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Detailed status message, populated by models controller
+ """
+
+ status_history: typing.Optional[typing.List[ModelDeploymentStatusHistoryItem]] = pydantic.Field(default=None)
+ """
+ History of status changes, ordered chronologically (oldest first)
+ """
+
+ model_provider_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional reference to the auto-created ModelProvider workspace/name (format: workspace/name)
+ """
+
+ auth_context: typing.Optional[AuthContext] = pydantic.Field(default=None)
+ """
+ Auth context captured at deployment creation.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_config.py b/sdks/python/types/model_deployment_config.py
new file mode 100644
index 0000000000..b36cec196d
--- /dev/null
+++ b/sdks/python/types/model_deployment_config.py
@@ -0,0 +1,88 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .container_executor_config import ContainerExecutorConfig
+from .engine import Engine
+from .model_deployment_config_model_spec import ModelDeploymentConfigModelSpec
+
+
+class ModelDeploymentConfig(UniversalBaseModel):
+ """
+ ModelDeploymentConfig stores the configuration details for deploying a model.
+ These objects are immutable with automatic versioning.
+
+ The unique identifier is the combination of workspace/name/entity_version.
+ """
+
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Unique identifier for the deployment config
+ """
+
+ name: str = pydantic.Field()
+ """
+ Name of the entity. Name/workspace combo must be unique across all entities. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace of the entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URN of the project associated with this entity.
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of model entity creation
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of the last model entity update
+ """
+
+ entity_version: int = pydantic.Field()
+ """
+ Version of this deployment config. Automatically managed.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description of the deployment configuration
+ """
+
+ engine: Engine = pydantic.Field()
+ """
+ Inference engine selecting the compiler path (nim/vllm/generic)
+ """
+
+ model_spec: ModelDeploymentConfigModelSpec = pydantic.Field()
+ """
+ What model to serve and how -- independent of the executor it runs on
+ """
+
+ executor_config: ContainerExecutorConfig = pydantic.Field()
+ """
+ Compute + container settings for the executor the deployment runs on
+ """
+
+ model_entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional reference to the base model entity ID for this deployment
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_config_filter.py b/sdks/python/types/model_deployment_config_filter.py
new file mode 100644
index 0000000000..b0e7d4e48f
--- /dev/null
+++ b/sdks/python/types/model_deployment_config_filter.py
@@ -0,0 +1,59 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .model_deployment_config_filter_description import ModelDeploymentConfigFilterDescription
+from .model_deployment_config_filter_name import ModelDeploymentConfigFilterName
+
+
+class ModelDeploymentConfigFilter(UniversalBaseModel):
+ """
+ Filter for ModelDeploymentConfig queries.
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by workspace.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project URN.
+ """
+
+ model_entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by associated model entity ID.
+ """
+
+ name: typing.Optional[ModelDeploymentConfigFilterName] = pydantic.Field(default=None)
+ """
+ Filter by config name.
+ """
+
+ description: typing.Optional[ModelDeploymentConfigFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by description.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by creation date.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by update date.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_config_filter_description.py b/sdks/python/types/model_deployment_config_filter_description.py
new file mode 100644
index 0000000000..12f5fcd05e
--- /dev/null
+++ b/sdks/python/types/model_deployment_config_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelDeploymentConfigFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_deployment_config_filter_name.py b/sdks/python/types/model_deployment_config_filter_name.py
new file mode 100644
index 0000000000..4da9206e53
--- /dev/null
+++ b/sdks/python/types/model_deployment_config_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelDeploymentConfigFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_deployment_config_model_spec.py b/sdks/python/types/model_deployment_config_model_spec.py
new file mode 100644
index 0000000000..a44d1c27aa
--- /dev/null
+++ b/sdks/python/types/model_deployment_config_model_spec.py
@@ -0,0 +1,61 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_type import ModelType
+from .tool_call_config import ToolCallConfig
+
+
+class ModelDeploymentConfigModelSpec(UniversalBaseModel):
+ """
+ What model to serve and how -- independent of the executor it runs on.
+
+ Executor-invariant facts about the model. The compiler resolves the weight
+ source per engine; serving fields override the model entity spec when set.
+ """
+
+ model_type: typing.Optional[ModelType] = pydantic.Field(default=None)
+ """
+ Type of model being deployed
+ """
+
+ model_namespace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Model repository namespace - organization/user namespace as it exists in repo_id.
+ """
+
+ model_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Model name - model repository name for model weights.
+ """
+
+ model_revision: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Model revision (branch, tag, or commit). If not specified, parsed from model_name @revision suffix or defaults to 'main'
+ """
+
+ chat_template: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Jinja2 chat template string for the model. Overrides the chat_template from ModelEntity.spec if both are set. Used by the engine to format chat completions.
+ """
+
+ tool_call_config: typing.Optional[ToolCallConfig] = pydantic.Field(default=None)
+ """
+ Tool calling configuration for the deployment. Overrides tool_call_config from ModelEntity.spec if both are set. Controls how the model handles function/tool calling.
+ """
+
+ lora_enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable LoRA support
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_configs_page.py b/sdks/python/types/model_deployment_configs_page.py
new file mode 100644
index 0000000000..84b1213aff
--- /dev/null
+++ b/sdks/python/types/model_deployment_configs_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_deployment_config import ModelDeploymentConfig
+from .pagination_data import PaginationData
+
+
+class ModelDeploymentConfigsPage(UniversalBaseModel):
+ data: typing.List[ModelDeploymentConfig]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_filter.py b/sdks/python/types/model_deployment_filter.py
new file mode 100644
index 0000000000..00d78fec47
--- /dev/null
+++ b/sdks/python/types/model_deployment_filter.py
@@ -0,0 +1,71 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .model_deployment_filter_config import ModelDeploymentFilterConfig
+from .model_deployment_filter_name import ModelDeploymentFilterName
+from .model_deployment_filter_status_message import ModelDeploymentFilterStatusMessage
+from .model_deployment_status import ModelDeploymentStatus
+
+
+class ModelDeploymentFilter(UniversalBaseModel):
+ """
+ Filter for ModelDeployment queries.
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by workspace.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project URN.
+ """
+
+ status: typing.Optional[ModelDeploymentStatus] = pydantic.Field(default=None)
+ """
+ Filter by status.
+ """
+
+ config: typing.Optional[ModelDeploymentFilterConfig] = pydantic.Field(default=None)
+ """
+ Filter by config name.
+ """
+
+ model_provider_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by model provider ID.
+ """
+
+ name: typing.Optional[ModelDeploymentFilterName] = pydantic.Field(default=None)
+ """
+ Filter by deployment name.
+ """
+
+ status_message: typing.Optional[ModelDeploymentFilterStatusMessage] = pydantic.Field(default=None)
+ """
+ Filter by status message.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by creation date.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by update date.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployment_filter_config.py b/sdks/python/types/model_deployment_filter_config.py
new file mode 100644
index 0000000000..f03cbeb7fb
--- /dev/null
+++ b/sdks/python/types/model_deployment_filter_config.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelDeploymentFilterConfig = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_deployment_filter_name.py b/sdks/python/types/model_deployment_filter_name.py
new file mode 100644
index 0000000000..b68ea7dad9
--- /dev/null
+++ b/sdks/python/types/model_deployment_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelDeploymentFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_deployment_filter_status_message.py b/sdks/python/types/model_deployment_filter_status_message.py
new file mode 100644
index 0000000000..252ff097df
--- /dev/null
+++ b/sdks/python/types/model_deployment_filter_status_message.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelDeploymentFilterStatusMessage = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_deployment_status.py b/sdks/python/types/model_deployment_status.py
new file mode 100644
index 0000000000..9abaa3f2c9
--- /dev/null
+++ b/sdks/python/types/model_deployment_status.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelDeploymentStatus = typing.Union[
+ typing.Literal["UNKNOWN", "CREATED", "PENDING", "READY", "ERROR", "DELETING", "DELETED", "LOST"], typing.Any
+]
diff --git a/sdks/python/types/model_deployment_status_history_item.py b/sdks/python/types/model_deployment_status_history_item.py
new file mode 100644
index 0000000000..d3aab5211a
--- /dev/null
+++ b/sdks/python/types/model_deployment_status_history_item.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_deployment_status import ModelDeploymentStatus
+
+
+class ModelDeploymentStatusHistoryItem(UniversalBaseModel):
+ """
+ Record of a status change in ModelDeployment history.
+ """
+
+ timestamp: dt.datetime = pydantic.Field()
+ """
+ When this status was recorded
+ """
+
+ status: ModelDeploymentStatus = pydantic.Field()
+ """
+ The status at this point in time
+ """
+
+ status_message: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Status message
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_deployments_page.py b/sdks/python/types/model_deployments_page.py
new file mode 100644
index 0000000000..5c74b954f0
--- /dev/null
+++ b/sdks/python/types/model_deployments_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_deployment import ModelDeployment
+from .pagination_data import PaginationData
+
+
+class ModelDeploymentsPage(UniversalBaseModel):
+ data: typing.List[ModelDeployment]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_entity.py b/sdks/python/types/model_entity.py
new file mode 100644
index 0000000000..e78d761f0b
--- /dev/null
+++ b/sdks/python/types/model_entity.py
@@ -0,0 +1,124 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .adapter import Adapter
+from .api_endpoint_data import ApiEndpointData
+from .backend_format import BackendFormat
+from .finetuning_type import FinetuningType
+from .model_spec import ModelSpec
+from .prompt_data import PromptData
+
+
+class ModelEntity(UniversalBaseModel):
+ """
+ Model Entity represents a versioned model registered within the platform.
+ Uses EntityBase for entity store compatibility.
+ """
+
+ id: str = pydantic.Field()
+ """
+ Autogenerated id
+ """
+
+ name: str = pydantic.Field()
+ """
+ Name of the entity. Name/workspace combo must be unique across all entities. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace of the entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URN of the project associated with this model entity.
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of model entity creation
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of the last model entity update
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description of the model.
+ """
+
+ spec: typing.Optional[ModelSpec] = pydantic.Field(default=None)
+ """
+ Detailed specification for the model
+ """
+
+ finetuning_type: typing.Optional[FinetuningType] = pydantic.Field(default=None)
+ """
+ Set for full weight finetuned models
+ """
+
+ fileset: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ A set of checkpoint files, configs, and other auxiliary info associated with this model - expected format {workspace}/{fileset_name}
+ """
+
+ trust_remote_code: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to trust remote code to load this model checkpoint.
+ """
+
+ base_model: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Link to another model which is used as a base for the current model
+ """
+
+ api_endpoint: typing.Optional[ApiEndpointData] = pydantic.Field(default=None)
+ """
+ Data about the inference endpoint for this model
+ """
+
+ backend_format: typing.Optional[BackendFormat] = pydantic.Field(default=None)
+ """
+ Inference API wire format expected by the backend. If unset, inference routing treats the model as OPENAI_CHAT.
+ """
+
+ adapters: typing.Optional[typing.List[Adapter]] = pydantic.Field(default=None)
+ """
+ Adapters that have been created against this model
+ """
+
+ prompt: typing.Optional[PromptData] = pydantic.Field(default=None)
+ """
+ Configuration for prompt engineering
+ """
+
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Custom fields for additional metadata
+ """
+
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Ownership information for the model
+ """
+
+ model_providers: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ List of ModelProvider workspace/name resource names that provide inference for this Model Entity
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_entity_filter.py b/sdks/python/types/model_entity_filter.py
new file mode 100644
index 0000000000..e3cb3f7d0a
--- /dev/null
+++ b/sdks/python/types/model_entity_filter.py
@@ -0,0 +1,82 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .model_entity_filter_adapters import ModelEntityFilterAdapters
+from .model_entity_filter_base_model import ModelEntityFilterBaseModel
+from .model_entity_filter_description import ModelEntityFilterDescription
+from .model_entity_filter_finetuning_type import ModelEntityFilterFinetuningType
+from .model_entity_filter_name import ModelEntityFilterName
+
+
+class ModelEntityFilter(UniversalBaseModel):
+ """
+ Filter for Model Entity queries.
+ """
+
+ name: typing.Optional[ModelEntityFilterName] = pydantic.Field(default=None)
+ """
+ Filter by name.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project name.
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by workspace id.
+ """
+
+ base_model: typing.Optional[ModelEntityFilterBaseModel] = pydantic.Field(default=None)
+ """
+ Filter by base model: true = has a base model, false = no base model, { name: string } or string = match base model name.
+ """
+
+ adapters: typing.Optional[ModelEntityFilterAdapters] = pydantic.Field(default=None)
+ """
+ Filter models with Parameter Efficient Fine-tuning Adapters.
+ """
+
+ finetuning_type: typing.Optional[ModelEntityFilterFinetuningType] = pydantic.Field(default=None)
+ """
+ Filter models that have been perviously finetuned.
+ """
+
+ prompt: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Filter models with prompt engineering data.
+ """
+
+ lora_enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Filter models by whether their deployment config has LoRA enabled.
+ """
+
+ description: typing.Optional[ModelEntityFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by description.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter entities based on creation date.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter entities based on update date.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_entity_filter_adapters.py b/sdks/python/types/model_entity_filter_adapters.py
new file mode 100644
index 0000000000..3b79531572
--- /dev/null
+++ b/sdks/python/types/model_entity_filter_adapters.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .finetuning_type_filter import FinetuningTypeFilter
+
+ModelEntityFilterAdapters = typing.Union[FinetuningTypeFilter, bool]
diff --git a/sdks/python/types/model_entity_filter_base_model.py b/sdks/python/types/model_entity_filter_base_model.py
new file mode 100644
index 0000000000..036de6f09a
--- /dev/null
+++ b/sdks/python/types/model_entity_filter_base_model.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .base_model_filter import BaseModelFilter
+
+ModelEntityFilterBaseModel = typing.Union[BaseModelFilter, bool, str]
diff --git a/sdks/python/types/model_entity_filter_description.py b/sdks/python/types/model_entity_filter_description.py
new file mode 100644
index 0000000000..67df47c56a
--- /dev/null
+++ b/sdks/python/types/model_entity_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelEntityFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_entity_filter_finetuning_type.py b/sdks/python/types/model_entity_filter_finetuning_type.py
new file mode 100644
index 0000000000..e91a454b2e
--- /dev/null
+++ b/sdks/python/types/model_entity_filter_finetuning_type.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .finetuning_type import FinetuningType
+
+ModelEntityFilterFinetuningType = typing.Union[FinetuningType, bool]
diff --git a/sdks/python/types/model_entity_filter_name.py b/sdks/python/types/model_entity_filter_name.py
new file mode 100644
index 0000000000..f10881a84c
--- /dev/null
+++ b/sdks/python/types/model_entity_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelEntityFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_entity_sort_field.py b/sdks/python/types/model_entity_sort_field.py
new file mode 100644
index 0000000000..27a58a0f45
--- /dev/null
+++ b/sdks/python/types/model_entity_sort_field.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelEntitySortField = typing.Union[
+ typing.Literal["name", "created_at", "-created_at", "updated_at", "-updated_at"], typing.Any
+]
diff --git a/sdks/python/types/model_entitys_page.py b/sdks/python/types/model_entitys_page.py
new file mode 100644
index 0000000000..6590de0fd8
--- /dev/null
+++ b/sdks/python/types/model_entitys_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_entity import ModelEntity
+from .pagination_data import PaginationData
+
+
+class ModelEntitysPage(UniversalBaseModel):
+ data: typing.List[ModelEntity]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_metadata_content.py b/sdks/python/types/model_metadata_content.py
new file mode 100644
index 0000000000..cd1da2bb4d
--- /dev/null
+++ b/sdks/python/types/model_metadata_content.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .tool_calling_metadata_content import ToolCallingMetadataContent
+
+
+class ModelMetadataContent(UniversalBaseModel):
+ """
+ Content for model-type filesets.
+
+ Contains tool calling configuration that is merged into the ModelSpec
+ during checkpoint analysis.
+ """
+
+ tool_calling: typing.Optional[ToolCallingMetadataContent] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_mode.py b/sdks/python/types/model_mode.py
new file mode 100644
index 0000000000..c963252f82
--- /dev/null
+++ b/sdks/python/types/model_mode.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelMode = typing.Union[typing.Literal["chat", "text"], typing.Any]
diff --git a/sdks/python/types/model_parameters.py b/sdks/python/types/model_parameters.py
new file mode 100644
index 0000000000..fbd4ebb39b
--- /dev/null
+++ b/sdks/python/types/model_parameters.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ModelParameters(UniversalBaseModel):
+ """
+ Parameters for configuring how to interact with a model in a guardrails config.
+ """
+
+ base_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URL to use for inference with this model.
+ """
+
+ default_headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Custom HTTP headers to include in requests to this model. Each key-value pair represents a header name (key) and its default value (value). You can override the default value for a header by populating it in the request headers.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_provider.py b/sdks/python/types/model_provider.py
new file mode 100644
index 0000000000..70b916c060
--- /dev/null
+++ b/sdks/python/types/model_provider.py
@@ -0,0 +1,132 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .auth_context import AuthContext
+from .model_provider_status import ModelProviderStatus
+from .served_model_mapping import ServedModelMapping
+
+
+class ModelProvider(UniversalBaseModel):
+ """
+ A ModelProvider defines a reachable network endpoint that provides an inference
+ service for one or more Model Entities. Examples of Model Providers include
+ OpenAI, NIMs, Bedrock, NVIDIA Build, etc. A ModelProvider may be provisioned
+ automatically by Models Controller for ModelDeployments, or it may be provisioned
+ manually by an end user for an endpoint that does not have its lifecycle managed
+ by models service (like an external provider.)
+
+ The unique identifier for a ModelProvider is the combination of workspace/name.
+ """
+
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Unique identifier for the model provider
+ """
+
+ name: str = pydantic.Field()
+ """
+ Name of the entity. Name/workspace combo must be unique across all entities. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace of the entity. Allowed characters: letters (a-z, A-Z), digits (0-9), underscores, hyphens, and dots.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URN of the project associated with this entity.
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of model entity creation
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ The timestamp of the last model entity update
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description of the model provider
+ """
+
+ host_url: str = pydantic.Field()
+ """
+ The network endpoint URL for the model provider
+ """
+
+ api_key_secret_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Reference to the API key stored in Secrets service
+ """
+
+ served_models: typing.Optional[typing.List[ServedModelMapping]] = pydantic.Field(default=None)
+ """
+ List of models served by this provider with routing information for IGW
+ """
+
+ enabled_models: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Optional list of specific models to enable from this provider. If not set, all discovered models are enabled.
+ """
+
+ status: typing.Optional[ModelProviderStatus] = pydantic.Field(default=None)
+ """
+ Current status of the model provider, populated by models service
+ """
+
+ status_message: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Detailed status message, populated by models service
+ """
+
+ default_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Default body parameters for inference requests. Can be overridden by user requests.
+ """
+
+ default_extra_headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Default headers for inference requests. Can be overridden by user requests.
+ """
+
+ required_extra_body: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Required body parameters for inference requests. Cannot be overridden by user requests.
+ """
+
+ required_extra_headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Required headers for inference requests. Cannot be overridden by user requests.
+ """
+
+ model_deployment_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional reference to the ModelDeployment ID if this provider was auto-created for a deployment
+ """
+
+ auth_context: typing.Optional[AuthContext] = pydantic.Field(default=None)
+ """
+ Auth context captured at provider creation.
+ """
+
+ auth_header_format: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Jinja2 template string controlling how the API key secret is sent to the upstream. Must contain exactly one variable named `auth_secret`, which is substituted with the resolved secret value at request time. Example: `'X-Api-Key: {{ auth_secret }}'`. If not set, defaults to `'Authorization: Bearer {{ auth_secret }}'`.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_provider_filter.py b/sdks/python/types/model_provider_filter.py
new file mode 100644
index 0000000000..1d8000910a
--- /dev/null
+++ b/sdks/python/types/model_provider_filter.py
@@ -0,0 +1,71 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .model_provider_filter_description import ModelProviderFilterDescription
+from .model_provider_filter_host_url import ModelProviderFilterHostUrl
+from .model_provider_filter_name import ModelProviderFilterName
+from .model_provider_status import ModelProviderStatus
+
+
+class ModelProviderFilter(UniversalBaseModel):
+ """
+ Filter for ModelProvider queries.
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by workspace.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project URN.
+ """
+
+ status: typing.Optional[ModelProviderStatus] = pydantic.Field(default=None)
+ """
+ Filter by status.
+ """
+
+ model_deployment_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by associated deployment ID.
+ """
+
+ name: typing.Optional[ModelProviderFilterName] = pydantic.Field(default=None)
+ """
+ Filter by name.
+ """
+
+ description: typing.Optional[ModelProviderFilterDescription] = pydantic.Field(default=None)
+ """
+ Filter by description.
+ """
+
+ host_url: typing.Optional[ModelProviderFilterHostUrl] = pydantic.Field(default=None)
+ """
+ Filter by host URL.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by creation date.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by update date.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_provider_filter_description.py b/sdks/python/types/model_provider_filter_description.py
new file mode 100644
index 0000000000..96a9fa9886
--- /dev/null
+++ b/sdks/python/types/model_provider_filter_description.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelProviderFilterDescription = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_provider_filter_host_url.py b/sdks/python/types/model_provider_filter_host_url.py
new file mode 100644
index 0000000000..340585bc82
--- /dev/null
+++ b/sdks/python/types/model_provider_filter_host_url.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelProviderFilterHostUrl = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_provider_filter_name.py b/sdks/python/types/model_provider_filter_name.py
new file mode 100644
index 0000000000..fe4b59b157
--- /dev/null
+++ b/sdks/python/types/model_provider_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+ModelProviderFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/model_provider_sort.py b/sdks/python/types/model_provider_sort.py
new file mode 100644
index 0000000000..ed5e232d92
--- /dev/null
+++ b/sdks/python/types/model_provider_sort.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelProviderSort = typing.Union[
+ typing.Literal["name", "created_at", "-created_at", "updated_at", "-updated_at", "status"], typing.Any
+]
diff --git a/sdks/python/types/model_provider_status.py b/sdks/python/types/model_provider_status.py
new file mode 100644
index 0000000000..1a481d6c4c
--- /dev/null
+++ b/sdks/python/types/model_provider_status.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelProviderStatus = typing.Union[
+ typing.Literal["UNKNOWN", "CREATED", "PENDING", "READY", "ERROR", "DELETING", "DELETED", "LOST"], typing.Any
+]
diff --git a/sdks/python/types/model_providers_page.py b/sdks/python/types/model_providers_page.py
new file mode 100644
index 0000000000..90c7130401
--- /dev/null
+++ b/sdks/python/types/model_providers_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .model_provider import ModelProvider
+from .pagination_data import PaginationData
+
+
+class ModelProvidersPage(UniversalBaseModel):
+ data: typing.List[ModelProvider]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_spec.py b/sdks/python/types/model_spec.py
new file mode 100644
index 0000000000..2af5c63073
--- /dev/null
+++ b/sdks/python/types/model_spec.py
@@ -0,0 +1,146 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .linear_layer_spec import LinearLayerSpec
+from .mamba_config import MambaConfig
+from .mo_e_config import MoEConfig
+from .sliding_window_config import SlidingWindowConfig
+from .tool_call_config import ToolCallConfig
+
+
+class ModelSpec(UniversalBaseModel):
+ """
+ Detailed specification for a model.
+ """
+
+ context_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Context window size
+ """
+
+ num_virtual_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of virtual tokens for prompt tuning
+ """
+
+ is_chat: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether this is a chat model
+ """
+
+ is_embedding_model: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether this is an embedding model
+ """
+
+ checkpoint_model_name: str = pydantic.Field()
+ """
+ Checkpoint Model identifier or model path
+ """
+
+ family: str = pydantic.Field()
+ """
+ Model architecture family (e.g., 'llama', 'mixtral', 'gpt2')
+ """
+
+ num_layers: int = pydantic.Field()
+ """
+ Number of transformer layers
+ """
+
+ hidden_size: int = pydantic.Field()
+ """
+ Hidden dimension size
+ """
+
+ num_attention_heads: int = pydantic.Field()
+ """
+ Number of attention heads
+ """
+
+ num_kv_heads: int = pydantic.Field()
+ """
+ Number of key-value heads (for GQA/MQA)
+ """
+
+ ffn_hidden_size: int = pydantic.Field()
+ """
+ FFN intermediate size
+ """
+
+ vocab_size: int = pydantic.Field()
+ """
+ Vocabulary size
+ """
+
+ tied_embeddings: bool = pydantic.Field()
+ """
+ Whether embeddings are tied
+ """
+
+ gated_mlp: bool = pydantic.Field()
+ """
+ Whether MLP uses gated activation
+ """
+
+ base_num_parameters: int = pydantic.Field()
+ """
+ Total model parameters
+ """
+
+ precision: str = pydantic.Field()
+ """
+ Model precision (e.g., 'float16', 'bfloat16', 'float32', 'int8', 'int4')
+ """
+
+ moe_config: typing.Optional[MoEConfig] = pydantic.Field(default=None)
+ """
+ MoE configuration if applicable
+ """
+
+ mamba_config: typing.Optional[MambaConfig] = pydantic.Field(default=None)
+ """
+ Mamba/SSM configuration if applicable
+ """
+
+ sliding_window_config: typing.Optional[SlidingWindowConfig] = pydantic.Field(default=None)
+ """
+ Sliding window attention config if applicable
+ """
+
+ linear_layers: typing.Optional[typing.List[LinearLayerSpec]] = pydantic.Field(default=None)
+ """
+ List of all linear/Conv1D layers with their dimensions. Used for LoRA parameter estimation without requiring model instantiation. Each entry contains the module name, in_features, and out_features.
+ """
+
+ chat_template: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Jinja2 chat template string for the model. Used by NIM to format chat completions. If not set, the model's built-in tokenizer template is used.
+ """
+
+ tool_call_config: typing.Optional[ToolCallConfig] = pydantic.Field(default=None)
+ """
+ Tool calling configuration for NIM deployments. Controls how the model handles function/tool calling in chat completions.
+ """
+
+ minimum_gpus_all_weights: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Minimum GPUs required for full fine-tuning using default configurations.
+ """
+
+ minimum_gpus_lora: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Minimum GPUs required for LoRA fine-tuning using default configurations.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/model_type.py b/sdks/python/types/model_type.py
new file mode 100644
index 0000000000..6bfe843980
--- /dev/null
+++ b/sdks/python/types/model_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ModelType = typing.Union[typing.Literal["llm", "embed", "other"], typing.Any]
diff --git a/sdks/python/types/multilingual_config.py b/sdks/python/types/multilingual_config.py
new file mode 100644
index 0000000000..6db91136c0
--- /dev/null
+++ b/sdks/python/types/multilingual_config.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class MultilingualConfig(UniversalBaseModel):
+ """
+ Configuration for multilingual refusal messages.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, detect the language of user input and return refusal messages in the same language. Supported languages: en (English), es (Spanish), zh (Chinese), de (German), fr (French), hi (Hindi), ja (Japanese), ar (Arabic), th (Thai).
+ """
+
+ refusal_messages: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Custom refusal messages per language code. If not specified, built-in defaults are used. Example: {'en': 'Sorry, I cannot help.', 'es': 'Lo siento, no puedo ayudar.'}
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/ngc_storage_config.py b/sdks/python/types/ngc_storage_config.py
new file mode 100644
index 0000000000..e469b8bdac
--- /dev/null
+++ b/sdks/python/types/ngc_storage_config.py
@@ -0,0 +1,64 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .ngc_storage_config_target_type import NgcStorageConfigTargetType
+from .secret_ref import SecretRef
+
+
+class NgcStorageConfig(UniversalBaseModel):
+ read_chunk_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Chunk size in bytes for reading/streaming files. Larger chunks reduce async overhead but increase memory per concurrent download. Default: 1MB.
+ """
+
+ org: str = pydantic.Field()
+ """
+ NGC organization name
+ """
+
+ team: str = pydantic.Field()
+ """
+ NGC team name
+ """
+
+ target: str = pydantic.Field()
+ """
+ NGC asset name (model or resource)
+ """
+
+ target_type: typing.Optional[NgcStorageConfigTargetType] = pydantic.Field(default=None)
+ """
+ Type of NGC asset: 'resource' or 'model'
+ """
+
+ version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ NGC asset version. If not provided, defaults to latest version
+ """
+
+ original_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The original version requested by the user before resolution (e.g., 'latest' or None). The 'version' field contains the resolved version ID.
+ """
+
+ api_key_secret: SecretRef = pydantic.Field()
+ """
+ NGC API key secret name
+ """
+
+ host: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ NGC API host URL
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/ngc_storage_config_target_type.py b/sdks/python/types/ngc_storage_config_target_type.py
new file mode 100644
index 0000000000..3d02c066f2
--- /dev/null
+++ b/sdks/python/types/ngc_storage_config_target_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+NgcStorageConfigTargetType = typing.Union[typing.Literal["resource", "model"], typing.Any]
diff --git a/sdks/python/types/note_annotation.py b/sdks/python/types/note_annotation.py
new file mode 100644
index 0000000000..5999b3c2fd
--- /dev/null
+++ b/sdks/python/types/note_annotation.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class NoteAnnotation(UniversalBaseModel):
+ """
+ Free-text note attached to a span or session.
+ """
+
+ annotation_id: str
+ workspace: str
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to, or omitted for session-level annotations.
+ """
+
+ session_id: str
+ created_by: typing.Optional[str] = None
+ created_at: dt.datetime
+ ingested_at: dt.datetime
+ text: str = pydantic.Field()
+ """
+ The note content.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/note_annotation_input.py b/sdks/python/types/note_annotation_input.py
new file mode 100644
index 0000000000..9551f25218
--- /dev/null
+++ b/sdks/python/types/note_annotation_input.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class NoteAnnotationInput(UniversalBaseModel):
+ """
+ Free-text note attached to a span or session.
+ """
+
+ span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Id of the span this annotation applies to. Omit to annotate the whole session instead of a specific span.
+ """
+
+ session_id: str = pydantic.Field()
+ """
+ Id of the session this annotation belongs to. Always required.
+ """
+
+ text: str = pydantic.Field()
+ """
+ The note content. 1 to 10,000 characters.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/numeric_filter.py b/sdks/python/types/numeric_filter.py
new file mode 100644
index 0000000000..9d6f29271f
--- /dev/null
+++ b/sdks/python/types/numeric_filter.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class NumericFilter(UniversalBaseModel):
+ """
+ Range filter for numeric annotation values.
+
+ At least one of `$gte` or `$lte` must be supplied — an empty `{}` is not a
+ meaningful filter and is rejected.
+ """
+
+ gte: typing_extensions.Annotated[
+ typing.Optional[float],
+ FieldMetadata(alias="$gte"),
+ pydantic.Field(alias="$gte", description="Include only values greater than or equal to this number."),
+ ] = None
+ lte: typing_extensions.Annotated[
+ typing.Optional[float],
+ FieldMetadata(alias="$lte"),
+ pydantic.Field(alias="$lte", description="Include only values less than or equal to this number."),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/oidc_discovery_response.py b/sdks/python/types/oidc_discovery_response.py
new file mode 100644
index 0000000000..8ffe27e9fa
--- /dev/null
+++ b/sdks/python/types/oidc_discovery_response.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class OidcDiscoveryResponse(UniversalBaseModel):
+ """
+ OIDC discovery response for CLI/SDK.
+ """
+
+ issuer: str
+ authorization_endpoint: typing.Optional[str] = None
+ token_endpoint: typing.Optional[str] = None
+ device_authorization_endpoint: typing.Optional[str] = None
+ userinfo_endpoint: typing.Optional[str] = None
+ client_id: str
+ default_scopes: typing.Optional[str] = None
+ scope_prefix: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/open_ai_list_models_resp.py b/sdks/python/types/open_ai_list_models_resp.py
new file mode 100644
index 0000000000..71a5fc9b42
--- /dev/null
+++ b/sdks/python/types/open_ai_list_models_resp.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .open_ai_model_resp import OpenAiModelResp
+
+
+class OpenAiListModelsResp(UniversalBaseModel):
+ """
+ Duplicated structure for an OpenAI /v1/models response.
+ """
+
+ data: typing.List[OpenAiModelResp]
+ object: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/open_ai_model_resp.py b/sdks/python/types/open_ai_model_resp.py
new file mode 100644
index 0000000000..acb2750bcb
--- /dev/null
+++ b/sdks/python/types/open_ai_model_resp.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class OpenAiModelResp(UniversalBaseModel):
+ """
+ Duplicated structure for an OpenAI /v1/models individual model response.
+ """
+
+ id: str
+ owned_by: str
+ object: typing.Optional[str] = None
+ created: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/otel_export_logs_partial_success.py b/sdks/python/types/otel_export_logs_partial_success.py
new file mode 100644
index 0000000000..e924f88712
--- /dev/null
+++ b/sdks/python/types/otel_export_logs_partial_success.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class OtelExportLogsPartialSuccess(UniversalBaseModel):
+ """
+ Partial success response details.
+ """
+
+ rejected_log_records: typing_extensions.Annotated[
+ typing.Optional[int],
+ FieldMetadata(alias="rejectedLogRecords"),
+ pydantic.Field(alias="rejectedLogRecords", description="Number of rejected log records"),
+ ] = None
+ error_message: typing_extensions.Annotated[
+ typing.Optional[str],
+ FieldMetadata(alias="errorMessage"),
+ pydantic.Field(alias="errorMessage", description="Human-readable error message"),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/otel_export_logs_service_response.py b/sdks/python/types/otel_export_logs_service_response.py
new file mode 100644
index 0000000000..0fbf3d14df
--- /dev/null
+++ b/sdks/python/types/otel_export_logs_service_response.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+from .otel_export_logs_partial_success import OtelExportLogsPartialSuccess
+
+
+class OtelExportLogsServiceResponse(UniversalBaseModel):
+ """
+ Response for log export requests.
+
+ Per OTLP spec, successful responses should be empty or contain partial_success info.
+ """
+
+ partial_success: typing_extensions.Annotated[
+ typing.Optional[OtelExportLogsPartialSuccess],
+ FieldMetadata(alias="partialSuccess"),
+ pydantic.Field(alias="partialSuccess"),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/output_rails.py b/sdks/python/types/output_rails.py
new file mode 100644
index 0000000000..18d09497d1
--- /dev/null
+++ b/sdks/python/types/output_rails.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .output_rails_streaming_config import OutputRailsStreamingConfig
+
+
+class OutputRails(UniversalBaseModel):
+ """
+ Configuration of output rails.
+ """
+
+ parallel: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, the output rails are executed in parallel.
+ """
+
+ flows: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all the flows that implement output rails.
+ """
+
+ streaming: typing.Optional[OutputRailsStreamingConfig] = pydantic.Field(default=None)
+ """
+ Configuration for streaming output rails.
+ """
+
+ apply_to_reasoning_traces: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, output rails will apply guardrails to both reasoning traces and output response. If False, output rails will only apply guardrails to the output response excluding the reasoning traces, thus keeping reasoning traces unaltered.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/output_rails_streaming_config.py b/sdks/python/types/output_rails_streaming_config.py
new file mode 100644
index 0000000000..a43ee04e69
--- /dev/null
+++ b/sdks/python/types/output_rails_streaming_config.py
@@ -0,0 +1,41 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class OutputRailsStreamingConfig(UniversalBaseModel):
+ """
+ Configuration for managing streaming output of LLM tokens.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Enables streaming mode when True.
+ """
+
+ chunk_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The number of tokens in each processing chunk. This is the size of the token block on which output rails are applied.
+ """
+
+ context_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The number of tokens carried over from the previous chunk to provide context for continuity in processing.
+ """
+
+ stream_first: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, token chunks are streamed immediately before output rails are applied.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/pagination_data.py b/sdks/python/types/pagination_data.py
new file mode 100644
index 0000000000..1603503dbf
--- /dev/null
+++ b/sdks/python/types/pagination_data.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PaginationData(UniversalBaseModel):
+ page: int = pydantic.Field()
+ """
+ The current page number.
+ """
+
+ page_size: int = pydantic.Field()
+ """
+ The page size used for the query.
+ """
+
+ current_page_size: int = pydantic.Field()
+ """
+ The size for the current page.
+ """
+
+ total_pages: int = pydantic.Field()
+ """
+ The total number of pages.
+ """
+
+ total_results: int = pydantic.Field()
+ """
+ The total number of results.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/pangea_rail_config.py b/sdks/python/types/pangea_rail_config.py
new file mode 100644
index 0000000000..e7cf04cb60
--- /dev/null
+++ b/sdks/python/types/pangea_rail_config.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pangea_rail_options import PangeaRailOptions
+
+
+class PangeaRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the Pangea AI Guard API
+ """
+
+ input: typing.Optional[PangeaRailOptions] = pydantic.Field(default=None)
+ """
+ Pangea configuration for an Input Guardrail
+ """
+
+ output: typing.Optional[PangeaRailOptions] = pydantic.Field(default=None)
+ """
+ Pangea configuration for an Output Guardrail
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/pangea_rail_options.py b/sdks/python/types/pangea_rail_options.py
new file mode 100644
index 0000000000..c8d2f838d2
--- /dev/null
+++ b/sdks/python/types/pangea_rail_options.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PangeaRailOptions(UniversalBaseModel):
+ """
+ Configuration data for the Pangea AI Guard API
+ """
+
+ recipe: str = pydantic.Field()
+ """
+ Recipe key of a configuration of data types and settings defined in the Pangea User Console. It
+ specifies the rules that are to be applied to the text, such as defang malicious URLs.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/patronus_evaluate_api_params.py b/sdks/python/types/patronus_evaluate_api_params.py
new file mode 100644
index 0000000000..28d8640603
--- /dev/null
+++ b/sdks/python/types/patronus_evaluate_api_params.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .patronus_evaluation_success_strategy import PatronusEvaluationSuccessStrategy
+
+
+class PatronusEvaluateApiParams(UniversalBaseModel):
+ """
+ Config to parameterize the Patronus Evaluate API call
+ """
+
+ success_strategy: typing.Optional[PatronusEvaluationSuccessStrategy] = pydantic.Field(default=None)
+ """
+ Strategy to determine whether the Patronus Evaluate API Guardrail passes or not.
+ """
+
+ params: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Parameters to the Patronus Evaluate API
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/patronus_evaluate_config_input.py b/sdks/python/types/patronus_evaluate_config_input.py
new file mode 100644
index 0000000000..7f2fd5c7eb
--- /dev/null
+++ b/sdks/python/types/patronus_evaluate_config_input.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .patronus_evaluate_api_params import PatronusEvaluateApiParams
+
+
+class PatronusEvaluateConfigInput(UniversalBaseModel):
+ """
+ Config for the Patronus Evaluate API call
+ """
+
+ evaluate_config: typing.Optional[PatronusEvaluateApiParams] = pydantic.Field(default=None)
+ """
+ Configuration passed to the Patronus Evaluate API
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/patronus_evaluate_config_output.py b/sdks/python/types/patronus_evaluate_config_output.py
new file mode 100644
index 0000000000..4a247338cf
--- /dev/null
+++ b/sdks/python/types/patronus_evaluate_config_output.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .patronus_evaluate_api_params import PatronusEvaluateApiParams
+
+
+class PatronusEvaluateConfigOutput(UniversalBaseModel):
+ """
+ Config for the Patronus Evaluate API call
+ """
+
+ evaluate_config: typing.Optional[PatronusEvaluateApiParams] = pydantic.Field(default=None)
+ """
+ Configuration passed to the Patronus Evaluate API
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/patronus_evaluation_success_strategy.py b/sdks/python/types/patronus_evaluation_success_strategy.py
new file mode 100644
index 0000000000..f515084401
--- /dev/null
+++ b/sdks/python/types/patronus_evaluation_success_strategy.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+PatronusEvaluationSuccessStrategy = typing.Union[typing.Literal["all_pass", "any_pass"], typing.Any]
diff --git a/sdks/python/types/patronus_rail_config_input.py b/sdks/python/types/patronus_rail_config_input.py
new file mode 100644
index 0000000000..b2a87c12ef
--- /dev/null
+++ b/sdks/python/types/patronus_rail_config_input.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .patronus_evaluate_config_input import PatronusEvaluateConfigInput
+
+
+class PatronusRailConfigInput(UniversalBaseModel):
+ """
+ Configuration data for the Patronus Evaluate API
+ """
+
+ input: typing.Optional[PatronusEvaluateConfigInput] = pydantic.Field(default=None)
+ """
+ Patronus Evaluate API configuration for an Input Guardrail
+ """
+
+ output: typing.Optional[PatronusEvaluateConfigInput] = pydantic.Field(default=None)
+ """
+ Patronus Evaluate API configuration for an Output Guardrail
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/patronus_rail_config_output.py b/sdks/python/types/patronus_rail_config_output.py
new file mode 100644
index 0000000000..4ae05aa2ec
--- /dev/null
+++ b/sdks/python/types/patronus_rail_config_output.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .patronus_evaluate_config_output import PatronusEvaluateConfigOutput
+
+
+class PatronusRailConfigOutput(UniversalBaseModel):
+ """
+ Configuration data for the Patronus Evaluate API
+ """
+
+ input: typing.Optional[PatronusEvaluateConfigOutput] = pydantic.Field(default=None)
+ """
+ Patronus Evaluate API configuration for an Input Guardrail
+ """
+
+ output: typing.Optional[PatronusEvaluateConfigOutput] = pydantic.Field(default=None)
+ """
+ Patronus Evaluate API configuration for an Output Guardrail
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_environment_variable.py b/sdks/python/types/platform_job_environment_variable.py
new file mode 100644
index 0000000000..1c3d81db2c
--- /dev/null
+++ b/sdks/python/types/platform_job_environment_variable.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_secret_environment_variable_ref import PlatformJobSecretEnvironmentVariableRef
+
+
+class PlatformJobEnvironmentVariable(UniversalBaseModel):
+ """
+ Environment variable for a job step
+ """
+
+ name: str = pydantic.Field()
+ """
+ The environment variable name
+ """
+
+ value: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The environment variable value
+ """
+
+ from_secret: typing.Optional[PlatformJobSecretEnvironmentVariableRef] = pydantic.Field(default=None)
+ """
+ Reference to a secret environment variable to populate the environment variable
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_list_result_response.py b/sdks/python/types/platform_job_list_result_response.py
new file mode 100644
index 0000000000..e8fd26ae96
--- /dev/null
+++ b/sdks/python/types/platform_job_list_result_response.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_result_response import PlatformJobResultResponse
+
+
+class PlatformJobListResultResponse(UniversalBaseModel):
+ data: typing.List[PlatformJobResultResponse]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_list_task_response.py b/sdks/python/types/platform_job_list_task_response.py
new file mode 100644
index 0000000000..d97ce99f82
--- /dev/null
+++ b/sdks/python/types/platform_job_list_task_response.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_task import PlatformJobTask
+
+
+class PlatformJobListTaskResponse(UniversalBaseModel):
+ """
+ Response model for listing job tasks.
+ """
+
+ data: typing.List[PlatformJobTask]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_log.py b/sdks/python/types/platform_job_log.py
new file mode 100644
index 0000000000..9a9c46329e
--- /dev/null
+++ b/sdks/python/types/platform_job_log.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PlatformJobLog(UniversalBaseModel):
+ timestamp: dt.datetime
+ job: str
+ job_step: str
+ job_task: str
+ message: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_log_page.py b/sdks/python/types/platform_job_log_page.py
new file mode 100644
index 0000000000..1650e79aca
--- /dev/null
+++ b/sdks/python/types/platform_job_log_page.py
@@ -0,0 +1,23 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_log import PlatformJobLog
+
+
+class PlatformJobLogPage(UniversalBaseModel):
+ data: typing.List[PlatformJobLog]
+ total: int
+ next_page: str
+ prev_page: str
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_response.py b/sdks/python/types/platform_job_response.py
new file mode 100644
index 0000000000..72b7f1c349
--- /dev/null
+++ b/sdks/python/types/platform_job_response.py
@@ -0,0 +1,65 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_spec_output import PlatformJobSpecOutput
+from .platform_job_status import PlatformJobStatus
+
+
+class PlatformJobResponse(UniversalBaseModel):
+ """
+ Response model for a platform job.
+ """
+
+ id: str
+ attempt_id: str
+ name: str
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Project URN
+ """
+
+ description: typing.Optional[str] = None
+ source: str
+ spec: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Job Spec
+ """
+
+ platform_spec: PlatformJobSpecOutput
+ fileset: str = pydantic.Field()
+ """
+ Fileset ID for storing job artifacts
+ """
+
+ status: PlatformJobStatus
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Details about the job status
+ """
+
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = None
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ ownership: typing.Optional[typing.Dict[str, typing.Any]] = None
+ custom_fields: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Custom Fields
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_responses_page.py b/sdks/python/types/platform_job_responses_page.py
new file mode 100644
index 0000000000..4f36ea9d2d
--- /dev/null
+++ b/sdks/python/types/platform_job_responses_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .platform_job_response import PlatformJobResponse
+
+
+class PlatformJobResponsesPage(UniversalBaseModel):
+ data: typing.List[PlatformJobResponse]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_result_response.py b/sdks/python/types/platform_job_result_response.py
new file mode 100644
index 0000000000..1f2bc2114e
--- /dev/null
+++ b/sdks/python/types/platform_job_result_response.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .file_storage_type import FileStorageType
+
+
+class PlatformJobResultResponse(UniversalBaseModel):
+ name: str
+ job: str
+ workspace: str
+ project: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ artifact_url: str
+ artifact_storage_type: FileStorageType
+ download_url: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_secret_environment_variable_ref.py b/sdks/python/types/platform_job_secret_environment_variable_ref.py
new file mode 100644
index 0000000000..51fcef80fe
--- /dev/null
+++ b/sdks/python/types/platform_job_secret_environment_variable_ref.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PlatformJobSecretEnvironmentVariableRef(UniversalBaseModel):
+ """
+ Reference to a secret to populate an environment variable for a job step.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the secret to reference
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_sort_field.py b/sdks/python/types/platform_job_sort_field.py
new file mode 100644
index 0000000000..ba63b307e1
--- /dev/null
+++ b/sdks/python/types/platform_job_sort_field.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+PlatformJobSortField = typing.Union[
+ typing.Literal["created_at", "-created_at", "updated_at", "-updated_at"], typing.Any
+]
diff --git a/sdks/python/types/platform_job_spec_input.py b/sdks/python/types/platform_job_spec_input.py
new file mode 100644
index 0000000000..cdb415676c
--- /dev/null
+++ b/sdks/python/types/platform_job_spec_input.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_step_spec_input import PlatformJobStepSpecInput
+
+
+class PlatformJobSpecInput(UniversalBaseModel):
+ """
+ Specification for a platform job, containing steps and secrets.
+ """
+
+ steps: typing.List[PlatformJobStepSpecInput] = pydantic.Field()
+ """
+ List of steps to be executed in the job
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_spec_output.py b/sdks/python/types/platform_job_spec_output.py
new file mode 100644
index 0000000000..0560bb64e8
--- /dev/null
+++ b/sdks/python/types/platform_job_spec_output.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_step_spec_output import PlatformJobStepSpecOutput
+
+
+class PlatformJobSpecOutput(UniversalBaseModel):
+ """
+ Specification for a platform job, containing steps and secrets.
+ """
+
+ steps: typing.List[PlatformJobStepSpecOutput] = pydantic.Field()
+ """
+ List of steps to be executed in the job
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_status.py b/sdks/python/types/platform_job_status.py
new file mode 100644
index 0000000000..3da9c4c126
--- /dev/null
+++ b/sdks/python/types/platform_job_status.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+PlatformJobStatus = typing.Union[
+ typing.Literal[
+ "created", "pending", "active", "cancelled", "cancelling", "error", "completed", "paused", "pausing", "resuming"
+ ],
+ typing.Any,
+]
diff --git a/sdks/python/types/platform_job_status_response.py b/sdks/python/types/platform_job_status_response.py
new file mode 100644
index 0000000000..38c953697f
--- /dev/null
+++ b/sdks/python/types/platform_job_status_response.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+from .platform_job_step_status_response import PlatformJobStepStatusResponse
+
+
+class PlatformJobStatusResponse(UniversalBaseModel):
+ id: str
+ name: str
+ status: PlatformJobStatus
+ status_details: typing.Dict[str, typing.Any]
+ error_details: typing.Dict[str, typing.Any]
+ steps: typing.List[PlatformJobStepStatusResponse]
+ created_at: dt.datetime
+ updated_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step.py b/sdks/python/types/platform_job_step.py
new file mode 100644
index 0000000000..814ee1086e
--- /dev/null
+++ b/sdks/python/types/platform_job_step.py
@@ -0,0 +1,80 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+
+
+class PlatformJobStep(UniversalBaseModel):
+ """
+ A single step within an attempt.
+
+ Parent-scoped: unique within (workspace, entity_type, parent=attempt_id).
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity name within the workspace
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the project associated with this entity.
+ """
+
+ attempt_id: str = pydantic.Field()
+ """
+ Parent attempt ID
+ """
+
+ config: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Configuration for the step
+ """
+
+ status: typing.Optional[PlatformJobStatus] = pydantic.Field(default=None)
+ """
+ Step status
+ """
+
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Status details
+ """
+
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Error details if applicable
+ """
+
+ id: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ created_by: typing.Optional[str] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ updated_by: typing.Optional[str] = None
+ entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Alias for id for backwards compatibility.
+ """
+
+ parent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent entity ID for nested entities.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step_spec_input.py b/sdks/python/types/platform_job_step_spec_input.py
new file mode 100644
index 0000000000..98a2491fc5
--- /dev/null
+++ b/sdks/python/types/platform_job_step_spec_input.py
@@ -0,0 +1,49 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_environment_variable import PlatformJobEnvironmentVariable
+from .platform_job_step_spec_input_executor import PlatformJobStepSpecInputExecutor
+from .step_lifecycle import StepLifecycle
+
+
+class PlatformJobStepSpecInput(UniversalBaseModel):
+ """
+ Specification for a single step in a platform job.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the step. Must be unique for all steps in a job. Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+ """
+
+ environment: typing.Optional[typing.List[PlatformJobEnvironmentVariable]] = pydantic.Field(default=None)
+ """
+ Environment variables for the step
+ """
+
+ executor: PlatformJobStepSpecInputExecutor = pydantic.Field()
+ """
+ The executor for the step
+ """
+
+ config: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Configuration for the step
+ """
+
+ lifecycle: typing.Optional[StepLifecycle] = pydantic.Field(default=None)
+ """
+ Lifecycle configuration settings for the step
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step_spec_input_executor.py b/sdks/python/types/platform_job_step_spec_input_executor.py
new file mode 100644
index 0000000000..0e95843931
--- /dev/null
+++ b/sdks/python/types/platform_job_step_spec_input_executor.py
@@ -0,0 +1,101 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class PlatformJobStepSpecInputExecutor_Cpu(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["cpu"] = "cpu"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecInputExecutor_Gpu(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["gpu"] = "gpu"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecInputExecutor_GpuDistributed(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["gpu_distributed"] = "gpu_distributed"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecInputExecutor_Subprocess(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["subprocess"] = "subprocess"
+ profile: typing.Optional[str] = None
+ command: typing.List[str]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+PlatformJobStepSpecInputExecutor = typing_extensions.Annotated[
+ typing.Union[
+ PlatformJobStepSpecInputExecutor_Cpu,
+ PlatformJobStepSpecInputExecutor_Gpu,
+ PlatformJobStepSpecInputExecutor_GpuDistributed,
+ PlatformJobStepSpecInputExecutor_Subprocess,
+ ],
+ pydantic.Field(discriminator="provider"),
+]
diff --git a/sdks/python/types/platform_job_step_spec_output.py b/sdks/python/types/platform_job_step_spec_output.py
new file mode 100644
index 0000000000..d90ffeb9ef
--- /dev/null
+++ b/sdks/python/types/platform_job_step_spec_output.py
@@ -0,0 +1,49 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_environment_variable import PlatformJobEnvironmentVariable
+from .platform_job_step_spec_output_executor import PlatformJobStepSpecOutputExecutor
+from .step_lifecycle import StepLifecycle
+
+
+class PlatformJobStepSpecOutput(UniversalBaseModel):
+ """
+ Specification for a single step in a platform job.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the step. Must be unique for all steps in a job. Name must start with a lowercase letter, be 2-63 characters, and contain only lowercase letters, digits, and hyphens (no consecutive hyphens, cannot end with a hyphen).
+ """
+
+ environment: typing.Optional[typing.List[PlatformJobEnvironmentVariable]] = pydantic.Field(default=None)
+ """
+ Environment variables for the step
+ """
+
+ executor: PlatformJobStepSpecOutputExecutor = pydantic.Field()
+ """
+ The executor for the step
+ """
+
+ config: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Configuration for the step
+ """
+
+ lifecycle: typing.Optional[StepLifecycle] = pydantic.Field(default=None)
+ """
+ Lifecycle configuration settings for the step
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step_spec_output_executor.py b/sdks/python/types/platform_job_step_spec_output_executor.py
new file mode 100644
index 0000000000..1dd4cbb385
--- /dev/null
+++ b/sdks/python/types/platform_job_step_spec_output_executor.py
@@ -0,0 +1,101 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from __future__ import annotations
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .container_spec import ContainerSpec
+
+
+class PlatformJobStepSpecOutputExecutor_Cpu(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["cpu"] = "cpu"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecOutputExecutor_Gpu(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["gpu"] = "gpu"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecOutputExecutor_GpuDistributed(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["gpu_distributed"] = "gpu_distributed"
+ profile: typing.Optional[str] = None
+ container: ContainerSpec
+ resources: typing.Optional[ComputeResources] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+class PlatformJobStepSpecOutputExecutor_Subprocess(UniversalBaseModel):
+ """
+ The executor for the step
+ """
+
+ provider: typing.Literal["subprocess"] = "subprocess"
+ profile: typing.Optional[str] = None
+ command: typing.List[str]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
+
+
+PlatformJobStepSpecOutputExecutor = typing_extensions.Annotated[
+ typing.Union[
+ PlatformJobStepSpecOutputExecutor_Cpu,
+ PlatformJobStepSpecOutputExecutor_Gpu,
+ PlatformJobStepSpecOutputExecutor_GpuDistributed,
+ PlatformJobStepSpecOutputExecutor_Subprocess,
+ ],
+ pydantic.Field(discriminator="provider"),
+]
diff --git a/sdks/python/types/platform_job_step_status_response.py b/sdks/python/types/platform_job_step_status_response.py
new file mode 100644
index 0000000000..ef640b715a
--- /dev/null
+++ b/sdks/python/types/platform_job_step_status_response.py
@@ -0,0 +1,29 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+from .platform_job_task_status_response import PlatformJobTaskStatusResponse
+
+
+class PlatformJobStepStatusResponse(UniversalBaseModel):
+ id: str
+ name: str
+ status: PlatformJobStatus
+ status_details: typing.Dict[str, typing.Any]
+ error_details: typing.Dict[str, typing.Any]
+ tasks: typing.List[PlatformJobTaskStatusResponse]
+ created_at: dt.datetime
+ updated_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step_with_context.py b/sdks/python/types/platform_job_step_with_context.py
new file mode 100644
index 0000000000..b0abeb5c3a
--- /dev/null
+++ b/sdks/python/types/platform_job_step_with_context.py
@@ -0,0 +1,43 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .auth_context import AuthContext
+from .platform_job_status import PlatformJobStatus
+from .platform_job_step_spec_output import PlatformJobStepSpecOutput
+
+
+class PlatformJobStepWithContext(UniversalBaseModel):
+ """
+ Step with additional context from parent job/attempt.
+ """
+
+ id: str
+ job: str
+ attempt_id: str
+ fileset: str
+ workspace: str
+ name: str
+ step_spec: typing.Optional[PlatformJobStepSpecOutput] = None
+ status: typing.Optional[PlatformJobStatus] = None
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = None
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = None
+ auth_context: typing.Optional[AuthContext] = pydantic.Field(default=None)
+ """
+ Auth context for task execution
+ """
+
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_step_with_contexts_page.py b/sdks/python/types/platform_job_step_with_contexts_page.py
new file mode 100644
index 0000000000..bc16560a4f
--- /dev/null
+++ b/sdks/python/types/platform_job_step_with_contexts_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .platform_job_step_with_context import PlatformJobStepWithContext
+
+
+class PlatformJobStepWithContextsPage(UniversalBaseModel):
+ data: typing.List[PlatformJobStepWithContext]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_steps_list_filter.py b/sdks/python/types/platform_job_steps_list_filter.py
new file mode 100644
index 0000000000..74328bbb3d
--- /dev/null
+++ b/sdks/python/types/platform_job_steps_list_filter.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+
+
+class PlatformJobStepsListFilter(UniversalBaseModel):
+ """
+ Filter options for listing platform job steps.
+ """
+
+ job: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The ID of the job to filter steps by.
+ """
+
+ status: typing.Optional[typing.List[PlatformJobStatus]] = pydantic.Field(default=None)
+ """
+ The list of statuses to filter steps by.
+ """
+
+ source: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The source of the job steps.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_task.py b/sdks/python/types/platform_job_task.py
new file mode 100644
index 0000000000..10d59f775e
--- /dev/null
+++ b/sdks/python/types/platform_job_task.py
@@ -0,0 +1,80 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+
+
+class PlatformJobTask(UniversalBaseModel):
+ """
+ A task within a step (for parallel execution).
+
+ Parent-scoped: unique within (workspace, entity_type, parent=step_id).
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity name within the workspace
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the project associated with this entity.
+ """
+
+ step_id: str = pydantic.Field()
+ """
+ Parent step ID
+ """
+
+ status: typing.Optional[PlatformJobStatus] = pydantic.Field(default=None)
+ """
+ Task status
+ """
+
+ status_details: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Details about the task status
+ """
+
+ error_details: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Details about task errors
+ """
+
+ error_stack: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Error stack trace if applicable
+ """
+
+ id: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ created_by: typing.Optional[str] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ updated_by: typing.Optional[str] = None
+ entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Alias for id for backwards compatibility.
+ """
+
+ parent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent entity ID for nested entities.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_job_task_status_response.py b/sdks/python/types/platform_job_task_status_response.py
new file mode 100644
index 0000000000..b888ec2228
--- /dev/null
+++ b/sdks/python/types/platform_job_task_status_response.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .platform_job_status import PlatformJobStatus
+
+
+class PlatformJobTaskStatusResponse(UniversalBaseModel):
+ id: str
+ name: str
+ status: PlatformJobStatus
+ status_details: typing.Dict[str, typing.Any]
+ error_details: typing.Dict[str, typing.Any]
+ error_stack: str
+ created_at: dt.datetime
+ updated_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_jobs_list_filter.py b/sdks/python/types/platform_jobs_list_filter.py
new file mode 100644
index 0000000000..e167e23e1f
--- /dev/null
+++ b/sdks/python/types/platform_jobs_list_filter.py
@@ -0,0 +1,60 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .platform_jobs_list_filter_name import PlatformJobsListFilterName
+from .platform_jobs_list_filter_source import PlatformJobsListFilterSource
+from .platform_jobs_list_filter_status import PlatformJobsListFilterStatus
+
+
+class PlatformJobsListFilter(UniversalBaseModel):
+ """
+ Filter options for listing platform jobs.
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Workspace of the job.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Project of the job.
+ """
+
+ name: typing.Optional[PlatformJobsListFilterName] = pydantic.Field(default=None)
+ """
+ Name of the job.
+ """
+
+ created_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Jobs created at 'gte' datetime or 'lte' datetime.
+ """
+
+ updated_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Jobs updated at 'gte' datetime or 'lte' datetime.
+ """
+
+ status: typing.Optional[PlatformJobsListFilterStatus] = pydantic.Field(default=None)
+ """
+ The current status.
+ """
+
+ source: typing.Optional[PlatformJobsListFilterSource] = pydantic.Field(default=None)
+ """
+ The source of the job.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_jobs_list_filter_name.py b/sdks/python/types/platform_jobs_list_filter_name.py
new file mode 100644
index 0000000000..dd8ba6c718
--- /dev/null
+++ b/sdks/python/types/platform_jobs_list_filter_name.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+PlatformJobsListFilterName = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/platform_jobs_list_filter_source.py b/sdks/python/types/platform_jobs_list_filter_source.py
new file mode 100644
index 0000000000..ce53170fef
--- /dev/null
+++ b/sdks/python/types/platform_jobs_list_filter_source.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+PlatformJobsListFilterSource = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/platform_jobs_list_filter_status.py b/sdks/python/types/platform_jobs_list_filter_status.py
new file mode 100644
index 0000000000..7d7717a639
--- /dev/null
+++ b/sdks/python/types/platform_jobs_list_filter_status.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .platform_job_status import PlatformJobStatus
+
+PlatformJobsListFilterStatus = typing.Union[PlatformJobStatus, typing.List[PlatformJobStatus]]
diff --git a/sdks/python/types/platform_secret_access_response.py b/sdks/python/types/platform_secret_access_response.py
new file mode 100644
index 0000000000..ef9430682b
--- /dev/null
+++ b/sdks/python/types/platform_secret_access_response.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PlatformSecretAccessResponse(UniversalBaseModel):
+ """
+ Response model for accessing a platform secret's value.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the secret
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace ID the secret belongs to
+ """
+
+ value: str = pydantic.Field()
+ """
+ The payload of the secret
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_secret_admin_rotation_response.py b/sdks/python/types/platform_secret_admin_rotation_response.py
new file mode 100644
index 0000000000..25cde6016d
--- /dev/null
+++ b/sdks/python/types/platform_secret_admin_rotation_response.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PlatformSecretAdminRotationResponse(UniversalBaseModel):
+ """
+ Response schema for admin secret rotation routine.
+ """
+
+ rotated_secrets: int
+ success: bool
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_secret_response.py b/sdks/python/types/platform_secret_response.py
new file mode 100644
index 0000000000..c22d49fe14
--- /dev/null
+++ b/sdks/python/types/platform_secret_response.py
@@ -0,0 +1,40 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PlatformSecretResponse(UniversalBaseModel):
+ """
+ Response model for a platform secret.
+ """
+
+ name: str = pydantic.Field()
+ """
+ The name of the secret
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ The workspace ID the secret belongs to
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ An optional description of the secret
+ """
+
+ created_at: typing.Optional[dt.datetime] = None
+ updated_at: typing.Optional[dt.datetime] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/platform_secret_responses_page.py b/sdks/python/types/platform_secret_responses_page.py
new file mode 100644
index 0000000000..69b1287519
--- /dev/null
+++ b/sdks/python/types/platform_secret_responses_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .platform_secret_response import PlatformSecretResponse
+
+
+class PlatformSecretResponsesPage(UniversalBaseModel):
+ data: typing.List[PlatformSecretResponse]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/private_ai_detection.py b/sdks/python/types/private_ai_detection.py
new file mode 100644
index 0000000000..84189d42e8
--- /dev/null
+++ b/sdks/python/types/private_ai_detection.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .private_ai_detection_options import PrivateAiDetectionOptions
+
+
+class PrivateAiDetection(UniversalBaseModel):
+ """
+ Configuration for Private AI.
+ """
+
+ server_endpoint: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The endpoint for the private AI detection server.
+ """
+
+ input: typing.Optional[PrivateAiDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the user input.
+ """
+
+ output: typing.Optional[PrivateAiDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the bot output.
+ """
+
+ retrieval: typing.Optional[PrivateAiDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on retrieved relevant chunks.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/private_ai_detection_options.py b/sdks/python/types/private_ai_detection_options.py
new file mode 100644
index 0000000000..ad33951051
--- /dev/null
+++ b/sdks/python/types/private_ai_detection_options.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class PrivateAiDetectionOptions(UniversalBaseModel):
+ """
+ Configuration options for Private AI.
+ """
+
+ entities: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of entities that should be detected.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/project.py b/sdks/python/types/project.py
new file mode 100644
index 0000000000..63aa43aa1d
--- /dev/null
+++ b/sdks/python/types/project.py
@@ -0,0 +1,52 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Project(UniversalBaseModel):
+ """
+ Schema for Project responses.
+ """
+
+ id: str = pydantic.Field()
+ """
+ Unique identifier
+ """
+
+ name: str = pydantic.Field()
+ """
+ Project name
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Project description
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ Creation timestamp
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ Last update timestamp
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/project_sort_field.py b/sdks/python/types/project_sort_field.py
new file mode 100644
index 0000000000..26a1caf07c
--- /dev/null
+++ b/sdks/python/types/project_sort_field.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ProjectSortField = typing.Union[
+ typing.Literal["created_at", "-created_at", "updated_at", "-updated_at", "name"], typing.Any
+]
diff --git a/sdks/python/types/projects_page.py b/sdks/python/types/projects_page.py
new file mode 100644
index 0000000000..c14b140a6c
--- /dev/null
+++ b/sdks/python/types/projects_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .project import Project
+
+
+class ProjectsPage(UniversalBaseModel):
+ data: typing.List[Project]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/prompt_data.py b/sdks/python/types/prompt_data.py
new file mode 100644
index 0000000000..2fd0f66574
--- /dev/null
+++ b/sdks/python/types/prompt_data.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .inference_params import InferenceParams
+
+
+class PromptData(UniversalBaseModel):
+ """
+ Configuration for prompt engineering.
+ """
+
+ system_prompt: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ System prompt template
+ """
+
+ icl_few_shot_examples: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ In-context learning examples
+ """
+
+ inference_params: typing.Optional[InferenceParams] = pydantic.Field(default=None)
+ """
+ Inference parameters that should be overridden.
+ """
+
+ system_prompt_template: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The template which will be used to compile the final prompt used for prompting the LLM. Currently supports only {{icl_few_shot_examples}}
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rail_status.py b/sdks/python/types/rail_status.py
new file mode 100644
index 0000000000..cdd4834e84
--- /dev/null
+++ b/sdks/python/types/rail_status.py
@@ -0,0 +1,23 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .status_enum import StatusEnum
+
+
+class RailStatus(UniversalBaseModel):
+ status: StatusEnum = pydantic.Field()
+ """
+ Status of the individual rail.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_config_data_input.py b/sdks/python/types/rails_config_data_input.py
new file mode 100644
index 0000000000..d93e79d0dd
--- /dev/null
+++ b/sdks/python/types/rails_config_data_input.py
@@ -0,0 +1,123 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .ai_defense_rail_config import AiDefenseRailConfig
+from .auto_align_rail_config import AutoAlignRailConfig
+from .clavata_rail_config import ClavataRailConfig
+from .content_safety_config import ContentSafetyConfig
+from .crowd_strike_aidr_rail_config import CrowdStrikeAidrRailConfig
+from .fact_checking_rail_config import FactCheckingRailConfig
+from .fiddler_guardrails import FiddlerGuardrails
+from .g_li_ner_detection import GLiNerDetection
+from .guardrails_ai_rail_config import GuardrailsAiRailConfig
+from .injection_detection import InjectionDetection
+from .jailbreak_detection_config import JailbreakDetectionConfig
+from .pangea_rail_config import PangeaRailConfig
+from .patronus_rail_config_input import PatronusRailConfigInput
+from .private_ai_detection import PrivateAiDetection
+from .regex_detection import RegexDetection
+from .sensitive_data_detection import SensitiveDataDetection
+from .trend_micro_rail_config import TrendMicroRailConfig
+
+
+class RailsConfigDataInput(UniversalBaseModel):
+ """
+ Configuration data for specific rails that are supported out-of-the-box.
+ """
+
+ fact_checking: typing.Optional[FactCheckingRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration data for the fact-checking rail.
+ """
+
+ autoalign: typing.Optional[AutoAlignRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration data for the AutoAlign guardrails API.
+ """
+
+ patronus: typing.Optional[PatronusRailConfigInput] = pydantic.Field(default=None)
+ """
+ Configuration data for the Patronus Evaluate API.
+ """
+
+ sensitive_data_detection: typing.Optional[SensitiveDataDetection] = pydantic.Field(default=None)
+ """
+ Configuration for detecting sensitive data.
+ """
+
+ regex_detection: typing.Optional[RegexDetection] = pydantic.Field(default=None)
+ """
+ Configuration for regex pattern detection.
+ """
+
+ jailbreak_detection: typing.Optional[JailbreakDetectionConfig] = pydantic.Field(default=None)
+ """
+ Configuration for jailbreak detection.
+ """
+
+ injection_detection: typing.Optional[InjectionDetection] = pydantic.Field(default=None)
+ """
+ Configuration for injection detection.
+ """
+
+ privateai: typing.Optional[PrivateAiDetection] = pydantic.Field(default=None)
+ """
+ Configuration for Private AI.
+ """
+
+ gliner: typing.Optional[GLiNerDetection] = pydantic.Field(default=None)
+ """
+ Configuration for GLiNER PII detection.
+ """
+
+ fiddler: typing.Optional[FiddlerGuardrails] = pydantic.Field(default=None)
+ """
+ Configuration for Fiddler Guardrails.
+ """
+
+ clavata: typing.Optional[ClavataRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Clavata.
+ """
+
+ crowdstrike_aidr: typing.Optional[CrowdStrikeAidrRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for CrowdStrike AIDR.
+ """
+
+ pangea: typing.Optional[PangeaRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Pangea.
+ """
+
+ guardrails_ai: typing.Optional[GuardrailsAiRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Guardrails AI validators.
+ """
+
+ trend_micro: typing.Optional[TrendMicroRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Trend Micro.
+ """
+
+ ai_defense: typing.Optional[AiDefenseRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Cisco AI Defense.
+ """
+
+ content_safety: typing.Optional[ContentSafetyConfig] = pydantic.Field(default=None)
+ """
+ Configuration for content safety rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_config_data_output.py b/sdks/python/types/rails_config_data_output.py
new file mode 100644
index 0000000000..7f26f25bf5
--- /dev/null
+++ b/sdks/python/types/rails_config_data_output.py
@@ -0,0 +1,123 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .ai_defense_rail_config import AiDefenseRailConfig
+from .auto_align_rail_config import AutoAlignRailConfig
+from .clavata_rail_config import ClavataRailConfig
+from .content_safety_config import ContentSafetyConfig
+from .crowd_strike_aidr_rail_config import CrowdStrikeAidrRailConfig
+from .fact_checking_rail_config import FactCheckingRailConfig
+from .fiddler_guardrails import FiddlerGuardrails
+from .g_li_ner_detection import GLiNerDetection
+from .guardrails_ai_rail_config import GuardrailsAiRailConfig
+from .injection_detection import InjectionDetection
+from .jailbreak_detection_config import JailbreakDetectionConfig
+from .pangea_rail_config import PangeaRailConfig
+from .patronus_rail_config_output import PatronusRailConfigOutput
+from .private_ai_detection import PrivateAiDetection
+from .regex_detection import RegexDetection
+from .sensitive_data_detection import SensitiveDataDetection
+from .trend_micro_rail_config import TrendMicroRailConfig
+
+
+class RailsConfigDataOutput(UniversalBaseModel):
+ """
+ Configuration data for specific rails that are supported out-of-the-box.
+ """
+
+ fact_checking: typing.Optional[FactCheckingRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration data for the fact-checking rail.
+ """
+
+ autoalign: typing.Optional[AutoAlignRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration data for the AutoAlign guardrails API.
+ """
+
+ patronus: typing.Optional[PatronusRailConfigOutput] = pydantic.Field(default=None)
+ """
+ Configuration data for the Patronus Evaluate API.
+ """
+
+ sensitive_data_detection: typing.Optional[SensitiveDataDetection] = pydantic.Field(default=None)
+ """
+ Configuration for detecting sensitive data.
+ """
+
+ regex_detection: typing.Optional[RegexDetection] = pydantic.Field(default=None)
+ """
+ Configuration for regex pattern detection.
+ """
+
+ jailbreak_detection: typing.Optional[JailbreakDetectionConfig] = pydantic.Field(default=None)
+ """
+ Configuration for jailbreak detection.
+ """
+
+ injection_detection: typing.Optional[InjectionDetection] = pydantic.Field(default=None)
+ """
+ Configuration for injection detection.
+ """
+
+ privateai: typing.Optional[PrivateAiDetection] = pydantic.Field(default=None)
+ """
+ Configuration for Private AI.
+ """
+
+ gliner: typing.Optional[GLiNerDetection] = pydantic.Field(default=None)
+ """
+ Configuration for GLiNER PII detection.
+ """
+
+ fiddler: typing.Optional[FiddlerGuardrails] = pydantic.Field(default=None)
+ """
+ Configuration for Fiddler Guardrails.
+ """
+
+ clavata: typing.Optional[ClavataRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Clavata.
+ """
+
+ crowdstrike_aidr: typing.Optional[CrowdStrikeAidrRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for CrowdStrike AIDR.
+ """
+
+ pangea: typing.Optional[PangeaRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Pangea.
+ """
+
+ guardrails_ai: typing.Optional[GuardrailsAiRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Guardrails AI validators.
+ """
+
+ trend_micro: typing.Optional[TrendMicroRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Trend Micro.
+ """
+
+ ai_defense: typing.Optional[AiDefenseRailConfig] = pydantic.Field(default=None)
+ """
+ Configuration for Cisco AI Defense.
+ """
+
+ content_safety: typing.Optional[ContentSafetyConfig] = pydantic.Field(default=None)
+ """
+ Configuration for content safety rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_config_input.py b/sdks/python/types/rails_config_input.py
new file mode 100644
index 0000000000..9ae7a2ae5a
--- /dev/null
+++ b/sdks/python/types/rails_config_input.py
@@ -0,0 +1,96 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .instruction import Instruction
+from .model import Model
+from .rails_input import RailsInput
+from .task_prompt import TaskPrompt
+from .tracing_config import TracingConfig
+
+
+class RailsConfigInput(UniversalBaseModel):
+ """
+ Configuration object for the models and the rails.
+ """
+
+ models: typing.Optional[typing.List[Model]] = pydantic.Field(default=None)
+ """
+ The list of models used by the rails configuration.
+ """
+
+ instructions: typing.Optional[typing.List[Instruction]] = pydantic.Field(default=None)
+ """
+ List of instructions in natural language that the LLM should use.
+ """
+
+ actions_server_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URL of the actions server that should be used for the rails.
+ """
+
+ sample_conversation: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The sample conversation that should be used inside the prompts.
+ """
+
+ prompts: typing.Optional[typing.List[TaskPrompt]] = pydantic.Field(default=None)
+ """
+ The prompts that should be used for the various LLM tasks.
+ """
+
+ prompting_mode: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Allows choosing between different prompting strategies.
+ """
+
+ lowest_temperature: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The lowest temperature that should be used for the LLM.
+ """
+
+ enable_multi_step_generation: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable multi-step generation for the LLM.
+ """
+
+ colang_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The Colang version to use.
+ """
+
+ custom_data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Any custom configuration data that might be needed.
+ """
+
+ rails: typing.Optional[RailsInput] = pydantic.Field(default=None)
+ """
+ Configuration for the various rails (input, output, etc.).
+ """
+
+ enable_rails_exceptions: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If set, the pre-defined guardrails raise exceptions instead of returning pre-defined messages.
+ """
+
+ passthrough: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the original prompt should pass through the guardrails configuration as is. This means it will not be altered in any way.
+ """
+
+ tracing: typing.Optional[TracingConfig] = pydantic.Field(default=None)
+ """
+ Configuration for tracing.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_config_output.py b/sdks/python/types/rails_config_output.py
new file mode 100644
index 0000000000..be6f31da72
--- /dev/null
+++ b/sdks/python/types/rails_config_output.py
@@ -0,0 +1,96 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .instruction import Instruction
+from .model import Model
+from .rails_output import RailsOutput
+from .task_prompt import TaskPrompt
+from .tracing_config import TracingConfig
+
+
+class RailsConfigOutput(UniversalBaseModel):
+ """
+ Configuration object for the models and the rails.
+ """
+
+ models: typing.Optional[typing.List[Model]] = pydantic.Field(default=None)
+ """
+ The list of models used by the rails configuration.
+ """
+
+ instructions: typing.Optional[typing.List[Instruction]] = pydantic.Field(default=None)
+ """
+ List of instructions in natural language that the LLM should use.
+ """
+
+ actions_server_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The URL of the actions server that should be used for the rails.
+ """
+
+ sample_conversation: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The sample conversation that should be used inside the prompts.
+ """
+
+ prompts: typing.Optional[typing.List[TaskPrompt]] = pydantic.Field(default=None)
+ """
+ The prompts that should be used for the various LLM tasks.
+ """
+
+ prompting_mode: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Allows choosing between different prompting strategies.
+ """
+
+ lowest_temperature: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The lowest temperature that should be used for the LLM.
+ """
+
+ enable_multi_step_generation: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable multi-step generation for the LLM.
+ """
+
+ colang_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The Colang version to use.
+ """
+
+ custom_data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Any custom configuration data that might be needed.
+ """
+
+ rails: typing.Optional[RailsOutput] = pydantic.Field(default=None)
+ """
+ Configuration for the various rails (input, output, etc.).
+ """
+
+ enable_rails_exceptions: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If set, the pre-defined guardrails raise exceptions instead of returning pre-defined messages.
+ """
+
+ passthrough: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether the original prompt should pass through the guardrails configuration as is. This means it will not be altered in any way.
+ """
+
+ tracing: typing.Optional[TracingConfig] = pydantic.Field(default=None)
+ """
+ Configuration for tracing.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_input.py b/sdks/python/types/rails_input.py
new file mode 100644
index 0000000000..a2f341ed82
--- /dev/null
+++ b/sdks/python/types/rails_input.py
@@ -0,0 +1,69 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .action_rails import ActionRails
+from .dialog_rails import DialogRails
+from .input_rails import InputRails
+from .output_rails import OutputRails
+from .rails_config_data_input import RailsConfigDataInput
+from .retrieval_rails import RetrievalRails
+from .tool_input_rails import ToolInputRails
+from .tool_output_rails import ToolOutputRails
+
+
+class RailsInput(UniversalBaseModel):
+ """
+ Configuration of specific rails.
+ """
+
+ config: typing.Optional[RailsConfigDataInput] = pydantic.Field(default=None)
+ """
+ Configuration data for specific rails that are supported out-of-the-box.
+ """
+
+ input: typing.Optional[InputRails] = pydantic.Field(default=None)
+ """
+ Configuration of the input rails.
+ """
+
+ output: typing.Optional[OutputRails] = pydantic.Field(default=None)
+ """
+ Configuration of the output rails.
+ """
+
+ retrieval: typing.Optional[RetrievalRails] = pydantic.Field(default=None)
+ """
+ Configuration of the retrieval rails.
+ """
+
+ dialog: typing.Optional[DialogRails] = pydantic.Field(default=None)
+ """
+ Configuration of the dialog rails.
+ """
+
+ actions: typing.Optional[ActionRails] = pydantic.Field(default=None)
+ """
+ Configuration of action rails.
+ """
+
+ tool_output: typing.Optional[ToolOutputRails] = pydantic.Field(default=None)
+ """
+ Configuration of tool output rails.
+ """
+
+ tool_input: typing.Optional[ToolInputRails] = pydantic.Field(default=None)
+ """
+ Configuration of tool input rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/rails_output.py b/sdks/python/types/rails_output.py
new file mode 100644
index 0000000000..3b3390fa39
--- /dev/null
+++ b/sdks/python/types/rails_output.py
@@ -0,0 +1,69 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .action_rails import ActionRails
+from .dialog_rails import DialogRails
+from .input_rails import InputRails
+from .output_rails import OutputRails
+from .rails_config_data_output import RailsConfigDataOutput
+from .retrieval_rails import RetrievalRails
+from .tool_input_rails import ToolInputRails
+from .tool_output_rails import ToolOutputRails
+
+
+class RailsOutput(UniversalBaseModel):
+ """
+ Configuration of specific rails.
+ """
+
+ config: typing.Optional[RailsConfigDataOutput] = pydantic.Field(default=None)
+ """
+ Configuration data for specific rails that are supported out-of-the-box.
+ """
+
+ input: typing.Optional[InputRails] = pydantic.Field(default=None)
+ """
+ Configuration of the input rails.
+ """
+
+ output: typing.Optional[OutputRails] = pydantic.Field(default=None)
+ """
+ Configuration of the output rails.
+ """
+
+ retrieval: typing.Optional[RetrievalRails] = pydantic.Field(default=None)
+ """
+ Configuration of the retrieval rails.
+ """
+
+ dialog: typing.Optional[DialogRails] = pydantic.Field(default=None)
+ """
+ Configuration of the dialog rails.
+ """
+
+ actions: typing.Optional[ActionRails] = pydantic.Field(default=None)
+ """
+ Configuration of action rails.
+ """
+
+ tool_output: typing.Optional[ToolOutputRails] = pydantic.Field(default=None)
+ """
+ Configuration of tool output rails.
+ """
+
+ tool_input: typing.Optional[ToolInputRails] = pydantic.Field(default=None)
+ """
+ Configuration of tool input rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/reasoning_config.py b/sdks/python/types/reasoning_config.py
new file mode 100644
index 0000000000..c3ffc7724a
--- /dev/null
+++ b/sdks/python/types/reasoning_config.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ReasoningConfig(UniversalBaseModel):
+ """
+ Configuration for reasoning mode in content safety models.
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, enable reasoning mode (with traces) for content safety models. If False, use low-latency mode without reasoning traces.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/regex_detection.py b/sdks/python/types/regex_detection.py
new file mode 100644
index 0000000000..8177c2554c
--- /dev/null
+++ b/sdks/python/types/regex_detection.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .regex_detection_options import RegexDetectionOptions
+
+
+class RegexDetection(UniversalBaseModel):
+ """
+ Configuration for regex pattern detection.
+ """
+
+ input: typing.Optional[RegexDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration for regex patterns to detect on user input.
+ """
+
+ output: typing.Optional[RegexDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration for regex patterns to detect on bot output.
+ """
+
+ retrieval: typing.Optional[RegexDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration for regex patterns to detect on retrieved relevant chunks.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/regex_detection_options.py b/sdks/python/types/regex_detection_options.py
new file mode 100644
index 0000000000..4b8ea3a992
--- /dev/null
+++ b/sdks/python/types/regex_detection_options.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class RegexDetectionOptions(UniversalBaseModel):
+ """
+ Configuration options for regex pattern detection on a specific source.
+ """
+
+ patterns: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ List of regex patterns to match against the text.
+ """
+
+ case_insensitive: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to perform case-insensitive matching.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/retrieval_rails.py b/sdks/python/types/retrieval_rails.py
new file mode 100644
index 0000000000..6d3ac70a18
--- /dev/null
+++ b/sdks/python/types/retrieval_rails.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class RetrievalRails(UniversalBaseModel):
+ """
+ Configuration of retrieval rails.
+ """
+
+ flows: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all the flows that implement retrieval rails.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/role_binding.py b/sdks/python/types/role_binding.py
new file mode 100644
index 0000000000..ada8604be1
--- /dev/null
+++ b/sdks/python/types/role_binding.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class RoleBinding(UniversalBaseModel):
+ """
+ Role binding response model.
+ """
+
+ id: str
+ name: str
+ principal: str
+ workspace: str
+ role: str
+ granted_by: str
+ granted_at: dt.datetime
+ revoked_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/role_binding_filter.py b/sdks/python/types/role_binding_filter.py
new file mode 100644
index 0000000000..073df508a1
--- /dev/null
+++ b/sdks/python/types/role_binding_filter.py
@@ -0,0 +1,60 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .date_range_filter import DateRangeFilter
+from .role_binding_filter_granted_by import RoleBindingFilterGrantedBy
+from .role_binding_filter_principal import RoleBindingFilterPrincipal
+from .role_binding_filter_role import RoleBindingFilterRole
+
+
+class RoleBindingFilter(UniversalBaseModel):
+ """
+ Filter for role bindings.
+ """
+
+ principal: typing.Optional[RoleBindingFilterPrincipal] = pydantic.Field(default=None)
+ """
+ Filter by principal ID
+ """
+
+ workspace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by workspace
+ """
+
+ role: typing.Optional[RoleBindingFilterRole] = pydantic.Field(default=None)
+ """
+ Filter by role
+ """
+
+ granted_by: typing.Optional[RoleBindingFilterGrantedBy] = pydantic.Field(default=None)
+ """
+ Filter by who granted the role
+ """
+
+ is_active: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Filter for active (True) or revoked (False) bindings
+ """
+
+ granted_at: typing.Optional[DateRangeFilter] = pydantic.Field(default=None)
+ """
+ Filter by granted date range
+ """
+
+ revoked_at: typing.Optional[DateRangeFilter] = pydantic.Field(default=None)
+ """
+ Filter by revoked date range
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/role_binding_filter_granted_by.py b/sdks/python/types/role_binding_filter_granted_by.py
new file mode 100644
index 0000000000..d584d4a58d
--- /dev/null
+++ b/sdks/python/types/role_binding_filter_granted_by.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+RoleBindingFilterGrantedBy = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/role_binding_filter_principal.py b/sdks/python/types/role_binding_filter_principal.py
new file mode 100644
index 0000000000..c8206b30cb
--- /dev/null
+++ b/sdks/python/types/role_binding_filter_principal.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+RoleBindingFilterPrincipal = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/role_binding_filter_role.py b/sdks/python/types/role_binding_filter_role.py
new file mode 100644
index 0000000000..e85e6b2b3d
--- /dev/null
+++ b/sdks/python/types/role_binding_filter_role.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .string_filter import StringFilter
+
+RoleBindingFilterRole = typing.Union[StringFilter, str]
diff --git a/sdks/python/types/role_bindings_page.py b/sdks/python/types/role_bindings_page.py
new file mode 100644
index 0000000000..5fc5b43670
--- /dev/null
+++ b/sdks/python/types/role_bindings_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .role_binding import RoleBinding
+
+
+class RoleBindingsPage(UniversalBaseModel):
+ data: typing.List[RoleBinding]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/s3storage_config.py b/sdks/python/types/s3storage_config.py
new file mode 100644
index 0000000000..313edd8988
--- /dev/null
+++ b/sdks/python/types/s3storage_config.py
@@ -0,0 +1,64 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .s3storage_config_signature_version import S3StorageConfigSignatureVersion
+from .secret_ref import SecretRef
+
+
+class S3StorageConfig(UniversalBaseModel):
+ read_chunk_size: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Chunk size in bytes for reading/streaming files. Larger chunks reduce async overhead but increase memory per concurrent download. Default: 1MB.
+ """
+
+ bucket: str = pydantic.Field()
+ """
+ S3 bucket name
+ """
+
+ prefix: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional prefix (folder path) within the bucket. All operations will be relative to this prefix.
+ """
+
+ region: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ AWS region. If not specified, uses SDK default (env vars, instance metadata, etc.)
+ """
+
+ endpoint_url: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Custom endpoint URL for S3-compatible storage (e.g., MinIO, Garage, RustFS). If not specified, uses AWS S3.
+ """
+
+ use_sdk_auth: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Use AWS SDK credential chain for authentication (env vars like AWS_ACCESS_KEY_ID, IAM roles, instance profiles, etc.). This option is only available for the platform's default storage backend. User-provided S3 storage must use explicit credentials via access_key_id_secret and secret_access_key_secret.
+ """
+
+ access_key_id_secret: typing.Optional[SecretRef] = pydantic.Field(default=None)
+ """
+ Secret reference for AWS access key ID. Requires use_sdk_auth=False.
+ """
+
+ secret_access_key_secret: typing.Optional[SecretRef] = pydantic.Field(default=None)
+ """
+ Secret reference for AWS secret access key. Requires use_sdk_auth=False.
+ """
+
+ signature_version: typing.Optional[S3StorageConfigSignatureVersion] = pydantic.Field(default=None)
+ """
+ AWS signature version for request signing. Use 's3' for legacy systems that only support signature v2.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/s3storage_config_signature_version.py b/sdks/python/types/s3storage_config_signature_version.py
new file mode 100644
index 0000000000..4972af8565
--- /dev/null
+++ b/sdks/python/types/s3storage_config_signature_version.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+S3StorageConfigSignatureVersion = typing.Union[typing.Literal["s3v4", "s3"], typing.Any]
diff --git a/sdks/python/types/secret_ref.py b/sdks/python/types/secret_ref.py
new file mode 100644
index 0000000000..ec98d7bc60
--- /dev/null
+++ b/sdks/python/types/secret_ref.py
@@ -0,0 +1,6 @@
+# This file was auto-generated by Fern from our API Definition.
+
+SecretRef = str
+"""
+Reference to a secret. Format: 'secret_name' (uses request workspace) or 'workspace/secret_name' (explicit workspace).
+"""
diff --git a/sdks/python/types/sensitive_data_detection.py b/sdks/python/types/sensitive_data_detection.py
new file mode 100644
index 0000000000..5586ec40d9
--- /dev/null
+++ b/sdks/python/types/sensitive_data_detection.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .sensitive_data_detection_options import SensitiveDataDetectionOptions
+
+
+class SensitiveDataDetection(UniversalBaseModel):
+ """
+ Configuration of what sensitive data should be detected.
+ """
+
+ recognizers: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ Additional custom recognizers. Check out https://microsoft.github.io/presidio/tutorial/08_no_code/ for more details.
+ """
+
+ input: typing.Optional[SensitiveDataDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the user input.
+ """
+
+ output: typing.Optional[SensitiveDataDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on the bot output.
+ """
+
+ retrieval: typing.Optional[SensitiveDataDetectionOptions] = pydantic.Field(default=None)
+ """
+ Configuration of the entities to be detected on retrieved relevant chunks.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/sensitive_data_detection_options.py b/sdks/python/types/sensitive_data_detection_options.py
new file mode 100644
index 0000000000..2e54968b19
--- /dev/null
+++ b/sdks/python/types/sensitive_data_detection_options.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SensitiveDataDetectionOptions(UniversalBaseModel):
+ entities: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The list of entities that should be detected. Check out https://microsoft.github.io/presidio/supported_entities/ forthe list of supported entities.
+ """
+
+ mask_token: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The token that should be used to mask the sensitive data.
+ """
+
+ score_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The score threshold that should be used to detect the sensitive data.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/served_model_mapping.py b/sdks/python/types/served_model_mapping.py
new file mode 100644
index 0000000000..14906763c2
--- /dev/null
+++ b/sdks/python/types/served_model_mapping.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ServedModelMapping(UniversalBaseModel):
+ """
+ Mapping between a Model Entity and how it's served by this provider.
+ """
+
+ model_entity_id: str = pydantic.Field()
+ """
+ Model Entity identifier as workspace/name (e.g., 'my-ws/my-model')
+ """
+
+ served_model_name: str = pydantic.Field()
+ """
+ The actual model name to send to the backend endpoint in the 'model' field
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/single_call_config.py b/sdks/python/types/single_call_config.py
new file mode 100644
index 0000000000..109682c703
--- /dev/null
+++ b/sdks/python/types/single_call_config.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SingleCallConfig(UniversalBaseModel):
+ """
+ Configuration for the single LLM call option for topical rails.
+ """
+
+ enabled: typing.Optional[bool] = None
+ fallback_to_multiple_calls: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to fall back to multiple calls if a single call is not possible.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/sliding_window_config.py b/sdks/python/types/sliding_window_config.py
new file mode 100644
index 0000000000..535f9c652c
--- /dev/null
+++ b/sdks/python/types/sliding_window_config.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SlidingWindowConfig(UniversalBaseModel):
+ """
+ Sliding window attention configuration.
+ """
+
+ window_size: int = pydantic.Field()
+ """
+ Sliding window size (attends to last N tokens)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/span.py b/sdks/python/types/span.py
new file mode 100644
index 0000000000..d1f99ca194
--- /dev/null
+++ b/sdks/python/types/span.py
@@ -0,0 +1,58 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .span_evaluation_context import SpanEvaluationContext
+from .span_kind import SpanKind
+from .span_status import SpanStatus
+
+
+class Span(UniversalBaseModel):
+ span_id: str
+ session_id: str
+ workspace: str
+ project: typing.Optional[str] = None
+ evaluation_context: typing.Optional[SpanEvaluationContext] = None
+ parent_span_id: typing.Optional[str] = None
+ kind: SpanKind
+ name: typing.Optional[str] = None
+ source: str
+ trace_id: typing.Optional[str] = None
+ started_at: dt.datetime
+ ended_at: typing.Optional[dt.datetime] = None
+ status: SpanStatus
+ error_type: typing.Optional[str] = None
+ error_message: typing.Optional[str] = None
+ provider: typing.Optional[str] = None
+ model: typing.Optional[str] = None
+ prompt_id: typing.Optional[str] = None
+ prompt_name: typing.Optional[str] = None
+ prompt_version: typing.Optional[str] = None
+ agent_id: typing.Optional[str] = None
+ agent_name: typing.Optional[str] = None
+ tool_name: typing.Optional[str] = None
+ input_tokens: typing.Optional[int] = None
+ output_tokens: typing.Optional[int] = None
+ cached_tokens: typing.Optional[int] = None
+ total_tokens: typing.Optional[int] = None
+ usage_details: typing.Optional[typing.Dict[str, int]] = None
+ cost_total_usd: typing.Optional[float] = None
+ cost_input_usd: typing.Optional[float] = None
+ cost_output_usd: typing.Optional[float] = None
+ cost_details: typing.Optional[typing.Dict[str, float]] = None
+ input: typing.Optional[str] = None
+ output: typing.Optional[str] = None
+ raw_attributes: typing.Optional[str] = None
+ ingested_at: dt.datetime
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/span_evaluation_context.py b/sdks/python/types/span_evaluation_context.py
new file mode 100644
index 0000000000..cb5bf4a17e
--- /dev/null
+++ b/sdks/python/types/span_evaluation_context.py
@@ -0,0 +1,26 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SpanEvaluationContext(UniversalBaseModel):
+ evaluation_id: typing.Optional[str] = None
+ evaluation_sha: typing.Optional[str] = None
+ evaluation_run_id: typing.Optional[str] = None
+ dataset_id: typing.Optional[str] = None
+ dataset_name: typing.Optional[str] = None
+ dataset_version: typing.Optional[str] = None
+ test_case_id: typing.Optional[str] = None
+ metadata: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/span_filter.py b/sdks/python/types/span_filter.py
new file mode 100644
index 0000000000..9bdd0c0bac
--- /dev/null
+++ b/sdks/python/types/span_filter.py
@@ -0,0 +1,130 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .span_kind import SpanKind
+from .span_status import SpanStatus
+
+
+class SpanFilter(UniversalBaseModel):
+ session_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by span session id.
+ """
+
+ trace_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by canonical trace id.
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by project name.
+ """
+
+ evaluation_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by evaluation id.
+ """
+
+ evaluation_sha: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by evaluation sha.
+ """
+
+ evaluation_run_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by evaluation run id. ATIF evaluation context is stored on root trajectory spans; use session_id from a matched root to fetch the full trace tree.
+ """
+
+ dataset_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by dataset id.
+ """
+
+ dataset_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by dataset name.
+ """
+
+ dataset_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by dataset version.
+ """
+
+ test_case_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by dataset test case id.
+ """
+
+ source: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by ingest source (e.g. 'otel', 'atif', 'chat_completions').
+ """
+
+ kind: typing.Optional[SpanKind] = pydantic.Field(default=None)
+ """
+ Filter by normalized span kind.
+ """
+
+ status: typing.Optional[SpanStatus] = pydantic.Field(default=None)
+ """
+ Filter by normalized span status.
+ """
+
+ model: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by model name.
+ """
+
+ tool_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by tool name.
+ """
+
+ provider: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by provider (e.g. 'openai', 'nim', 'anthropic').
+ """
+
+ agent_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by agent identifier.
+ """
+
+ agent_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by agent application name (e.g. 'claude-code', 'codex').
+ """
+
+ prompt_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by prompt template name.
+ """
+
+ prompt_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by prompt template version.
+ """
+
+ parent_span_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by parent span id. Use to fetch direct children of a span.
+ """
+
+ started_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by span start timestamp.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/span_kind.py b/sdks/python/types/span_kind.py
new file mode 100644
index 0000000000..b57bbc5381
--- /dev/null
+++ b/sdks/python/types/span_kind.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+SpanKind = typing.Union[
+ typing.Literal[
+ "LLM", "CHAIN", "TOOL", "RETRIEVER", "EMBEDDING", "AGENT", "RERANKER", "EVALUATOR", "GUARDRAIL", "UNKNOWN"
+ ],
+ typing.Any,
+]
diff --git a/sdks/python/types/span_sort_field.py b/sdks/python/types/span_sort_field.py
new file mode 100644
index 0000000000..9787a3ffed
--- /dev/null
+++ b/sdks/python/types/span_sort_field.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+SpanSortField = typing.Union[typing.Literal["started_at", "-started_at"], typing.Any]
diff --git a/sdks/python/types/span_status.py b/sdks/python/types/span_status.py
new file mode 100644
index 0000000000..1258bf9e61
--- /dev/null
+++ b/sdks/python/types/span_status.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+SpanStatus = typing.Union[typing.Literal["success", "error", "cancelled", "unknown"], typing.Any]
diff --git a/sdks/python/types/spans_page.py b/sdks/python/types/spans_page.py
new file mode 100644
index 0000000000..6b410d139a
--- /dev/null
+++ b/sdks/python/types/spans_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .span import Span
+
+
+class SpansPage(UniversalBaseModel):
+ data: typing.List[Span]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/status_enum.py b/sdks/python/types/status_enum.py
new file mode 100644
index 0000000000..dc3bdc4755
--- /dev/null
+++ b/sdks/python/types/status_enum.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+StatusEnum = typing.Union[typing.Literal["blocked", "success", "unknown"], typing.Any]
diff --git a/sdks/python/types/step_lifecycle.py b/sdks/python/types/step_lifecycle.py
new file mode 100644
index 0000000000..65affdd442
--- /dev/null
+++ b/sdks/python/types/step_lifecycle.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class StepLifecycle(UniversalBaseModel):
+ """
+ Controller-level lifecycle configuration for a job step.
+
+ These settings control how the jobs controller manages the step,
+ as opposed to ``config`` which is the task payload forwarded to
+ the container.
+ """
+
+ staleness_timeout_seconds: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ If every active task in the step goes this many seconds without an update, the step is terminated. A value of 0 disables staleness detection.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/storage_config_type.py b/sdks/python/types/storage_config_type.py
new file mode 100644
index 0000000000..7e0d7e860a
--- /dev/null
+++ b/sdks/python/types/storage_config_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+StorageConfigType = typing.Union[typing.Literal["local", "ngc", "huggingface", "s3"], typing.Any]
diff --git a/sdks/python/types/string_filter.py b/sdks/python/types/string_filter.py
new file mode 100644
index 0000000000..ccfa28476e
--- /dev/null
+++ b/sdks/python/types/string_filter.py
@@ -0,0 +1,40 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class StringFilter(UniversalBaseModel):
+ eq: typing_extensions.Annotated[
+ typing.Optional[str],
+ FieldMetadata(alias="$eq"),
+ pydantic.Field(alias="$eq", description="Filter for results equal to this value."),
+ ] = None
+ like: typing_extensions.Annotated[
+ typing.Optional[str],
+ FieldMetadata(alias="$like"),
+ pydantic.Field(alias="$like", description="Filter for results matching this pattern."),
+ ] = None
+ in_: typing_extensions.Annotated[
+ typing.Optional[typing.List[str]],
+ FieldMetadata(alias="$in"),
+ pydantic.Field(alias="$in", description="Filter for results in this list of values."),
+ ] = None
+ nin: typing_extensions.Annotated[
+ typing.Optional[typing.List[str]],
+ FieldMetadata(alias="$nin"),
+ pydantic.Field(alias="$nin", description="Filter for results not in this list of values."),
+ ] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/subprocess_execution_provider.py b/sdks/python/types/subprocess_execution_provider.py
new file mode 100644
index 0000000000..ae4be68734
--- /dev/null
+++ b/sdks/python/types/subprocess_execution_provider.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SubprocessExecutionProvider(UniversalBaseModel):
+ """
+ Host subprocess execution provider.
+ """
+
+ profile: typing.Optional[str] = None
+ command: typing.List[str]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/subprocess_job_execution_profile.py b/sdks/python/types/subprocess_job_execution_profile.py
new file mode 100644
index 0000000000..526498e05c
--- /dev/null
+++ b/sdks/python/types/subprocess_job_execution_profile.py
@@ -0,0 +1,30 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .subprocess_job_execution_profile_config import SubprocessJobExecutionProfileConfig
+from .subprocess_job_execution_profile_provider import SubprocessJobExecutionProfileProvider
+
+
+class SubprocessJobExecutionProfile(UniversalBaseModel):
+ provider: typing.Optional[SubprocessJobExecutionProfileProvider] = None
+ profile: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The profile name for the executor, e.g., high_priority_a100, low_priority, etc.
+ """
+
+ config: typing.Optional[SubprocessJobExecutionProfileConfig] = pydantic.Field(default=None)
+ """
+ Additional configuration for the subprocess executor
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/subprocess_job_execution_profile_config.py b/sdks/python/types/subprocess_job_execution_profile_config.py
new file mode 100644
index 0000000000..bba025ed64
--- /dev/null
+++ b/sdks/python/types/subprocess_job_execution_profile_config.py
@@ -0,0 +1,45 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class SubprocessJobExecutionProfileConfig(UniversalBaseModel):
+ ttl_seconds_before_active: typing.Optional[int] = None
+ ttl_seconds_active: typing.Optional[int] = None
+ ttl_seconds_after_finished: typing.Optional[int] = None
+ cleanup_completed_jobs_immediately: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Keep subprocess working directories by default so runs remain inspectable.
+ """
+
+ launcher_tool_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Path to the jobs launcher tool
+ """
+
+ env: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Optional env vars applied to all jobs (e.g. HOME=/tmp). Keys must not conflict with platform-reserved names. Job steps may override these variables.
+ """
+
+ working_directory: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Root directory for subprocess job state, config, storage, and logs.
+ """
+
+ graceful_shutdown_timeout_seconds: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ How long to wait after SIGTERM before force killing the process group.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/subprocess_job_execution_profile_provider.py b/sdks/python/types/subprocess_job_execution_profile_provider.py
new file mode 100644
index 0000000000..65b168c226
--- /dev/null
+++ b/sdks/python/types/subprocess_job_execution_profile_provider.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+SubprocessJobExecutionProfileProvider = typing.Union[typing.Literal["subprocess"], typing.Any]
diff --git a/sdks/python/types/task_prompt.py b/sdks/python/types/task_prompt.py
new file mode 100644
index 0000000000..3043f3043b
--- /dev/null
+++ b/sdks/python/types/task_prompt.py
@@ -0,0 +1,67 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .task_prompt_messages_item import TaskPromptMessagesItem
+
+
+class TaskPrompt(UniversalBaseModel):
+ """
+ Configuration for prompts that will be used for a specific task.
+ """
+
+ task: str = pydantic.Field()
+ """
+ The id of the task associated with this prompt.
+ """
+
+ content: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The content of the prompt, if it's a string.
+ """
+
+ messages: typing.Optional[typing.List[TaskPromptMessagesItem]] = pydantic.Field(default=None)
+ """
+ The list of messages included in the prompt. Used for chat models.
+ """
+
+ models: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ If specified, the prompt will be used only for the given LLM engines/models. The format is a list of strings with the format: or /.
+ """
+
+ output_parser: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the output parser to use for this prompt.
+ """
+
+ max_length: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The maximum length of the prompt in number of characters.
+ """
+
+ mode: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Corresponds to the `prompting_mode` for which this prompt is fetched. Default is 'standard'.
+ """
+
+ stop: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ If specified, will be configure stop tokens for models that support this.
+ """
+
+ max_tokens: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ The maximum number of tokens that can be generated in the chat completion.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/task_prompt_messages_item.py b/sdks/python/types/task_prompt_messages_item.py
new file mode 100644
index 0000000000..5996269e94
--- /dev/null
+++ b/sdks/python/types/task_prompt_messages_item.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from .message_template import MessageTemplate
+
+TaskPromptMessagesItem = typing.Union[MessageTemplate, str]
diff --git a/sdks/python/types/tool_call_config.py b/sdks/python/types/tool_call_config.py
new file mode 100644
index 0000000000..16cb7d6308
--- /dev/null
+++ b/sdks/python/types/tool_call_config.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ToolCallConfig(UniversalBaseModel):
+ """
+ Configuration for tool calling support in NIM deployments.
+ """
+
+ tool_call_parser: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Name of the tool call parser to use (e.g., 'openai', 'hermes', 'pythonic', 'llama3_json', 'mistral').
+ """
+
+ tool_call_plugin: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Reference to a fileset containing the custom tool call plugin Python file. Expected format: '{workspace}/{fileset_name}'. The fileset is mounted separately from the model checkpoint at deployment time.
+ """
+
+ auto_tool_choice: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable automatic tool choice. When enabled, the model can decide to call tools without explicit user instruction.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/tool_calling_metadata_content.py b/sdks/python/types/tool_calling_metadata_content.py
new file mode 100644
index 0000000000..14a0e05b59
--- /dev/null
+++ b/sdks/python/types/tool_calling_metadata_content.py
@@ -0,0 +1,44 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ToolCallingMetadataContent(UniversalBaseModel):
+ """
+ Content for tool-calling configuration on model filesets.
+
+ Stores chat template and tool calling settings that are merged into
+ the ModelSpec during checkpoint analysis.
+ """
+
+ chat_template: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Jinja2 chat template for the model.
+ """
+
+ tool_call_parser: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Name of the tool call parser (e.g., 'openai', 'hermes', 'pythonic', 'llama3_json', 'mistral').
+ """
+
+ tool_call_plugin: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Reference to a fileset containing a custom tool call plugin Python file. Expected format: '{workspace}/{fileset_name}'.
+ """
+
+ auto_tool_choice: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable automatic tool choice.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/tool_input_rails.py b/sdks/python/types/tool_input_rails.py
new file mode 100644
index 0000000000..a5948827b0
--- /dev/null
+++ b/sdks/python/types/tool_input_rails.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ToolInputRails(UniversalBaseModel):
+ """
+ Configuration of tool input rails.
+ Tool input rails are applied to tool results before they are processed.
+ They can validate, filter, or transform tool outputs for security and safety.
+ """
+
+ flows: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all the flows that implement tool input rails.
+ """
+
+ parallel: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, the tool input rails are executed in parallel.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/tool_output_rails.py b/sdks/python/types/tool_output_rails.py
new file mode 100644
index 0000000000..139a3e1096
--- /dev/null
+++ b/sdks/python/types/tool_output_rails.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ToolOutputRails(UniversalBaseModel):
+ """
+ Configuration of tool output rails.
+ Tool output rails are applied to tool calls before they are executed.
+ They can validate tool names, parameters, and context to ensure safe tool usage.
+ """
+
+ flows: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ The names of all the flows that implement tool output rails.
+ """
+
+ parallel: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, the tool output rails are executed in parallel.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/trace.py b/sdks/python/types/trace.py
new file mode 100644
index 0000000000..3f2659cca2
--- /dev/null
+++ b/sdks/python/types/trace.py
@@ -0,0 +1,40 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .span_evaluation_context import SpanEvaluationContext
+from .span_status import SpanStatus
+
+
+class Trace(UniversalBaseModel):
+ id: str
+ root_span_id: typing.Optional[str] = None
+ session_id: str
+ workspace: str
+ name: typing.Optional[str] = None
+ evaluation_context: typing.Optional[SpanEvaluationContext] = None
+ started_at: dt.datetime
+ ended_at: typing.Optional[dt.datetime] = None
+ duration_ms: typing.Optional[float] = None
+ status: SpanStatus
+ input_tokens: typing.Optional[int] = None
+ output_tokens: typing.Optional[int] = None
+ cached_tokens: typing.Optional[int] = None
+ total_tokens: typing.Optional[int] = None
+ cost_usd: typing.Optional[float] = None
+ cost_input_usd: typing.Optional[float] = None
+ cost_output_usd: typing.Optional[float] = None
+ span_count: typing.Optional[int] = None
+ error_count: typing.Optional[int] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/trace_filter.py b/sdks/python/types/trace_filter.py
new file mode 100644
index 0000000000..46156b26ef
--- /dev/null
+++ b/sdks/python/types/trace_filter.py
@@ -0,0 +1,74 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .datetime_filter import DatetimeFilter
+from .span_status import SpanStatus
+
+
+class TraceFilter(UniversalBaseModel):
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by canonical Intake trace id.
+ """
+
+ session_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by session id.
+ """
+
+ status: typing.Optional[SpanStatus] = pydantic.Field(default=None)
+ """
+ Filter by rolled-up trace status.
+ """
+
+ started_at: typing.Optional[DatetimeFilter] = pydantic.Field(default=None)
+ """
+ Filter by root span start timestamp.
+ """
+
+ evaluation_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span evaluation id.
+ """
+
+ evaluation_sha: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span evaluation sha.
+ """
+
+ evaluation_run_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span evaluation run id.
+ """
+
+ dataset_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span dataset id.
+ """
+
+ dataset_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span dataset name.
+ """
+
+ dataset_version: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span dataset version.
+ """
+
+ test_case_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter by root-span dataset test case id.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/trace_sort_field.py b/sdks/python/types/trace_sort_field.py
new file mode 100644
index 0000000000..b71102a710
--- /dev/null
+++ b/sdks/python/types/trace_sort_field.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+TraceSortField = typing.Union[typing.Literal["started_at", "-started_at"], typing.Any]
diff --git a/sdks/python/types/traces_page.py b/sdks/python/types/traces_page.py
new file mode 100644
index 0000000000..6e63e255d9
--- /dev/null
+++ b/sdks/python/types/traces_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .trace import Trace
+
+
+class TracesPage(UniversalBaseModel):
+ data: typing.List[Trace]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/tracing_config.py b/sdks/python/types/tracing_config.py
new file mode 100644
index 0000000000..9e476aff84
--- /dev/null
+++ b/sdks/python/types/tracing_config.py
@@ -0,0 +1,34 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .log_adapter_config import LogAdapterConfig
+
+
+class TracingConfig(UniversalBaseModel):
+ enabled: typing.Optional[bool] = None
+ adapters: typing.Optional[typing.List[LogAdapterConfig]] = pydantic.Field(default=None)
+ """
+ The list of tracing adapters to use. If not specified, the default adapters are used.
+ """
+
+ span_format: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The span format to use. Options are 'legacy' (simple metrics) or 'opentelemetry' (OpenTelemetry semantic conventions).
+ """
+
+ enable_content_capture: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Capture prompts and responses (user/assistant/tool message content) in tracing/telemetry events. Disabled by default for privacy and alignment with OpenTelemetry GenAI semantic conventions. WARNING: Enabling this may include PII and sensitive data in your telemetry backend.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/trend_micro_rail_config.py b/sdks/python/types/trend_micro_rail_config.py
new file mode 100644
index 0000000000..fa443fe250
--- /dev/null
+++ b/sdks/python/types/trend_micro_rail_config.py
@@ -0,0 +1,46 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+import typing_extensions
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ..core.serialization import FieldMetadata
+
+
+class TrendMicroRailConfig(UniversalBaseModel):
+ """
+ Configuration data for the Trend Micro AI Guard API
+ """
+
+ v1url: typing_extensions.Annotated[
+ typing.Optional[str],
+ FieldMetadata(alias="v1_url"),
+ pydantic.Field(
+ alias="v1_url",
+ description="The endpoint for the Trend Micro AI Guard API. For other regions, use: https://api.{region}.xdr.trendmicro.com/v3.0/aiSecurity/applyGuardrails where region is eu, jp, au, in, sg, or mea.",
+ ),
+ ] = None
+ api_key_env_var: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Environment variable containing API key for Trend Micro AI Guard
+ """
+
+ application_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Application name for TMV1-Application-Name header (REQUIRED). Must contain only letters, numbers, hyphens, and underscores, with a maximum length of 64 characters.
+ """
+
+ detailed_response: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ If True, returns detailed AI Guard results with confidence scores (Prefer: return=representation). If False, returns minimal response with only action and reasons (Prefer: return=minimal).
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/update_adapter_request.py b/sdks/python/types/update_adapter_request.py
new file mode 100644
index 0000000000..9d9577947f
--- /dev/null
+++ b/sdks/python/types/update_adapter_request.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class UpdateAdapterRequest(UniversalBaseModel):
+ """
+ Request model for updating Adapter Sub Entity metadata.
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description of the adapter
+ """
+
+ enabled: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to make this adapter available for inference post training
+ """
+
+ fileset: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Updated fileset for the adapter
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/user_messages_config.py b/sdks/python/types/user_messages_config.py
new file mode 100644
index 0000000000..19538c07ad
--- /dev/null
+++ b/sdks/python/types/user_messages_config.py
@@ -0,0 +1,36 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class UserMessagesConfig(UniversalBaseModel):
+ """
+ Configuration for how the user messages are interpreted.
+ """
+
+ embeddings_only: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to use only embeddings for computing the user canonical form messages.
+ """
+
+ embeddings_only_similarity_threshold: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ The similarity threshold to use when using only embeddings for computing the user canonical form messages.
+ """
+
+ embeddings_only_fallback_intent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Defines the fallback intent when the similarity is below the threshold. If set to None, the user intent is computed normally using the LLM. If set to a string value, that string is used as the intent.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/validation_error.py b/sdks/python/types/validation_error.py
new file mode 100644
index 0000000000..b68edee99c
--- /dev/null
+++ b/sdks/python/types/validation_error.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .validation_error_loc_item import ValidationErrorLocItem
+
+
+class ValidationError(UniversalBaseModel):
+ loc: typing.List[ValidationErrorLocItem]
+ msg: str
+ type: str
+ input: typing.Optional[typing.Any] = None
+ ctx: typing.Optional[typing.Dict[str, typing.Any]] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/validation_error_loc_item.py b/sdks/python/types/validation_error_loc_item.py
new file mode 100644
index 0000000000..9a0a83fef5
--- /dev/null
+++ b/sdks/python/types/validation_error_loc_item.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ValidationErrorLocItem = typing.Union[str, int]
diff --git a/sdks/python/types/virtual_model.py b/sdks/python/types/virtual_model.py
new file mode 100644
index 0000000000..8b650f890b
--- /dev/null
+++ b/sdks/python/types/virtual_model.py
@@ -0,0 +1,82 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .middleware_call import MiddlewareCall
+from .virtual_model_inference_config import VirtualModelInferenceConfig
+
+
+class VirtualModel(UniversalBaseModel):
+ """
+ Logical inference route.
+
+ Maps a user-facing model name to an optional default model entity and
+ defines ordered middleware pipelines for the request, response, and
+ post-response phases.
+
+ When a caller sets ``model: "workspace/my-virtual-model"`` in an inference
+ request, IGW resolves the ``VirtualModel`` instead of a ``ModelEntity``
+ directly. If ``default_model_entity`` is set, IGW writes it into
+ ``request["model"]`` before the request middleware pipeline runs. Middleware
+ may mutate ``request["model"]`` freely. After the pipeline completes, IGW
+ reads ``request["model"]``, resolves it to a ``ModelProvider`` via the
+ ``ModelCache``, and proxies.
+
+ The ``ModelProviderReconciler`` auto-creates a passthrough ``VirtualModel``
+ for each discovered model (same workspace and name as the ``ModelEntity``,
+ empty middleware lists, ``default_model_entity`` pointing to that entity).
+ All existing inference requests continue to work without changes.
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Entity name within the workspace
+ """
+
+ workspace: str = pydantic.Field()
+ """
+ Workspace identifier
+ """
+
+ project: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The name of the project associated with this entity.
+ """
+
+ default_model_entity: typing.Optional[str] = None
+ autoprovisioned: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+ """
+
+ models: typing.Optional[typing.List[VirtualModelInferenceConfig]] = None
+ request_middleware: typing.Optional[typing.List[MiddlewareCall]] = None
+ response_middleware: typing.Optional[typing.List[MiddlewareCall]] = None
+ post_response_middleware: typing.Optional[typing.List[MiddlewareCall]] = None
+ override_proxy: typing.Optional[str] = None
+ id: typing.Optional[str] = None
+ created_at: typing.Optional[dt.datetime] = None
+ created_by: typing.Optional[str] = None
+ updated_at: typing.Optional[dt.datetime] = None
+ updated_by: typing.Optional[str] = None
+ entity_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Alias for id for backwards compatibility.
+ """
+
+ parent: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Parent entity ID for nested entities.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/virtual_model_inference_config.py b/sdks/python/types/virtual_model_inference_config.py
new file mode 100644
index 0000000000..0ef5f9efc2
--- /dev/null
+++ b/sdks/python/types/virtual_model_inference_config.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .backend_format import BackendFormat
+
+
+class VirtualModelInferenceConfig(UniversalBaseModel):
+ """
+ Inference configuration for one model entity referenced by a VirtualModel.
+ """
+
+ model: str
+ backend_format: typing.Optional[BackendFormat] = pydantic.Field(default=None)
+ """
+ Optional backend format override for this VirtualModel entry.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/virtual_models_page.py b/sdks/python/types/virtual_models_page.py
new file mode 100644
index 0000000000..23adbc27f9
--- /dev/null
+++ b/sdks/python/types/virtual_models_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .virtual_model import VirtualModel
+
+
+class VirtualModelsPage(UniversalBaseModel):
+ data: typing.List[VirtualModel]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/volcano_job_execution_profile.py b/sdks/python/types/volcano_job_execution_profile.py
new file mode 100644
index 0000000000..1a1cae6754
--- /dev/null
+++ b/sdks/python/types/volcano_job_execution_profile.py
@@ -0,0 +1,37 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .volcano_job_execution_profile_config import VolcanoJobExecutionProfileConfig
+
+
+class VolcanoJobExecutionProfile(UniversalBaseModel):
+ """
+ Volcano Job Execution Profile
+ """
+
+ provider: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The compute provider for the executor, e.g., cpu, gpu
+ """
+
+ profile: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The profile name for the executor, e.g., high_priority_a100, low_priority, etc.
+ """
+
+ config: VolcanoJobExecutionProfileConfig = pydantic.Field()
+ """
+ Additional configuration for the kubernetes executor
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/volcano_job_execution_profile_config.py b/sdks/python/types/volcano_job_execution_profile_config.py
new file mode 100644
index 0000000000..1967df91c4
--- /dev/null
+++ b/sdks/python/types/volcano_job_execution_profile_config.py
@@ -0,0 +1,129 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .compute_resources import ComputeResources
+from .image_pull_secret import ImagePullSecret
+from .kubernetes_job_storage_config import KubernetesJobStorageConfig
+from .kubernetes_object_metadata import KubernetesObjectMetadata
+
+
+class VolcanoJobExecutionProfileConfig(UniversalBaseModel):
+ """
+ Configuration for Volcano Job Execution Profile
+ """
+
+ ttl_seconds_before_active: typing.Optional[int] = None
+ ttl_seconds_active: typing.Optional[int] = None
+ ttl_seconds_after_finished: typing.Optional[int] = None
+ cleanup_completed_jobs_immediately: typing.Optional[bool] = None
+ launcher_tool_path: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Path to the jobs launcher tool
+ """
+
+ env: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Optional env vars applied to all jobs (e.g. HOME=/tmp). Keys must not conflict with platform-reserved names. Job steps may override these variables.
+ """
+
+ namespace: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Kubernetes namespace to submit the job to. If not set, it will be determined from the environment.
+ """
+
+ service_account_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Kubernetes service account name for job pods. Uses the Kubernetes default service account when set to 'default'.
+ """
+
+ tolerations: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field(default=None)
+ """
+ Tolerations for the Kubernetes job pods.
+ """
+
+ node_selector: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None)
+ """
+ Node selector for the Kubernetes job pods.
+ """
+
+ affinity: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Affinity for the Kubernetes job pods.
+ """
+
+ resources: typing.Optional[ComputeResources] = pydantic.Field(default=None)
+ """
+ Resource requests and limits for the Kubernetes job pods.
+ """
+
+ pod_security_context: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Pod security context for the Kubernetes job pods.
+ """
+
+ image_pull_secrets: typing.Optional[typing.List[ImagePullSecret]] = pydantic.Field(default=None)
+ """
+ Image pull secrets for the Kubernetes job pods.
+ """
+
+ job_metadata: typing.Optional[KubernetesObjectMetadata] = pydantic.Field(default=None)
+ """
+ Metadata to add to each job object in the Kubernetes job.
+ """
+
+ pod_metadata: typing.Optional[KubernetesObjectMetadata] = pydantic.Field(default=None)
+ """
+ Metadata to add to each pod in the Kubernetes job.
+ """
+
+ storage: typing.Optional[KubernetesJobStorageConfig] = pydantic.Field(default=None)
+ """
+ Storage configuration for the Kubernetes job pods.
+ """
+
+ num_gpus: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Number of GPUs to request for the job
+ """
+
+ scheduler_name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The scheduler name to use for the Volcano job.
+ """
+
+ launcher_image: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Container image that contains the jobs-launcher binary.
+ """
+
+ queue: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The Volcano queue to submit the job to.
+ """
+
+ max_retry: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ maxRetry indicates the maximum number of retries allowed by the job
+ """
+
+ plugins: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ plugins indicates the plugins used by Volcano when the job is scheduled. We always add the pytorch plugin if more than one node.
+ """
+
+ enable_multi_node_networking: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Enable multi-node networking injection. Sets annotations to trigger Kyverno policy mutations.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/workspace.py b/sdks/python/types/workspace.py
new file mode 100644
index 0000000000..2a7ff53296
--- /dev/null
+++ b/sdks/python/types/workspace.py
@@ -0,0 +1,57 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class Workspace(UniversalBaseModel):
+ """
+ Workspace schema for API responses.
+ """
+
+ id: str = pydantic.Field()
+ """
+ System-generated UUID
+ """
+
+ name: str = pydantic.Field()
+ """
+ Workspace name (user-provided)
+ """
+
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Optional description
+ """
+
+ created_at: dt.datetime = pydantic.Field()
+ """
+ Timestamp of workspace creation
+ """
+
+ created_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Principal id for workspace creator
+ """
+
+ updated_at: dt.datetime = pydantic.Field()
+ """
+ Timestamp of last workspace update
+ """
+
+ updated_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Principal id for last workspace update
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/workspace_member.py b/sdks/python/types/workspace_member.py
new file mode 100644
index 0000000000..36115d5f3d
--- /dev/null
+++ b/sdks/python/types/workspace_member.py
@@ -0,0 +1,42 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import datetime as dt
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class WorkspaceMember(UniversalBaseModel):
+ """
+ Workspace member response model.
+ """
+
+ principal: str = pydantic.Field()
+ """
+ The principal identifier
+ """
+
+ roles: typing.List[str] = pydantic.Field()
+ """
+ List of roles granted to the principal
+ """
+
+ granted_at: typing.Optional[dt.datetime] = pydantic.Field(default=None)
+ """
+ Earliest date when a role was granted to this principal
+ """
+
+ granted_by: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Who granted the earliest role
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/workspace_member_list_response.py b/sdks/python/types/workspace_member_list_response.py
new file mode 100644
index 0000000000..87f1104d5f
--- /dev/null
+++ b/sdks/python/types/workspace_member_list_response.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .workspace_member import WorkspaceMember
+
+
+class WorkspaceMemberListResponse(UniversalBaseModel):
+ """
+ Schema for workspace member list responses.
+ """
+
+ data: typing.List[WorkspaceMember]
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/types/workspaces_page.py b/sdks/python/types/workspaces_page.py
new file mode 100644
index 0000000000..4d766da3fa
--- /dev/null
+++ b/sdks/python/types/workspaces_page.py
@@ -0,0 +1,35 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .pagination_data import PaginationData
+from .workspace import Workspace
+
+
+class WorkspacesPage(UniversalBaseModel):
+ data: typing.List[Workspace]
+ pagination: typing.Optional[PaginationData] = pydantic.Field(default=None)
+ """
+ Pagination information.
+ """
+
+ sort: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ The field on which the results are sorted.
+ """
+
+ filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None)
+ """
+ Filtering information.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/sdks/python/virtual_models/__init__.py b/sdks/python/virtual_models/__init__.py
new file mode 100644
index 0000000000..5cde0202dc
--- /dev/null
+++ b/sdks/python/virtual_models/__init__.py
@@ -0,0 +1,4 @@
+# This file was auto-generated by Fern from our API Definition.
+
+# isort: skip_file
+
diff --git a/sdks/python/virtual_models/client.py b/sdks/python/virtual_models/client.py
new file mode 100644
index 0000000000..4df40b42f3
--- /dev/null
+++ b/sdks/python/virtual_models/client.py
@@ -0,0 +1,660 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.request_options import RequestOptions
+from ..types.middleware_call import MiddlewareCall
+from ..types.virtual_model import VirtualModel
+from ..types.virtual_model_inference_config import VirtualModelInferenceConfig
+from ..types.virtual_models_page import VirtualModelsPage
+from .raw_client import AsyncRawVirtualModelsClient, RawVirtualModelsClient
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class VirtualModelsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._raw_client = RawVirtualModelsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> RawVirtualModelsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ RawVirtualModelsClient
+ """
+ return self._raw_client
+
+ def list_virtual_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModelsPage:
+ """
+ List VirtualModels for the given workspace.
+
+ Use ``workspace=-`` to list across all workspaces accessible to the caller.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number (1-indexed).
+
+ page_size : typing.Optional[int]
+ Number of results per page.
+
+ sort : typing.Optional[str]
+ Sort field. Prefix with ``-`` for descending order.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModelsPage
+ Paginated list of virtual models
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.virtual_models.list_virtual_models(
+ workspace="workspace",
+ )
+ """
+ _response = self._raw_client.list_virtual_models(
+ workspace, page=page, page_size=page_size, sort=sort, request_options=request_options
+ )
+ return _response.data
+
+ def create_virtual_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModel:
+ """
+ Create a new VirtualModel in the given workspace.
+
+ A VirtualModel defines an ordered middleware pipeline that IGW executes
+ when an inference request arrives with ``model: "workspace/name"`` matching
+ this entity.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the virtual model within the workspace. Must be unique per workspace.
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ VirtualModel created successfully.
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.virtual_models.create_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.create_virtual_model(
+ workspace,
+ name=name,
+ default_model_entity=default_model_entity,
+ autoprovisioned=autoprovisioned,
+ models=models,
+ request_middleware=request_middleware,
+ response_middleware=response_middleware,
+ post_response_middleware=post_response_middleware,
+ override_proxy=override_proxy,
+ request_options=request_options,
+ )
+ return _response.data
+
+ def get_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> VirtualModel:
+ """
+ Get a VirtualModel by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ VirtualModel details
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.virtual_models.get_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.get_virtual_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ def delete_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Permanently delete a VirtualModel.
+
+ This does not affect any in-flight requests already being routed through
+ this VirtualModel. IGW's model cache is refreshed on its next polling cycle.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.virtual_models.delete_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.delete_virtual_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ def update_virtual_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModel:
+ """
+ Partially update a VirtualModel.
+
+ Only fields present in the request body are modified. Fields absent from
+ the request body retain their current values.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ Updated virtual model
+
+ Examples
+ --------
+ from nvidia import NvidiaApi
+
+ client = NvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+ client.virtual_models.update_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+ """
+ _response = self._raw_client.update_virtual_model(
+ workspace,
+ name,
+ default_model_entity=default_model_entity,
+ autoprovisioned=autoprovisioned,
+ models=models,
+ request_middleware=request_middleware,
+ response_middleware=response_middleware,
+ post_response_middleware=post_response_middleware,
+ override_proxy=override_proxy,
+ request_options=request_options,
+ )
+ return _response.data
+
+
+class AsyncVirtualModelsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._raw_client = AsyncRawVirtualModelsClient(client_wrapper=client_wrapper)
+
+ @property
+ def with_raw_response(self) -> AsyncRawVirtualModelsClient:
+ """
+ Retrieves a raw implementation of this client that returns raw responses.
+
+ Returns
+ -------
+ AsyncRawVirtualModelsClient
+ """
+ return self._raw_client
+
+ async def list_virtual_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModelsPage:
+ """
+ List VirtualModels for the given workspace.
+
+ Use ``workspace=-`` to list across all workspaces accessible to the caller.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number (1-indexed).
+
+ page_size : typing.Optional[int]
+ Number of results per page.
+
+ sort : typing.Optional[str]
+ Sort field. Prefix with ``-`` for descending order.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModelsPage
+ Paginated list of virtual models
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.virtual_models.list_virtual_models(
+ workspace="workspace",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.list_virtual_models(
+ workspace, page=page, page_size=page_size, sort=sort, request_options=request_options
+ )
+ return _response.data
+
+ async def create_virtual_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModel:
+ """
+ Create a new VirtualModel in the given workspace.
+
+ A VirtualModel defines an ordered middleware pipeline that IGW executes
+ when an inference request arrives with ``model: "workspace/name"`` matching
+ this entity.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the virtual model within the workspace. Must be unique per workspace.
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ VirtualModel created successfully.
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.virtual_models.create_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.create_virtual_model(
+ workspace,
+ name=name,
+ default_model_entity=default_model_entity,
+ autoprovisioned=autoprovisioned,
+ models=models,
+ request_middleware=request_middleware,
+ response_middleware=response_middleware,
+ post_response_middleware=post_response_middleware,
+ override_proxy=override_proxy,
+ request_options=request_options,
+ )
+ return _response.data
+
+ async def get_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> VirtualModel:
+ """
+ Get a VirtualModel by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ VirtualModel details
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.virtual_models.get_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.get_virtual_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def delete_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> None:
+ """
+ Permanently delete a VirtualModel.
+
+ This does not affect any in-flight requests already being routed through
+ this VirtualModel. IGW's model cache is refreshed on its next polling cycle.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.virtual_models.delete_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.delete_virtual_model(workspace, name, request_options=request_options)
+ return _response.data
+
+ async def update_virtual_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> VirtualModel:
+ """
+ Partially update a VirtualModel.
+
+ Only fields present in the request body are modified. Fields absent from
+ the request body retain their current values.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ VirtualModel
+ Updated virtual model
+
+ Examples
+ --------
+ import asyncio
+
+ from nvidia import AsyncNvidiaApi
+
+ client = AsyncNvidiaApi(
+ base_url="https://yourhost.com/path/to/api",
+ )
+
+
+ async def main() -> None:
+ await client.virtual_models.update_virtual_model(
+ workspace="workspace",
+ name="name",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_virtual_model(
+ workspace,
+ name,
+ default_model_entity=default_model_entity,
+ autoprovisioned=autoprovisioned,
+ models=models,
+ request_middleware=request_middleware,
+ response_middleware=response_middleware,
+ post_response_middleware=post_response_middleware,
+ override_proxy=override_proxy,
+ request_options=request_options,
+ )
+ return _response.data
diff --git a/sdks/python/virtual_models/raw_client.py b/sdks/python/virtual_models/raw_client.py
new file mode 100644
index 0000000000..dc74708dbe
--- /dev/null
+++ b/sdks/python/virtual_models/raw_client.py
@@ -0,0 +1,954 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+from json.decoder import JSONDecodeError
+
+from ..core.api_error import ApiError
+from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
+from ..core.http_response import AsyncHttpResponse, HttpResponse
+from ..core.jsonable_encoder import encode_path_param
+from ..core.parse_error import ParsingError
+from ..core.pydantic_utilities import parse_obj_as
+from ..core.request_options import RequestOptions
+from ..core.serialization import convert_and_respect_annotation_metadata
+from ..errors.conflict_error import ConflictError
+from ..errors.not_found_error import NotFoundError
+from ..errors.unprocessable_entity_error import UnprocessableEntityError
+from ..types.middleware_call import MiddlewareCall
+from ..types.virtual_model import VirtualModel
+from ..types.virtual_model_inference_config import VirtualModelInferenceConfig
+from ..types.virtual_models_page import VirtualModelsPage
+from pydantic import ValidationError
+
+# this is used as the default value for optional parameters
+OMIT = typing.cast(typing.Any, ...)
+
+
+class RawVirtualModelsClient:
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ def list_virtual_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[VirtualModelsPage]:
+ """
+ List VirtualModels for the given workspace.
+
+ Use ``workspace=-`` to list across all workspaces accessible to the caller.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number (1-indexed).
+
+ page_size : typing.Optional[int]
+ Number of results per page.
+
+ sort : typing.Optional[str]
+ Sort field. Prefix with ``-`` for descending order.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[VirtualModelsPage]
+ Paginated list of virtual models
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModelsPage,
+ parse_obj_as(
+ type_=VirtualModelsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def create_virtual_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[VirtualModel]:
+ """
+ Create a new VirtualModel in the given workspace.
+
+ A VirtualModel defines an ordered middleware pipeline that IGW executes
+ when an inference request arrives with ``model: "workspace/name"`` matching
+ this entity.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the virtual model within the workspace. Must be unique per workspace.
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[VirtualModel]
+ VirtualModel created successfully.
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models",
+ method="POST",
+ json={
+ "default_model_entity": default_model_entity,
+ "autoprovisioned": autoprovisioned,
+ "models": convert_and_respect_annotation_metadata(
+ object_=models, annotation=typing.Sequence[VirtualModelInferenceConfig], direction="write"
+ ),
+ "request_middleware": convert_and_respect_annotation_metadata(
+ object_=request_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "response_middleware": convert_and_respect_annotation_metadata(
+ object_=response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "post_response_middleware": convert_and_respect_annotation_metadata(
+ object_=post_response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "override_proxy": override_proxy,
+ "name": name,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def get_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[VirtualModel]:
+ """
+ Get a VirtualModel by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[VirtualModel]
+ VirtualModel details
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def delete_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> HttpResponse[None]:
+ """
+ Permanently delete a VirtualModel.
+
+ This does not affect any in-flight requests already being routed through
+ this VirtualModel. IGW's model cache is refreshed on its next polling cycle.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[None]
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return HttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ def update_virtual_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[VirtualModel]:
+ """
+ Partially update a VirtualModel.
+
+ Only fields present in the request body are modified. Fields absent from
+ the request body retain their current values.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[VirtualModel]
+ Updated virtual model
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "default_model_entity": default_model_entity,
+ "autoprovisioned": autoprovisioned,
+ "models": convert_and_respect_annotation_metadata(
+ object_=models, annotation=typing.Sequence[VirtualModelInferenceConfig], direction="write"
+ ),
+ "request_middleware": convert_and_respect_annotation_metadata(
+ object_=request_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "response_middleware": convert_and_respect_annotation_metadata(
+ object_=response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "post_response_middleware": convert_and_respect_annotation_metadata(
+ object_=post_response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "override_proxy": override_proxy,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+
+class AsyncRawVirtualModelsClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def list_virtual_models(
+ self,
+ workspace: str,
+ *,
+ page: typing.Optional[int] = None,
+ page_size: typing.Optional[int] = None,
+ sort: typing.Optional[str] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[VirtualModelsPage]:
+ """
+ List VirtualModels for the given workspace.
+
+ Use ``workspace=-`` to list across all workspaces accessible to the caller.
+
+ Parameters
+ ----------
+ workspace : str
+
+ page : typing.Optional[int]
+ Page number (1-indexed).
+
+ page_size : typing.Optional[int]
+ Number of results per page.
+
+ sort : typing.Optional[str]
+ Sort field. Prefix with ``-`` for descending order.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[VirtualModelsPage]
+ Paginated list of virtual models
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models",
+ method="GET",
+ params={
+ "page": page,
+ "page_size": page_size,
+ "sort": sort,
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModelsPage,
+ parse_obj_as(
+ type_=VirtualModelsPage, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def create_virtual_model(
+ self,
+ workspace: str,
+ *,
+ name: str,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[VirtualModel]:
+ """
+ Create a new VirtualModel in the given workspace.
+
+ A VirtualModel defines an ordered middleware pipeline that IGW executes
+ when an inference request arrives with ``model: "workspace/name"`` matching
+ this entity.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+ Name of the virtual model within the workspace. Must be unique per workspace.
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[VirtualModel]
+ VirtualModel created successfully.
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models",
+ method="POST",
+ json={
+ "default_model_entity": default_model_entity,
+ "autoprovisioned": autoprovisioned,
+ "models": convert_and_respect_annotation_metadata(
+ object_=models, annotation=typing.Sequence[VirtualModelInferenceConfig], direction="write"
+ ),
+ "request_middleware": convert_and_respect_annotation_metadata(
+ object_=request_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "response_middleware": convert_and_respect_annotation_metadata(
+ object_=response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "post_response_middleware": convert_and_respect_annotation_metadata(
+ object_=post_response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "override_proxy": override_proxy,
+ "name": name,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def get_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[VirtualModel]:
+ """
+ Get a VirtualModel by workspace and name.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[VirtualModel]
+ VirtualModel details
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def delete_virtual_model(
+ self, workspace: str, name: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> AsyncHttpResponse[None]:
+ """
+ Permanently delete a VirtualModel.
+
+ This does not affect any in-flight requests already being routed through
+ this VirtualModel. IGW's model cache is refreshed on its next polling cycle.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[None]
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return AsyncHttpResponse(response=_response, data=None)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
+
+ async def update_virtual_model(
+ self,
+ workspace: str,
+ name: str,
+ *,
+ default_model_entity: typing.Optional[str] = OMIT,
+ autoprovisioned: typing.Optional[bool] = OMIT,
+ models: typing.Optional[typing.Sequence[VirtualModelInferenceConfig]] = OMIT,
+ request_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ post_response_middleware: typing.Optional[typing.Sequence[MiddlewareCall]] = OMIT,
+ override_proxy: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[VirtualModel]:
+ """
+ Partially update a VirtualModel.
+
+ Only fields present in the request body are modified. Fields absent from
+ the request body retain their current values.
+
+ Parameters
+ ----------
+ workspace : str
+
+ name : str
+
+ default_model_entity : typing.Optional[str]
+ Model entity to route to, in "workspace/name" format. Written into request["model"] before the request middleware pipeline runs. If omitted, a request middleware plugin must handle backend routing itself. Set to null to clear an existing value.
+
+ autoprovisioned : typing.Optional[bool]
+ Marks this VirtualModel as controller-managed. The Models controller will delete it once no ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into that cleanup behavior.
+
+ models : typing.Optional[typing.Sequence[VirtualModelInferenceConfig]]
+ Model entity references used by this VirtualModel. A per-entry backend_format overrides the referenced ModelEntity backend_format when IGW resolves the backend format for a request.
+
+ request_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied before proxying to the backend. Each entry is a MiddlewareCall with a "name" (plugin identifier) and optional "config_type" and "config_id" fields that reference a stored plugin configuration.
+
+ response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins applied after the backend response is received, before returning it to the caller.
+
+ post_response_middleware : typing.Optional[typing.Sequence[MiddlewareCall]]
+ Ordered list of middleware plugins invoked after the response has been returned to the caller. Intended for fire-and-forget work (logging, analytics) that must not block or modify the response.
+
+ override_proxy : typing.Optional[str]
+ Plugin-provided proxy implementation for IGW to use instead of its default aiohttp proxy. Format: "plugin-name.proxy-name". Leave unset to use the default IGW proxy. Set to null to clear an existing value.
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[VirtualModel]
+ Updated virtual model
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"apis/inference-gateway/v2/workspaces/{encode_path_param(workspace)}/virtual-models/{encode_path_param(name)}",
+ method="PATCH",
+ json={
+ "default_model_entity": default_model_entity,
+ "autoprovisioned": autoprovisioned,
+ "models": convert_and_respect_annotation_metadata(
+ object_=models, annotation=typing.Sequence[VirtualModelInferenceConfig], direction="write"
+ ),
+ "request_middleware": convert_and_respect_annotation_metadata(
+ object_=request_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "response_middleware": convert_and_respect_annotation_metadata(
+ object_=response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "post_response_middleware": convert_and_respect_annotation_metadata(
+ object_=post_response_middleware, annotation=typing.Sequence[MiddlewareCall], direction="write"
+ ),
+ "override_proxy": override_proxy,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ VirtualModel,
+ parse_obj_as(
+ type_=VirtualModel, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 409:
+ raise ConflictError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 422:
+ raise UnprocessableEntityError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ typing.Any,
+ parse_obj_as(
+ type_=typing.Any, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)