Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .spec-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8f933ed904093dc331cc8d2a8bc9c6cf4ac5e03b
d5f013e70d4328c7c69b14d933b6db8b77fb41c9
2 changes: 1 addition & 1 deletion src/onepin/.fern/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
]
},
"originGitCommit": "aa97888912968233d7b8278a5e028789d15ef281",
"originGitCommit": "9acc656075c4ab37342d99405b9e12debae3aa64",
"originGitCommitIsDirty": false,
"invokedBy": "ci",
"ciProvider": "github"
Expand Down
20 changes: 20 additions & 0 deletions src/onepin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ class OnePinClient:
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.

stream_reconnection_enabled : typing.Optional[bool]
Whether to automatically reconnect on stream disconnection for resumable streaming endpoints. Defaults to True. Per-request `stream_reconnection_enabled` in `request_options` takes precedence over this value.

max_stream_reconnection_attempts : typing.Optional[int]
The maximum number of reconnection attempts for resumable streaming endpoints. Defaults to no limit. Per-request `max_stream_reconnection_attempts` 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.

Expand Down Expand Up @@ -86,6 +92,8 @@ def __init__(
headers: typing.Optional[typing.Dict[str, str]] = None,
timeout: typing.Optional[float] = None,
max_retries: typing.Optional[int] = None,
stream_reconnection_enabled: typing.Optional[bool] = None,
max_stream_reconnection_attempts: 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,
Expand All @@ -105,6 +113,8 @@ def __init__(
else httpx.Client(timeout=_defaulted_timeout),
timeout=_defaulted_timeout,
max_retries=_defaulted_max_retries,
stream_reconnection_enabled=stream_reconnection_enabled,
max_stream_reconnection_attempts=max_stream_reconnection_attempts,
logging=logging,
)
self._health: typing.Optional[HealthClient] = None
Expand Down Expand Up @@ -329,6 +339,12 @@ class AsyncOnePinClient:
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.

stream_reconnection_enabled : typing.Optional[bool]
Whether to automatically reconnect on stream disconnection for resumable streaming endpoints. Defaults to True. Per-request `stream_reconnection_enabled` in `request_options` takes precedence over this value.

max_stream_reconnection_attempts : typing.Optional[int]
The maximum number of reconnection attempts for resumable streaming endpoints. Defaults to no limit. Per-request `max_stream_reconnection_attempts` 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.

Expand Down Expand Up @@ -357,6 +373,8 @@ def __init__(
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
timeout: typing.Optional[float] = None,
max_retries: typing.Optional[int] = None,
stream_reconnection_enabled: typing.Optional[bool] = None,
max_stream_reconnection_attempts: 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,
Expand All @@ -375,6 +393,8 @@ def __init__(
else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects),
timeout=_defaulted_timeout,
max_retries=_defaulted_max_retries,
stream_reconnection_enabled=stream_reconnection_enabled,
max_stream_reconnection_attempts=max_stream_reconnection_attempts,
logging=logging,
)
self._health: typing.Optional[AsyncHealthClient] = None
Expand Down
32 changes: 30 additions & 2 deletions src/onepin/core/client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ def __init__(
base_url: str,
timeout: typing.Optional[float] = None,
max_retries: int = 2,
stream_reconnection_enabled: typing.Optional[bool] = None,
max_stream_reconnection_attempts: typing.Optional[int] = None,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
):
self._token = token
self._headers = headers
self._base_url = base_url
self._timeout = timeout
self._max_retries = max_retries
self._stream_reconnection_enabled = stream_reconnection_enabled
self._max_stream_reconnection_attempts = max_stream_reconnection_attempts
self._logging = logging

def get_headers(self) -> typing.Dict[str, str]:
Expand Down Expand Up @@ -58,6 +62,12 @@ def get_timeout(self) -> typing.Optional[float]:
def get_max_retries(self) -> int:
return self._max_retries

def get_stream_reconnection_enabled(self) -> bool:
return self._stream_reconnection_enabled if self._stream_reconnection_enabled is not None else True

def get_max_stream_reconnection_attempts(self) -> typing.Optional[int]:
return self._max_stream_reconnection_attempts


class SyncClientWrapper(BaseClientWrapper):
def __init__(
Expand All @@ -68,11 +78,20 @@ def __init__(
base_url: str,
timeout: typing.Optional[float] = None,
max_retries: int = 2,
stream_reconnection_enabled: typing.Optional[bool] = None,
max_stream_reconnection_attempts: typing.Optional[int] = None,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
httpx_client: httpx.Client,
):
super().__init__(
token=token, headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries, logging=logging
token=token,
headers=headers,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
stream_reconnection_enabled=stream_reconnection_enabled,
max_stream_reconnection_attempts=max_stream_reconnection_attempts,
logging=logging,
)
self.httpx_client = HttpClient(
httpx_client=httpx_client,
Expand All @@ -93,12 +112,21 @@ def __init__(
base_url: str,
timeout: typing.Optional[float] = None,
max_retries: int = 2,
stream_reconnection_enabled: typing.Optional[bool] = None,
max_stream_reconnection_attempts: typing.Optional[int] = None,
logging: typing.Optional[typing.Union[LogConfig, Logger]] = None,
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
httpx_client: httpx.AsyncClient,
):
super().__init__(
token=token, headers=headers, base_url=base_url, timeout=timeout, max_retries=max_retries, logging=logging
token=token,
headers=headers,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
stream_reconnection_enabled=stream_reconnection_enabled,
max_stream_reconnection_attempts=max_stream_reconnection_attempts,
logging=logging,
)
self._async_token = async_token
self.httpx_client = AsyncHttpClient(
Expand Down
14 changes: 12 additions & 2 deletions src/onepin/core/http_sse/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import codecs
import re
from contextlib import asynccontextmanager, contextmanager
from typing import Any, AsyncGenerator, AsyncIterator, Iterator
from typing import Any, AsyncGenerator, AsyncIterator, Iterator, Optional

import httpx
from ._decoders import SSEDecoder
Expand All @@ -14,8 +14,18 @@


class EventSource:
def __init__(self, response: httpx.Response) -> None:
def __init__(
self,
response: httpx.Response,
*,
resumable: bool = False,
stream_reconnection_enabled: bool = True,
max_stream_reconnection_attempts: Optional[int] = None,
) -> None:
self._response = response
self._resumable = resumable
self._stream_reconnection_enabled = stream_reconnection_enabled
self._max_stream_reconnection_attempts = max_stream_reconnection_attempts

def _check_content_type(self) -> None:
content_type = self._response.headers.get("content-type", "").partition(";")[0]
Expand Down
2 changes: 2 additions & 0 deletions src/onepin/core/request_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ class RequestOptions(typing.TypedDict, total=False):
additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]]
additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]]
chunk_size: NotRequired[int]
stream_reconnection_enabled: NotRequired[bool]
max_stream_reconnection_attempts: NotRequired[int]
14 changes: 8 additions & 6 deletions src/onepin/providers/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,12 @@ def list_catalog_provider_model_voices(
request_options: typing.Optional[RequestOptions] = None,
) -> ApiCountedListResponseCatalogVoiceOut:
"""
List platform voices catalogued under an exact `(provider, model)`.
List platform voices whose `supported_models` contains `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.
(System workspace); a voice surfaces under every model in its `supported_models`
array (JSONB `@>`), and voices with no models (NULL) surface under none. Paginated
via `offset` / `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker.

Parameters
----------
Expand Down Expand Up @@ -408,11 +409,12 @@ async def list_catalog_provider_model_voices(
request_options: typing.Optional[RequestOptions] = None,
) -> ApiCountedListResponseCatalogVoiceOut:
"""
List platform voices catalogued under an exact `(provider, model)`.
List platform voices whose `supported_models` contains `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.
(System workspace); a voice surfaces under every model in its `supported_models`
array (JSONB `@>`), and voices with no models (NULL) surface under none. Paginated
via `offset` / `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker.

