From a33ed30a94cd56737747e3492b5bddf4ea8a8183 Mon Sep 17 00:00:00 2001 From: "onepin-pipeline-bot[bot]" <290953255+onepin-pipeline-bot[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 02:07:53 +0000 Subject: [PATCH] feat: sync SDK to OnePin API v0.38.12 --- .spec-sha | 2 +- src/onepin/.fern/metadata.json | 14 +- src/onepin/__init__.py | 57 +- src/onepin/client.py | 19 + src/onepin/core/client_wrapper.py | 2 +- src/onepin/nodes/client.py | 114 +++ src/onepin/nodes/raw_client.py | 172 ++++ src/onepin/providers/__init__.py | 4 + src/onepin/providers/client.py | 512 ++++++++++++ src/onepin/providers/raw_client.py | 777 ++++++++++++++++++ src/onepin/reference.md | 533 ++++++++++++ src/onepin/types/__init__.py | 39 +- ...ounted_list_response_catalog_voice_out.py} | 15 +- src/onepin/types/api_key_scope.py | 1 + .../api_list_response_catalog_model_out.py | 24 + .../api_list_response_catalog_provider_out.py | 24 + .../types/api_response_catalog_model_out.py | 22 + .../api_response_catalog_provider_out.py | 22 + src/onepin/types/catalog_link.py | 27 + src/onepin/types/catalog_model_out.py | 33 + src/onepin/types/catalog_provider_out.py | 31 + src/onepin/types/catalog_voice_out.py | 36 + src/onepin/types/node_type.py | 1 + .../types/workflow_run_data_card_out.py | 4 +- .../types/workflow_run_data_validation_out.py | 35 + ...orkflow_run_data_validation_out_status.py} | 2 +- 26 files changed, 2487 insertions(+), 35 deletions(-) create mode 100644 src/onepin/providers/__init__.py create mode 100644 src/onepin/providers/client.py create mode 100644 src/onepin/providers/raw_client.py rename src/onepin/types/{workflow_run_data_scores_out.py => api_counted_list_response_catalog_voice_out.py} (52%) create mode 100644 src/onepin/types/api_list_response_catalog_model_out.py create mode 100644 src/onepin/types/api_list_response_catalog_provider_out.py create mode 100644 src/onepin/types/api_response_catalog_model_out.py create mode 100644 src/onepin/types/api_response_catalog_provider_out.py create mode 100644 src/onepin/types/catalog_link.py create mode 100644 src/onepin/types/catalog_model_out.py create mode 100644 src/onepin/types/catalog_provider_out.py create mode 100644 src/onepin/types/catalog_voice_out.py create mode 100644 src/onepin/types/workflow_run_data_validation_out.py rename src/onepin/types/{workflow_run_data_scores_out_accuracy_status.py => workflow_run_data_validation_out_status.py} (75%) diff --git a/.spec-sha b/.spec-sha index 8d33425..68677bc 100644 --- a/.spec-sha +++ b/.spec-sha @@ -1 +1 @@ -9fe47587946f7ab984ac1dd701c85c15c368a67c +22d7f164e18c741e9d6e2cba0f280a3a3af4d153 diff --git a/src/onepin/.fern/metadata.json b/src/onepin/.fern/metadata.json index c57a2d6..8c61ab7 100644 --- a/src/onepin/.fern/metadata.json +++ b/src/onepin/.fern/metadata.json @@ -5,9 +5,19 @@ "generatorConfig": { "client_class_name": "OnePinClient", "package_name": "onepin", - "flat_layout": false + "flat_layout": false, + "additional_init_exports": [ + { + "from": "_version_gate", + "imports": [ + "make_client", + "make_async_client", + "OnePinUpgradeRequiredError" + ] + } + ] }, - "originGitCommit": "2bb9115ea1292fce9ca3019bd7c90ba226cc58b6", + "originGitCommit": "e61a07d289073104a086ed6aec6161a6169f829a", "originGitCommitIsDirty": false, "invokedBy": "ci", "ciProvider": "github" diff --git a/src/onepin/__init__.py b/src/onepin/__init__.py index 3923001..21a972c 100644 --- a/src/onepin/__init__.py +++ b/src/onepin/__init__.py @@ -8,6 +8,7 @@ if typing.TYPE_CHECKING: from .types import ( ApiCountedListResponseApiKeyOut, + ApiCountedListResponseCatalogVoiceOut, ApiCountedListResponseVoiceOut, ApiCountedListResponseWorkflowListItem, ApiCountedListResponseWorkflowRunListItem, @@ -19,6 +20,8 @@ ApiKeyOut, ApiKeyRotateOut, ApiKeyScope, + ApiListResponseCatalogModelOut, + ApiListResponseCatalogProviderOut, ApiListResponseCustomerPlanResponse, ApiListResponseDictionaryOut, ApiListResponseNodePortsOut, @@ -33,6 +36,8 @@ ApiResponseApiKeyRotateOut, ApiResponseAuthWhoamiOut, ApiResponseBalanceResponse, + ApiResponseCatalogModelOut, + ApiResponseCatalogProviderOut, ApiResponseCheckoutResponse, ApiResponseCustomerPlanChangePreviewResponse, ApiResponseCustomerSubscriptionResponse, @@ -73,6 +78,10 @@ AuthWhoamiOut, AuthWhoamiOutAuthKind, BalanceResponse, + CatalogLink, + CatalogModelOut, + CatalogProviderOut, + CatalogVoiceOut, CheckoutResponse, CountedPaginationMeta, CustomerPlanChangePreviewResponse, @@ -180,8 +189,8 @@ WorkflowRunDataRowOut, WorkflowRunDataRowOutAutoCorrectedStatus, WorkflowRunDataRowOutScriptStatus, - WorkflowRunDataScoresOut, - WorkflowRunDataScoresOutAccuracyStatus, + WorkflowRunDataValidationOut, + WorkflowRunDataValidationOutStatus, WorkflowRunDataVoiceOut, WorkflowRunDataVoiceOutStatus, WorkflowRunDetailOut, @@ -222,6 +231,7 @@ health, nodes, provider_keys, + providers, templates, uploads, usage, @@ -235,6 +245,7 @@ workspaces, ) from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient + from ._version_gate import OnePinUpgradeRequiredError, make_async_client, make_client from .client import AsyncOnePinClient, OnePinClient from .dictionary import ( ListDictionaryEntriesApiV1DictionaryGetRequestLanguage, @@ -265,6 +276,7 @@ from .workflows import ListWorkflowsRequestOrderItem, ListWorkflowsRequestSortItem _dynamic_imports: typing.Dict[str, str] = { "ApiCountedListResponseApiKeyOut": ".types", + "ApiCountedListResponseCatalogVoiceOut": ".types", "ApiCountedListResponseVoiceOut": ".types", "ApiCountedListResponseWorkflowListItem": ".types", "ApiCountedListResponseWorkflowRunListItem": ".types", @@ -276,6 +288,8 @@ "ApiKeyOut": ".types", "ApiKeyRotateOut": ".types", "ApiKeyScope": ".types", + "ApiListResponseCatalogModelOut": ".types", + "ApiListResponseCatalogProviderOut": ".types", "ApiListResponseCustomerPlanResponse": ".types", "ApiListResponseDictionaryOut": ".types", "ApiListResponseNodePortsOut": ".types", @@ -290,6 +304,8 @@ "ApiResponseApiKeyRotateOut": ".types", "ApiResponseAuthWhoamiOut": ".types", "ApiResponseBalanceResponse": ".types", + "ApiResponseCatalogModelOut": ".types", + "ApiResponseCatalogProviderOut": ".types", "ApiResponseCheckoutResponse": ".types", "ApiResponseCustomerPlanChangePreviewResponse": ".types", "ApiResponseCustomerSubscriptionResponse": ".types", @@ -331,6 +347,10 @@ "AuthWhoamiOut": ".types", "AuthWhoamiOutAuthKind": ".types", "BalanceResponse": ".types", + "CatalogLink": ".types", + "CatalogModelOut": ".types", + "CatalogProviderOut": ".types", + "CatalogVoiceOut": ".types", "CheckoutResponse": ".types", "ConflictError": ".errors", "CountedPaginationMeta": ".types", @@ -385,6 +405,7 @@ "NumericOption": ".types", "OnePinClient": ".client", "OnePinClientEnvironment": ".environment", + "OnePinUpgradeRequiredError": "._version_gate", "PaginationMeta": ".types", "PaymentMethodResponse": ".types", "PlanDetails": ".types", @@ -467,8 +488,8 @@ "WorkflowRunDataRowOut": ".types", "WorkflowRunDataRowOutAutoCorrectedStatus": ".types", "WorkflowRunDataRowOutScriptStatus": ".types", - "WorkflowRunDataScoresOut": ".types", - "WorkflowRunDataScoresOutAccuracyStatus": ".types", + "WorkflowRunDataValidationOut": ".types", + "WorkflowRunDataValidationOutStatus": ".types", "WorkflowRunDataVoiceOut": ".types", "WorkflowRunDataVoiceOutStatus": ".types", "WorkflowRunDetailOut": ".types", @@ -504,8 +525,11 @@ "billing": ".billing", "dictionary": ".dictionary", "health": ".health", + "make_async_client": "._version_gate", + "make_client": "._version_gate", "nodes": ".nodes", "provider_keys": ".provider_keys", + "providers": ".providers", "templates": ".templates", "uploads": ".uploads", "usage": ".usage", @@ -517,11 +541,6 @@ "workspace_aggregates": ".workspace_aggregates", "workspace_members": ".workspace_members", "workspaces": ".workspaces", - # Hand-rolled version gate, re-exported here. Also declared in - # fern/generators.yml `additional_init_exports`, so `fern generate` reproduces these. - "OnePinUpgradeRequiredError": "._version_gate", - "make_async_client": "._version_gate", - "make_client": "._version_gate", } @@ -548,6 +567,7 @@ def __dir__(): __all__ = [ "ApiCountedListResponseApiKeyOut", + "ApiCountedListResponseCatalogVoiceOut", "ApiCountedListResponseVoiceOut", "ApiCountedListResponseWorkflowListItem", "ApiCountedListResponseWorkflowRunListItem", @@ -559,6 +579,8 @@ def __dir__(): "ApiKeyOut", "ApiKeyRotateOut", "ApiKeyScope", + "ApiListResponseCatalogModelOut", + "ApiListResponseCatalogProviderOut", "ApiListResponseCustomerPlanResponse", "ApiListResponseDictionaryOut", "ApiListResponseNodePortsOut", @@ -573,6 +595,8 @@ def __dir__(): "ApiResponseApiKeyRotateOut", "ApiResponseAuthWhoamiOut", "ApiResponseBalanceResponse", + "ApiResponseCatalogModelOut", + "ApiResponseCatalogProviderOut", "ApiResponseCheckoutResponse", "ApiResponseCustomerPlanChangePreviewResponse", "ApiResponseCustomerSubscriptionResponse", @@ -614,6 +638,10 @@ def __dir__(): "AuthWhoamiOut", "AuthWhoamiOutAuthKind", "BalanceResponse", + "CatalogLink", + "CatalogModelOut", + "CatalogProviderOut", + "CatalogVoiceOut", "CheckoutResponse", "ConflictError", "CountedPaginationMeta", @@ -668,6 +696,7 @@ def __dir__(): "NumericOption", "OnePinClient", "OnePinClientEnvironment", + "OnePinUpgradeRequiredError", "PaginationMeta", "PaymentMethodResponse", "PlanDetails", @@ -750,8 +779,8 @@ def __dir__(): "WorkflowRunDataRowOut", "WorkflowRunDataRowOutAutoCorrectedStatus", "WorkflowRunDataRowOutScriptStatus", - "WorkflowRunDataScoresOut", - "WorkflowRunDataScoresOutAccuracyStatus", + "WorkflowRunDataValidationOut", + "WorkflowRunDataValidationOutStatus", "WorkflowRunDataVoiceOut", "WorkflowRunDataVoiceOutStatus", "WorkflowRunDetailOut", @@ -787,8 +816,11 @@ def __dir__(): "billing", "dictionary", "health", + "make_async_client", + "make_client", "nodes", "provider_keys", + "providers", "templates", "uploads", "usage", @@ -800,7 +832,4 @@ def __dir__(): "workspace_aggregates", "workspace_members", "workspaces", - "OnePinUpgradeRequiredError", - "make_async_client", - "make_client", ] diff --git a/src/onepin/client.py b/src/onepin/client.py index e192699..9fcc96a 100644 --- a/src/onepin/client.py +++ b/src/onepin/client.py @@ -17,6 +17,7 @@ from .health.client import AsyncHealthClient, HealthClient from .nodes.client import AsyncNodesClient, NodesClient from .provider_keys.client import AsyncProviderKeysClient, ProviderKeysClient + from .providers.client import AsyncProvidersClient, ProvidersClient from .templates.client import AsyncTemplatesClient, TemplatesClient from .uploads.client import AsyncUploadsClient, UploadsClient from .usage.client import AsyncUsageClient, UsageClient @@ -113,6 +114,7 @@ def __init__( self._dictionary: typing.Optional[DictionaryClient] = None self._nodes: typing.Optional[NodesClient] = None self._provider_keys: typing.Optional[ProviderKeysClient] = None + self._providers: typing.Optional[ProvidersClient] = None self._templates: typing.Optional[TemplatesClient] = None self._voices: typing.Optional[VoicesClient] = None self._workspace: typing.Optional[WorkspaceClient] = None @@ -181,6 +183,14 @@ def provider_keys(self): self._provider_keys = ProviderKeysClient(client_wrapper=self._client_wrapper) return self._provider_keys + @property + def providers(self): + if self._providers is None: + from .providers.client import ProvidersClient # noqa: E402 + + self._providers = ProvidersClient(client_wrapper=self._client_wrapper) + return self._providers + @property def templates(self): if self._templates is None: @@ -374,6 +384,7 @@ def __init__( self._dictionary: typing.Optional[AsyncDictionaryClient] = None self._nodes: typing.Optional[AsyncNodesClient] = None self._provider_keys: typing.Optional[AsyncProviderKeysClient] = None + self._providers: typing.Optional[AsyncProvidersClient] = None self._templates: typing.Optional[AsyncTemplatesClient] = None self._voices: typing.Optional[AsyncVoicesClient] = None self._workspace: typing.Optional[AsyncWorkspaceClient] = None @@ -442,6 +453,14 @@ def provider_keys(self): self._provider_keys = AsyncProviderKeysClient(client_wrapper=self._client_wrapper) return self._provider_keys + @property + def providers(self): + if self._providers is None: + from .providers.client import AsyncProvidersClient # noqa: E402 + + self._providers = AsyncProvidersClient(client_wrapper=self._client_wrapper) + return self._providers + @property def templates(self): if self._templates is None: diff --git a/src/onepin/core/client_wrapper.py b/src/onepin/core/client_wrapper.py index 7e6af11..fb6bf54 100644 --- a/src/onepin/core/client_wrapper.py +++ b/src/onepin/core/client_wrapper.py @@ -29,7 +29,7 @@ def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "onepin/0.5.1", + "User-Agent": "onepin/0.6.1", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", diff --git a/src/onepin/nodes/client.py b/src/onepin/nodes/client.py index f54f97d..a3ec2c1 100644 --- a/src/onepin/nodes/client.py +++ b/src/onepin/nodes/client.py @@ -60,6 +60,12 @@ def get_node_detail( """ Return full node definition + runtime options for the canvas node-config UI. + **Deprecated (POD-612):** this version inlines the model catalog as + `options.models_by_provider`. Use `GET /api/v2/nodes/{node_type}`, which + replaces the inline tree with a `providers` HATEOAS href to the standalone + catalog `/api/v1/providers`. This endpoint is kept for one release while the + FE migrates, then removed. + Unlike `GET /nodes` (which returns only port schemas), this endpoint returns the actual runtime values a user picks: available target languages (from settings), the TTS model catalog grouped by provider, and a HATEOAS link to the workspace- @@ -95,6 +101,53 @@ def get_node_detail( ) return _response.data + def get_node_detail_v2( + self, + node_type: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseNodeDetailOut: + """ + Return full node definition + runtime options (v2 — HATEOAS catalog href). + + POD-612: replaces the deprecated v1 ``options.models_by_provider`` inline tree + with a ``providers`` HATEOAS href to the standalone catalog + ``/api/v1/providers``. The FE follows that href to fetch each model's + ``config_schema`` lazily. The ``voices`` href (with its provider/model/language + filter enums) is unchanged, so the voice picker never needs the catalog call. + Requires ``X-Workspace-Id`` for a uniform FE contract. + + Parameters + ---------- + node_type : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseNodeDetailOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.nodes.get_node_detail_v2( + node_type="node_type", + ) + """ + _response = self._raw_client.get_node_detail_v2( + node_type, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + class AsyncNodesClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -157,6 +210,12 @@ async def get_node_detail( """ Return full node definition + runtime options for the canvas node-config UI. + **Deprecated (POD-612):** this version inlines the model catalog as + `options.models_by_provider`. Use `GET /api/v2/nodes/{node_type}`, which + replaces the inline tree with a `providers` HATEOAS href to the standalone + catalog `/api/v1/providers`. This endpoint is kept for one release while the + FE migrates, then removed. + Unlike `GET /nodes` (which returns only port schemas), this endpoint returns the actual runtime values a user picks: available target languages (from settings), the TTS model catalog grouped by provider, and a HATEOAS link to the workspace- @@ -199,3 +258,58 @@ async def main() -> None: node_type, workspace_id=workspace_id, request_options=request_options ) return _response.data + + async def get_node_detail_v2( + self, + node_type: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseNodeDetailOut: + """ + Return full node definition + runtime options (v2 — HATEOAS catalog href). + + POD-612: replaces the deprecated v1 ``options.models_by_provider`` inline tree + with a ``providers`` HATEOAS href to the standalone catalog + ``/api/v1/providers``. The FE follows that href to fetch each model's + ``config_schema`` lazily. The ``voices`` href (with its provider/model/language + filter enums) is unchanged, so the voice picker never needs the catalog call. + Requires ``X-Workspace-Id`` for a uniform FE contract. + + Parameters + ---------- + node_type : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseNodeDetailOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.nodes.get_node_detail_v2( + node_type="node_type", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_node_detail_v2( + node_type, workspace_id=workspace_id, request_options=request_options + ) + return _response.data diff --git a/src/onepin/nodes/raw_client.py b/src/onepin/nodes/raw_client.py index 7bfb174..8f1ff8f 100644 --- a/src/onepin/nodes/raw_client.py +++ b/src/onepin/nodes/raw_client.py @@ -72,6 +72,12 @@ def get_node_detail( """ Return full node definition + runtime options for the canvas node-config UI. + **Deprecated (POD-612):** this version inlines the model catalog as + `options.models_by_provider`. Use `GET /api/v2/nodes/{node_type}`, which + replaces the inline tree with a `providers` HATEOAS href to the standalone + catalog `/api/v1/providers`. This endpoint is kept for one release while the + FE migrates, then removed. + Unlike `GET /nodes` (which returns only port schemas), this endpoint returns the actual runtime values a user picks: available target languages (from settings), the TTS model catalog grouped by provider, and a HATEOAS link to the workspace- @@ -140,6 +146,86 @@ def get_node_detail( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def get_node_detail_v2( + self, + node_type: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ApiResponseNodeDetailOut]: + """ + Return full node definition + runtime options (v2 — HATEOAS catalog href). + + POD-612: replaces the deprecated v1 ``options.models_by_provider`` inline tree + with a ``providers`` HATEOAS href to the standalone catalog + ``/api/v1/providers``. The FE follows that href to fetch each model's + ``config_schema`` lazily. The ``voices`` href (with its provider/model/language + filter enums) is unchanged, so the voice picker never needs the catalog call. + Requires ``X-Workspace-Id`` for a uniform FE contract. + + Parameters + ---------- + node_type : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiResponseNodeDetailOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/v2/nodes/{encode_path_param(node_type)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseNodeDetailOut, + parse_obj_as( + type_=ApiResponseNodeDetailOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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 AsyncRawNodesClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -195,6 +281,12 @@ async def get_node_detail( """ Return full node definition + runtime options for the canvas node-config UI. + **Deprecated (POD-612):** this version inlines the model catalog as + `options.models_by_provider`. Use `GET /api/v2/nodes/{node_type}`, which + replaces the inline tree with a `providers` HATEOAS href to the standalone + catalog `/api/v1/providers`. This endpoint is kept for one release while the + FE migrates, then removed. + Unlike `GET /nodes` (which returns only port schemas), this endpoint returns the actual runtime values a user picks: available target languages (from settings), the TTS model catalog grouped by provider, and a HATEOAS link to the workspace- @@ -262,3 +354,83 @@ async def get_node_detail( status_code=_response.status_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_node_detail_v2( + self, + node_type: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ApiResponseNodeDetailOut]: + """ + Return full node definition + runtime options (v2 — HATEOAS catalog href). + + POD-612: replaces the deprecated v1 ``options.models_by_provider`` inline tree + with a ``providers`` HATEOAS href to the standalone catalog + ``/api/v1/providers``. The FE follows that href to fetch each model's + ``config_schema`` lazily. The ``voices`` href (with its provider/model/language + filter enums) is unchanged, so the voice picker never needs the catalog call. + Requires ``X-Workspace-Id`` for a uniform FE contract. + + Parameters + ---------- + node_type : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiResponseNodeDetailOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/v2/nodes/{encode_path_param(node_type)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseNodeDetailOut, + parse_obj_as( + type_=ApiResponseNodeDetailOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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/src/onepin/providers/__init__.py b/src/onepin/providers/__init__.py new file mode 100644 index 0000000..5cde020 --- /dev/null +++ b/src/onepin/providers/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/onepin/providers/client.py b/src/onepin/providers/client.py new file mode 100644 index 0000000..1a1a7e2 --- /dev/null +++ b/src/onepin/providers/client.py @@ -0,0 +1,512 @@ +# 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.api_counted_list_response_catalog_voice_out import ApiCountedListResponseCatalogVoiceOut +from ..types.api_list_response_catalog_model_out import ApiListResponseCatalogModelOut +from ..types.api_list_response_catalog_provider_out import ApiListResponseCatalogProviderOut +from ..types.api_response_catalog_model_out import ApiResponseCatalogModelOut +from ..types.api_response_catalog_provider_out import ApiResponseCatalogProviderOut +from .raw_client import AsyncRawProvidersClient, RawProvidersClient + + +class ProvidersClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawProvidersClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawProvidersClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawProvidersClient + """ + return self._raw_client + + def list_catalog_providers( + self, *, workspace_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> ApiListResponseCatalogProviderOut: + """ + List TTS providers in the public catalog. + + Returns the processing (TTS) provider catalog with a per-provider model count + and a HATEOAS link to each provider's models. Lean / customer-safe — cost, + credentials, and base URLs are never exposed. Requires `X-Workspace-Id` (or a + workspace-bound API key with the `catalog:read` scope), matching `/voices`. + + Parameters + ---------- + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiListResponseCatalogProviderOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.providers.list_catalog_providers() + """ + _response = self._raw_client.list_catalog_providers(workspace_id=workspace_id, request_options=request_options) + return _response.data + + def get_catalog_provider( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseCatalogProviderOut: + """ + Get a single TTS provider by canonical name (e.g. `cartesia`). + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseCatalogProviderOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.providers.get_catalog_provider( + provider="provider", + ) + """ + _response = self._raw_client.get_catalog_provider( + provider, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + def list_catalog_provider_models( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiListResponseCatalogModelOut: + """ + List a provider's TTS models, each with its `config_schema` and live `voice_count`. + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiListResponseCatalogModelOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.providers.list_catalog_provider_models( + provider="provider", + ) + """ + _response = self._raw_client.list_catalog_provider_models( + provider, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + def list_catalog_provider_model_voices( + self, + provider: str, + model: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiCountedListResponseCatalogVoiceOut: + """ + List platform voices catalogued under an exact `(provider, model)`. + + Lean voice shape with a presigned `preview_url`. Platform catalog voices only + (System workspace); model-less voices are excluded. Paginated via `offset` / + `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker. + + Parameters + ---------- + provider : str + + model : str + + offset : typing.Optional[int] + + limit : typing.Optional[int] + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiCountedListResponseCatalogVoiceOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.providers.list_catalog_provider_model_voices( + provider="provider", + model="model", + ) + """ + _response = self._raw_client.list_catalog_provider_model_voices( + provider, model, offset=offset, limit=limit, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + def get_catalog_provider_model( + self, + provider: str, + model: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseCatalogModelOut: + """ + Get a single TTS model — `config_schema` + live `voice_count`. + + Parameters + ---------- + provider : str + + model : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseCatalogModelOut + Successful Response + + Examples + -------- + from onepin import OnePinClient + + client = OnePinClient( + token="YOUR_TOKEN", + ) + client.providers.get_catalog_provider_model( + provider="provider", + model="model", + ) + """ + _response = self._raw_client.get_catalog_provider_model( + provider, model, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + +class AsyncProvidersClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawProvidersClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawProvidersClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawProvidersClient + """ + return self._raw_client + + async def list_catalog_providers( + self, *, workspace_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> ApiListResponseCatalogProviderOut: + """ + List TTS providers in the public catalog. + + Returns the processing (TTS) provider catalog with a per-provider model count + and a HATEOAS link to each provider's models. Lean / customer-safe — cost, + credentials, and base URLs are never exposed. Requires `X-Workspace-Id` (or a + workspace-bound API key with the `catalog:read` scope), matching `/voices`. + + Parameters + ---------- + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiListResponseCatalogProviderOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.providers.list_catalog_providers() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_catalog_providers( + workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + async def get_catalog_provider( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseCatalogProviderOut: + """ + Get a single TTS provider by canonical name (e.g. `cartesia`). + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseCatalogProviderOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.providers.get_catalog_provider( + provider="provider", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_catalog_provider( + provider, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + async def list_catalog_provider_models( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiListResponseCatalogModelOut: + """ + List a provider's TTS models, each with its `config_schema` and live `voice_count`. + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiListResponseCatalogModelOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.providers.list_catalog_provider_models( + provider="provider", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_catalog_provider_models( + provider, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + async def list_catalog_provider_model_voices( + self, + provider: str, + model: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiCountedListResponseCatalogVoiceOut: + """ + List platform voices catalogued under an exact `(provider, model)`. + + Lean voice shape with a presigned `preview_url`. Platform catalog voices only + (System workspace); model-less voices are excluded. Paginated via `offset` / + `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker. + + Parameters + ---------- + provider : str + + model : str + + offset : typing.Optional[int] + + limit : typing.Optional[int] + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiCountedListResponseCatalogVoiceOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.providers.list_catalog_provider_model_voices( + provider="provider", + model="model", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_catalog_provider_model_voices( + provider, model, offset=offset, limit=limit, workspace_id=workspace_id, request_options=request_options + ) + return _response.data + + async def get_catalog_provider_model( + self, + provider: str, + model: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> ApiResponseCatalogModelOut: + """ + Get a single TTS model — `config_schema` + live `voice_count`. + + Parameters + ---------- + provider : str + + model : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ApiResponseCatalogModelOut + Successful Response + + Examples + -------- + import asyncio + + from onepin import AsyncOnePinClient + + client = AsyncOnePinClient( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.providers.get_catalog_provider_model( + provider="provider", + model="model", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_catalog_provider_model( + provider, model, workspace_id=workspace_id, request_options=request_options + ) + return _response.data diff --git a/src/onepin/providers/raw_client.py b/src/onepin/providers/raw_client.py new file mode 100644 index 0000000..04f216b --- /dev/null +++ b/src/onepin/providers/raw_client.py @@ -0,0 +1,777 @@ +# 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.not_found_error import NotFoundError +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.api_counted_list_response_catalog_voice_out import ApiCountedListResponseCatalogVoiceOut +from ..types.api_list_response_catalog_model_out import ApiListResponseCatalogModelOut +from ..types.api_list_response_catalog_provider_out import ApiListResponseCatalogProviderOut +from ..types.api_response_catalog_model_out import ApiResponseCatalogModelOut +from ..types.api_response_catalog_provider_out import ApiResponseCatalogProviderOut +from ..types.http_validation_error import HttpValidationError +from pydantic import ValidationError + + +class RawProvidersClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_catalog_providers( + self, *, workspace_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ApiListResponseCatalogProviderOut]: + """ + List TTS providers in the public catalog. + + Returns the processing (TTS) provider catalog with a per-provider model count + and a HATEOAS link to each provider's models. Lean / customer-safe — cost, + credentials, and base URLs are never exposed. Requires `X-Workspace-Id` (or a + workspace-bound API key with the `catalog:read` scope), matching `/voices`. + + Parameters + ---------- + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiListResponseCatalogProviderOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + "api/v1/providers", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiListResponseCatalogProviderOut, + parse_obj_as( + type_=ApiListResponseCatalogProviderOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ApiResponseCatalogProviderOut]: + """ + Get a single TTS provider by canonical name (e.g. `cartesia`). + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiResponseCatalogProviderOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseCatalogProviderOut, + parse_obj_as( + type_=ApiResponseCatalogProviderOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_models( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ApiListResponseCatalogModelOut]: + """ + List a provider's TTS models, each with its `config_schema` and live `voice_count`. + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiListResponseCatalogModelOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiListResponseCatalogModelOut, + parse_obj_as( + type_=ApiListResponseCatalogModelOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_model_voices( + self, + provider: str, + model: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ApiCountedListResponseCatalogVoiceOut]: + """ + List platform voices catalogued under an exact `(provider, model)`. + + Lean voice shape with a presigned `preview_url`. Platform catalog voices only + (System workspace); model-less voices are excluded. Paginated via `offset` / + `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker. + + Parameters + ---------- + provider : str + + model : str + + offset : typing.Optional[int] + + limit : typing.Optional[int] + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiCountedListResponseCatalogVoiceOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models/{encode_path_param(model)}/voices", + method="GET", + params={ + "offset": offset, + "limit": limit, + }, + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiCountedListResponseCatalogVoiceOut, + parse_obj_as( + type_=ApiCountedListResponseCatalogVoiceOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_model( + self, + provider: str, + model: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ApiResponseCatalogModelOut]: + """ + Get a single TTS model — `config_schema` + live `voice_count`. + + Parameters + ---------- + provider : str + + model : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ApiResponseCatalogModelOut] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models/{encode_path_param(model)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseCatalogModelOut, + parse_obj_as( + type_=ApiResponseCatalogModelOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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 AsyncRawProvidersClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_catalog_providers( + self, *, workspace_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ApiListResponseCatalogProviderOut]: + """ + List TTS providers in the public catalog. + + Returns the processing (TTS) provider catalog with a per-provider model count + and a HATEOAS link to each provider's models. Lean / customer-safe — cost, + credentials, and base URLs are never exposed. Requires `X-Workspace-Id` (or a + workspace-bound API key with the `catalog:read` scope), matching `/voices`. + + Parameters + ---------- + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiListResponseCatalogProviderOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + "api/v1/providers", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiListResponseCatalogProviderOut, + parse_obj_as( + type_=ApiListResponseCatalogProviderOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ApiResponseCatalogProviderOut]: + """ + Get a single TTS provider by canonical name (e.g. `cartesia`). + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiResponseCatalogProviderOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseCatalogProviderOut, + parse_obj_as( + type_=ApiResponseCatalogProviderOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_models( + self, + provider: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ApiListResponseCatalogModelOut]: + """ + List a provider's TTS models, each with its `config_schema` and live `voice_count`. + + Parameters + ---------- + provider : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiListResponseCatalogModelOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiListResponseCatalogModelOut, + parse_obj_as( + type_=ApiListResponseCatalogModelOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_model_voices( + self, + provider: str, + model: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ApiCountedListResponseCatalogVoiceOut]: + """ + List platform voices catalogued under an exact `(provider, model)`. + + Lean voice shape with a presigned `preview_url`. Platform catalog voices only + (System workspace); model-less voices are excluded. Paginated via `offset` / + `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker. + + Parameters + ---------- + provider : str + + model : str + + offset : typing.Optional[int] + + limit : typing.Optional[int] + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiCountedListResponseCatalogVoiceOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models/{encode_path_param(model)}/voices", + method="GET", + params={ + "offset": offset, + "limit": limit, + }, + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiCountedListResponseCatalogVoiceOut, + parse_obj_as( + type_=ApiCountedListResponseCatalogVoiceOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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_catalog_provider_model( + self, + provider: str, + model: str, + *, + workspace_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ApiResponseCatalogModelOut]: + """ + Get a single TTS model — `config_schema` + live `voice_count`. + + Parameters + ---------- + provider : str + + model : str + + workspace_id : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ApiResponseCatalogModelOut] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/v1/providers/{encode_path_param(provider)}/models/{encode_path_param(model)}", + method="GET", + headers={ + "X-Workspace-Id": str(workspace_id) if workspace_id is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ApiResponseCatalogModelOut, + parse_obj_as( + type_=ApiResponseCatalogModelOut, # 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( + HttpValidationError, + parse_obj_as( + type_=HttpValidationError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_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/src/onepin/reference.md b/src/onepin/reference.md index cd5d910..a3cff42 100644 --- a/src/onepin/reference.md +++ b/src/onepin/reference.md @@ -1713,6 +1713,12 @@ client.nodes.list_nodes() Return full node definition + runtime options for the canvas node-config UI. +**Deprecated (POD-612):** this version inlines the model catalog as +`options.models_by_provider`. Use `GET /api/v2/nodes/{node_type}`, which +replaces the inline tree with a `providers` HATEOAS href to the standalone +catalog `/api/v1/providers`. This endpoint is kept for one release while the +FE migrates, then removed. + Unlike `GET /nodes` (which returns only port schemas), this endpoint returns the actual runtime values a user picks: available target languages (from settings), the TTS model catalog grouped by provider, and a HATEOAS link to the workspace- @@ -1781,6 +1787,94 @@ client.nodes.get_node_detail( + + + + +
client.nodes.get_node_detail_v2(...) -> ApiResponseNodeDetailOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Return full node definition + runtime options (v2 — HATEOAS catalog href). + +POD-612: replaces the deprecated v1 ``options.models_by_provider`` inline tree +with a ``providers`` HATEOAS href to the standalone catalog +``/api/v1/providers``. The FE follows that href to fetch each model's +``config_schema`` lazily. The ``voices`` href (with its provider/model/language +filter enums) is unchanged, so the voice picker never needs the catalog call. +Requires ``X-Workspace-Id`` for a uniform FE contract. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.nodes.get_node_detail_v2( + node_type="node_type", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**node_type:** `str` + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -2029,6 +2123,445 @@ client.provider_keys.delete_provider_key( + + + + +## providers +
client.providers.list_catalog_providers(...) -> ApiListResponseCatalogProviderOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List TTS providers in the public catalog. + +Returns the processing (TTS) provider catalog with a per-provider model count +and a HATEOAS link to each provider's models. Lean / customer-safe — cost, +credentials, and base URLs are never exposed. Requires `X-Workspace-Id` (or a +workspace-bound API key with the `catalog:read` scope), matching `/voices`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.providers.list_catalog_providers() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.providers.get_catalog_provider(...) -> ApiResponseCatalogProviderOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get a single TTS provider by canonical name (e.g. `cartesia`). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.providers.get_catalog_provider( + provider="provider", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**provider:** `str` + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.providers.list_catalog_provider_models(...) -> ApiListResponseCatalogModelOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List a provider's TTS models, each with its `config_schema` and live `voice_count`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.providers.list_catalog_provider_models( + provider="provider", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**provider:** `str` + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.providers.list_catalog_provider_model_voices(...) -> ApiCountedListResponseCatalogVoiceOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List platform voices catalogued under an exact `(provider, model)`. + +Lean voice shape with a presigned `preview_url`. Platform catalog voices only +(System workspace); model-less voices are excluded. Paginated via `offset` / +`limit`. The flat `/voices?provider=&model=` endpoint remains for the picker. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.providers.list_catalog_provider_model_voices( + provider="provider", + model="model", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**provider:** `str` + +
+
+ +
+
+ +**model:** `str` + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.providers.get_catalog_provider_model(...) -> ApiResponseCatalogModelOut +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get a single TTS model — `config_schema` + live `voice_count`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from onepin import OnePinClient +from onepin.environment import OnePinClientEnvironment + +client = OnePinClient( + token="", + environment=OnePinClientEnvironment.PROD, +) + +client.providers.get_catalog_provider_model( + provider="provider", + model="model", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**provider:** `str` + +
+
+ +
+
+ +**model:** `str` + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
diff --git a/src/onepin/types/__init__.py b/src/onepin/types/__init__.py index bc316d6..06c892f 100644 --- a/src/onepin/types/__init__.py +++ b/src/onepin/types/__init__.py @@ -7,6 +7,7 @@ if typing.TYPE_CHECKING: from .api_counted_list_response_api_key_out import ApiCountedListResponseApiKeyOut + from .api_counted_list_response_catalog_voice_out import ApiCountedListResponseCatalogVoiceOut from .api_counted_list_response_voice_out import ApiCountedListResponseVoiceOut from .api_counted_list_response_workflow_list_item import ApiCountedListResponseWorkflowListItem from .api_counted_list_response_workflow_run_list_item import ApiCountedListResponseWorkflowRunListItem @@ -18,6 +19,8 @@ from .api_key_out import ApiKeyOut from .api_key_rotate_out import ApiKeyRotateOut from .api_key_scope import ApiKeyScope + from .api_list_response_catalog_model_out import ApiListResponseCatalogModelOut + from .api_list_response_catalog_provider_out import ApiListResponseCatalogProviderOut from .api_list_response_customer_plan_response import ApiListResponseCustomerPlanResponse from .api_list_response_dictionary_out import ApiListResponseDictionaryOut from .api_list_response_node_ports_out import ApiListResponseNodePortsOut @@ -32,6 +35,8 @@ from .api_response_api_key_rotate_out import ApiResponseApiKeyRotateOut from .api_response_auth_whoami_out import ApiResponseAuthWhoamiOut from .api_response_balance_response import ApiResponseBalanceResponse + from .api_response_catalog_model_out import ApiResponseCatalogModelOut + from .api_response_catalog_provider_out import ApiResponseCatalogProviderOut from .api_response_checkout_response import ApiResponseCheckoutResponse from .api_response_customer_plan_change_preview_response import ApiResponseCustomerPlanChangePreviewResponse from .api_response_customer_subscription_response import ApiResponseCustomerSubscriptionResponse @@ -74,6 +79,10 @@ from .auth_whoami_out import AuthWhoamiOut from .auth_whoami_out_auth_kind import AuthWhoamiOutAuthKind from .balance_response import BalanceResponse + from .catalog_link import CatalogLink + from .catalog_model_out import CatalogModelOut + from .catalog_provider_out import CatalogProviderOut + from .catalog_voice_out import CatalogVoiceOut from .checkout_response import CheckoutResponse from .counted_pagination_meta import CountedPaginationMeta from .customer_plan_change_preview_response import CustomerPlanChangePreviewResponse @@ -183,8 +192,8 @@ from .workflow_run_data_row_out import WorkflowRunDataRowOut from .workflow_run_data_row_out_auto_corrected_status import WorkflowRunDataRowOutAutoCorrectedStatus from .workflow_run_data_row_out_script_status import WorkflowRunDataRowOutScriptStatus - from .workflow_run_data_scores_out import WorkflowRunDataScoresOut - from .workflow_run_data_scores_out_accuracy_status import WorkflowRunDataScoresOutAccuracyStatus + from .workflow_run_data_validation_out import WorkflowRunDataValidationOut + from .workflow_run_data_validation_out_status import WorkflowRunDataValidationOutStatus from .workflow_run_data_voice_out import WorkflowRunDataVoiceOut from .workflow_run_data_voice_out_status import WorkflowRunDataVoiceOutStatus from .workflow_run_detail_out import WorkflowRunDetailOut @@ -217,6 +226,7 @@ from .workspace_workflows_stats_out import WorkspaceWorkflowsStatsOut _dynamic_imports: typing.Dict[str, str] = { "ApiCountedListResponseApiKeyOut": ".api_counted_list_response_api_key_out", + "ApiCountedListResponseCatalogVoiceOut": ".api_counted_list_response_catalog_voice_out", "ApiCountedListResponseVoiceOut": ".api_counted_list_response_voice_out", "ApiCountedListResponseWorkflowListItem": ".api_counted_list_response_workflow_list_item", "ApiCountedListResponseWorkflowRunListItem": ".api_counted_list_response_workflow_run_list_item", @@ -228,6 +238,8 @@ "ApiKeyOut": ".api_key_out", "ApiKeyRotateOut": ".api_key_rotate_out", "ApiKeyScope": ".api_key_scope", + "ApiListResponseCatalogModelOut": ".api_list_response_catalog_model_out", + "ApiListResponseCatalogProviderOut": ".api_list_response_catalog_provider_out", "ApiListResponseCustomerPlanResponse": ".api_list_response_customer_plan_response", "ApiListResponseDictionaryOut": ".api_list_response_dictionary_out", "ApiListResponseNodePortsOut": ".api_list_response_node_ports_out", @@ -242,6 +254,8 @@ "ApiResponseApiKeyRotateOut": ".api_response_api_key_rotate_out", "ApiResponseAuthWhoamiOut": ".api_response_auth_whoami_out", "ApiResponseBalanceResponse": ".api_response_balance_response", + "ApiResponseCatalogModelOut": ".api_response_catalog_model_out", + "ApiResponseCatalogProviderOut": ".api_response_catalog_provider_out", "ApiResponseCheckoutResponse": ".api_response_checkout_response", "ApiResponseCustomerPlanChangePreviewResponse": ".api_response_customer_plan_change_preview_response", "ApiResponseCustomerSubscriptionResponse": ".api_response_customer_subscription_response", @@ -282,6 +296,10 @@ "AuthWhoamiOut": ".auth_whoami_out", "AuthWhoamiOutAuthKind": ".auth_whoami_out_auth_kind", "BalanceResponse": ".balance_response", + "CatalogLink": ".catalog_link", + "CatalogModelOut": ".catalog_model_out", + "CatalogProviderOut": ".catalog_provider_out", + "CatalogVoiceOut": ".catalog_voice_out", "CheckoutResponse": ".checkout_response", "CountedPaginationMeta": ".counted_pagination_meta", "CustomerPlanChangePreviewResponse": ".customer_plan_change_preview_response", @@ -389,8 +407,8 @@ "WorkflowRunDataRowOut": ".workflow_run_data_row_out", "WorkflowRunDataRowOutAutoCorrectedStatus": ".workflow_run_data_row_out_auto_corrected_status", "WorkflowRunDataRowOutScriptStatus": ".workflow_run_data_row_out_script_status", - "WorkflowRunDataScoresOut": ".workflow_run_data_scores_out", - "WorkflowRunDataScoresOutAccuracyStatus": ".workflow_run_data_scores_out_accuracy_status", + "WorkflowRunDataValidationOut": ".workflow_run_data_validation_out", + "WorkflowRunDataValidationOutStatus": ".workflow_run_data_validation_out_status", "WorkflowRunDataVoiceOut": ".workflow_run_data_voice_out", "WorkflowRunDataVoiceOutStatus": ".workflow_run_data_voice_out_status", "WorkflowRunDetailOut": ".workflow_run_detail_out", @@ -447,6 +465,7 @@ def __dir__(): __all__ = [ "ApiCountedListResponseApiKeyOut", + "ApiCountedListResponseCatalogVoiceOut", "ApiCountedListResponseVoiceOut", "ApiCountedListResponseWorkflowListItem", "ApiCountedListResponseWorkflowRunListItem", @@ -458,6 +477,8 @@ def __dir__(): "ApiKeyOut", "ApiKeyRotateOut", "ApiKeyScope", + "ApiListResponseCatalogModelOut", + "ApiListResponseCatalogProviderOut", "ApiListResponseCustomerPlanResponse", "ApiListResponseDictionaryOut", "ApiListResponseNodePortsOut", @@ -472,6 +493,8 @@ def __dir__(): "ApiResponseApiKeyRotateOut", "ApiResponseAuthWhoamiOut", "ApiResponseBalanceResponse", + "ApiResponseCatalogModelOut", + "ApiResponseCatalogProviderOut", "ApiResponseCheckoutResponse", "ApiResponseCustomerPlanChangePreviewResponse", "ApiResponseCustomerSubscriptionResponse", @@ -512,6 +535,10 @@ def __dir__(): "AuthWhoamiOut", "AuthWhoamiOutAuthKind", "BalanceResponse", + "CatalogLink", + "CatalogModelOut", + "CatalogProviderOut", + "CatalogVoiceOut", "CheckoutResponse", "CountedPaginationMeta", "CustomerPlanChangePreviewResponse", @@ -619,8 +646,8 @@ def __dir__(): "WorkflowRunDataRowOut", "WorkflowRunDataRowOutAutoCorrectedStatus", "WorkflowRunDataRowOutScriptStatus", - "WorkflowRunDataScoresOut", - "WorkflowRunDataScoresOutAccuracyStatus", + "WorkflowRunDataValidationOut", + "WorkflowRunDataValidationOutStatus", "WorkflowRunDataVoiceOut", "WorkflowRunDataVoiceOutStatus", "WorkflowRunDetailOut", diff --git a/src/onepin/types/workflow_run_data_scores_out.py b/src/onepin/types/api_counted_list_response_catalog_voice_out.py similarity index 52% rename from src/onepin/types/workflow_run_data_scores_out.py rename to src/onepin/types/api_counted_list_response_catalog_voice_out.py index ae821ba..0709f39 100644 --- a/src/onepin/types/workflow_run_data_scores_out.py +++ b/src/onepin/types/api_counted_list_response_catalog_voice_out.py @@ -4,16 +4,15 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .workflow_run_data_scores_out_accuracy_status import WorkflowRunDataScoresOutAccuracyStatus +from .catalog_voice_out import CatalogVoiceOut +from .counted_pagination_meta import CountedPaginationMeta +from .meta import Meta -class WorkflowRunDataScoresOut(UniversalBaseModel): - accuracy: typing.Optional[float] = None - accuracy_status: WorkflowRunDataScoresOutAccuracyStatus - accuracy_reason: typing.Optional[str] = None - wer: typing.Optional[float] = None - cer: typing.Optional[float] = None - transcript: typing.Optional[str] = None +class ApiCountedListResponseCatalogVoiceOut(UniversalBaseModel): + data: typing.List[CatalogVoiceOut] + meta: Meta + pagination: CountedPaginationMeta if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/onepin/types/api_key_scope.py b/src/onepin/types/api_key_scope.py index 712b138..fd42c3b 100644 --- a/src/onepin/types/api_key_scope.py +++ b/src/onepin/types/api_key_scope.py @@ -14,6 +14,7 @@ "uploads:write", "workspace:read", "templates:read", + "catalog:read", ], typing.Any, ] diff --git a/src/onepin/types/api_list_response_catalog_model_out.py b/src/onepin/types/api_list_response_catalog_model_out.py new file mode 100644 index 0000000..e81d108 --- /dev/null +++ b/src/onepin/types/api_list_response_catalog_model_out.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 .catalog_model_out import CatalogModelOut +from .meta import Meta +from .pagination_meta import PaginationMeta + + +class ApiListResponseCatalogModelOut(UniversalBaseModel): + data: typing.List[CatalogModelOut] + meta: Meta + pagination: PaginationMeta + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/onepin/types/api_list_response_catalog_provider_out.py b/src/onepin/types/api_list_response_catalog_provider_out.py new file mode 100644 index 0000000..dabeadd --- /dev/null +++ b/src/onepin/types/api_list_response_catalog_provider_out.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 .catalog_provider_out import CatalogProviderOut +from .meta import Meta +from .pagination_meta import PaginationMeta + + +class ApiListResponseCatalogProviderOut(UniversalBaseModel): + data: typing.List[CatalogProviderOut] + meta: Meta + pagination: PaginationMeta + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/onepin/types/api_response_catalog_model_out.py b/src/onepin/types/api_response_catalog_model_out.py new file mode 100644 index 0000000..5dd2299 --- /dev/null +++ b/src/onepin/types/api_response_catalog_model_out.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 +from .catalog_model_out import CatalogModelOut +from .meta import Meta + + +class ApiResponseCatalogModelOut(UniversalBaseModel): + data: CatalogModelOut + meta: Meta + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/onepin/types/api_response_catalog_provider_out.py b/src/onepin/types/api_response_catalog_provider_out.py new file mode 100644 index 0000000..0f9b381 --- /dev/null +++ b/src/onepin/types/api_response_catalog_provider_out.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 +from .catalog_provider_out import CatalogProviderOut +from .meta import Meta + + +class ApiResponseCatalogProviderOut(UniversalBaseModel): + data: CatalogProviderOut + meta: Meta + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/onepin/types/catalog_link.py b/src/onepin/types/catalog_link.py new file mode 100644 index 0000000..5a2752e --- /dev/null +++ b/src/onepin/types/catalog_link.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 CatalogLink(UniversalBaseModel): + """ + HATEOAS link to a nested catalog resource (HAL-FORMS-flavored). + + The server emits a concrete, ready-to-call ``href`` (path segments already + filled in and URL-encoded) so the FE never constructs catalog URLs itself. + """ + + href: str + method: 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/src/onepin/types/catalog_model_out.py b/src/onepin/types/catalog_model_out.py new file mode 100644 index 0000000..05a0ba8 --- /dev/null +++ b/src/onepin/types/catalog_model_out.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 .catalog_link import CatalogLink + + +class CatalogModelOut(UniversalBaseModel): + """ + Catalog model entry — lean, customer-safe. + + ``config_schema`` is the per-model TTS config JSON-schema (from the provider + registry's Pydantic config class). ``voice_count`` is the number of active + platform voices catalogued under this exact ``(provider, model)``. + """ + + model: str + display_name: str + content_type: typing.Optional[str] = None + config_schema: typing.Optional[typing.Dict[str, typing.Any]] = None + voice_count: int + links: typing.Optional[typing.Dict[str, CatalogLink]] = 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/src/onepin/types/catalog_provider_out.py b/src/onepin/types/catalog_provider_out.py new file mode 100644 index 0000000..64fb849 --- /dev/null +++ b/src/onepin/types/catalog_provider_out.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 +from .catalog_link import CatalogLink + + +class CatalogProviderOut(UniversalBaseModel): + """ + Catalog provider entry — lean, customer-safe. + + Sourced from the in-memory ``ProviderRegistry`` (TTS / ``processing`` kind). + Cost, credentials, base_url, and enabled flags are excluded by construction. + """ + + provider: str + display_name: str + kind: str + model_count: int + links: typing.Optional[typing.Dict[str, CatalogLink]] = 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/src/onepin/types/catalog_voice_out.py b/src/onepin/types/catalog_voice_out.py new file mode 100644 index 0000000..a46102c --- /dev/null +++ b/src/onepin/types/catalog_voice_out.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 .voice_accent import VoiceAccent +from .voice_age import VoiceAge +from .voice_gender import VoiceGender + + +class CatalogVoiceOut(UniversalBaseModel): + """ + Lean voice entry for ``/providers/{p}/models/{m}/voices``. + + ``provider``/``model`` are implied by the path, so they are omitted here. + ``preview_url`` is a short-lived presigned S3 URL for the preview sample. + """ + + id: str + provider_voice_id: str + name: str + gender: typing.Optional[VoiceGender] = None + age: typing.Optional[VoiceAge] = None + accent: typing.Optional[VoiceAccent] = None + supported_languages: typing.Optional[typing.List[str]] = None + preview_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/src/onepin/types/node_type.py b/src/onepin/types/node_type.py index 36281c2..4794994 100644 --- a/src/onepin/types/node_type.py +++ b/src/onepin/types/node_type.py @@ -10,6 +10,7 @@ "processing_generator", "sink_preview", "validator_error_rate", + "validator_naturalness", ], typing.Any, ] diff --git a/src/onepin/types/workflow_run_data_card_out.py b/src/onepin/types/workflow_run_data_card_out.py index 56a1ea1..b4b9e16 100644 --- a/src/onepin/types/workflow_run_data_card_out.py +++ b/src/onepin/types/workflow_run_data_card_out.py @@ -6,7 +6,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .workflow_run_data_audio_out import WorkflowRunDataAudioOut from .workflow_run_data_card_out_waveform_status import WorkflowRunDataCardOutWaveformStatus -from .workflow_run_data_scores_out import WorkflowRunDataScoresOut +from .workflow_run_data_validation_out import WorkflowRunDataValidationOut from .workflow_run_data_voice_out import WorkflowRunDataVoiceOut @@ -18,7 +18,7 @@ class WorkflowRunDataCardOut(UniversalBaseModel): locale_code: typing.Optional[str] = None script: typing.Optional[str] = None audio: WorkflowRunDataAudioOut - scores: WorkflowRunDataScoresOut + validations: typing.Optional[typing.List[WorkflowRunDataValidationOut]] = None voice: WorkflowRunDataVoiceOut waveform_url: typing.Optional[str] = None waveform_status: typing.Optional[WorkflowRunDataCardOutWaveformStatus] = None diff --git a/src/onepin/types/workflow_run_data_validation_out.py b/src/onepin/types/workflow_run_data_validation_out.py new file mode 100644 index 0000000..71299fc --- /dev/null +++ b/src/onepin/types/workflow_run_data_validation_out.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 .workflow_run_data_validation_out_status import WorkflowRunDataValidationOutStatus + + +class WorkflowRunDataValidationOut(UniversalBaseModel): + """ + Per-validator scoring entry for a single line (POD-599). + + WER entries populate ``wer``/``cer``/``transcript``; naturalness entries + populate ``score`` (0-100). All fields except ``kind`` and ``status`` are + optional so future validator kinds can omit inapplicable fields. + """ + + kind: str + label: typing.Optional[str] = None + score: typing.Optional[float] = None + status: WorkflowRunDataValidationOutStatus + reason: typing.Optional[str] = None + wer: typing.Optional[float] = None + cer: typing.Optional[float] = None + transcript: 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/src/onepin/types/workflow_run_data_scores_out_accuracy_status.py b/src/onepin/types/workflow_run_data_validation_out_status.py similarity index 75% rename from src/onepin/types/workflow_run_data_scores_out_accuracy_status.py rename to src/onepin/types/workflow_run_data_validation_out_status.py index cdea3b8..d23296e 100644 --- a/src/onepin/types/workflow_run_data_scores_out_accuracy_status.py +++ b/src/onepin/types/workflow_run_data_validation_out_status.py @@ -2,6 +2,6 @@ import typing -WorkflowRunDataScoresOutAccuracyStatus = typing.Union[ +WorkflowRunDataValidationOutStatus = typing.Union[ typing.Literal["available", "not_ready", "unsupported", "unavailable"], typing.Any ]