Parameters
----------
Expand Down
14 changes: 8 additions & 6 deletions src/onepin/providers/raw_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,12 @@ def list_catalog_provider_model_voices(
request_options: typing.Optional[RequestOptions] = None,
) -> HttpResponse[ApiCountedListResponseCatalogVoiceOut]:
"""
List platform voices catalogued under an exact `(provider, model)`.
List platform voices whose `supported_models` contains `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.
(System workspace); a voice surfaces under every model in its `supported_models`
array (JSONB `@>`), and voices with no models (NULL) surface under none. Paginated
via `offset` / `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker.

Parameters
----------
Expand Down Expand Up @@ -620,11 +621,12 @@ async def list_catalog_provider_model_voices(
request_options: typing.Optional[RequestOptions] = None,
) -> AsyncHttpResponse[ApiCountedListResponseCatalogVoiceOut]:
"""
List platform voices catalogued under an exact `(provider, model)`.
List platform voices whose `supported_models` contains `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.
(System workspace); a voice surfaces under every model in its `supported_models`
array (JSONB `@>`), and voices with no models (NULL) surface under none. Paginated
via `offset` / `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker.

Parameters
----------
Expand Down
7 changes: 4 additions & 3 deletions src/onepin/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2378,11 +2378,12 @@ client.providers.list_catalog_provider_models(
<dl>
<dd>

List platform voices catalogued under an exact `(provider, model)`.
List platform voices whose `supported_models` contains `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.
(System workspace); a voice surfaces under every model in its `supported_models`
array (JSONB `@>`), and voices with no models (NULL) surface under none. Paginated
via `offset` / `limit`. The flat `/voices?provider=&model=` endpoint remains for the picker.
</dd>
</dl>
</dd>
Expand Down
1 change: 1 addition & 0 deletions src/onepin/types/node_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"sink_preview",
"validator_error_rate",
"validator_naturalness",
"validator_noise",
],
typing.Any,
]
2 changes: 1 addition & 1 deletion src/onepin/types/voice_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class VoiceOut(UniversalBaseModel):
name: str
provider: str
provider_voice_id: str
model: typing.Optional[str] = None
description: typing.Optional[str] = None
is_active: bool
gender: typing.Optional[VoiceGender] = None
Expand All @@ -33,6 +32,7 @@ class VoiceOut(UniversalBaseModel):
duration_seconds: typing.Optional[float] = None
sample_url: typing.Optional[str] = None
supported_languages: typing.Optional[typing.List[str]] = None
supported_models: typing.Optional[typing.List[str]] = None
is_favorite: typing.Optional[bool] = None
created_at: dt.datetime
updated_at: dt.datetime
Expand Down
2 changes: 1 addition & 1 deletion src/onepin/types/voice_similar_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class VoiceSimilarOut(UniversalBaseModel):
name: str
provider: str
provider_voice_id: str
model: typing.Optional[str] = None
description: typing.Optional[str] = None
is_active: bool
gender: typing.Optional[VoiceGender] = None
Expand All @@ -33,6 +32,7 @@ class VoiceSimilarOut(UniversalBaseModel):
duration_seconds: typing.Optional[float] = None
sample_url: typing.Optional[str] = None
supported_languages: typing.Optional[typing.List[str]] = None
supported_models: typing.Optional[typing.List[str]] = None
is_favorite: typing.Optional[bool] = None
created_at: dt.datetime
updated_at: dt.datetime
Expand Down
Loading