Skip to content

Commit 25422c6

Browse files
Release 1.1.9
1 parent 31f1315 commit 25422c6

30 files changed

Lines changed: 1279 additions & 234 deletions

.fern/metadata.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"cliVersion": "3.30.4",
3+
"generatorName": "fernapi/fern-python-sdk",
4+
"generatorVersion": "4.46.6",
5+
"generatorConfig": {
6+
"client_class_name": "Respeecher",
7+
"use_typeddict_requests": true,
8+
"should_generate_websocket_clients": true
9+
},
10+
"sdkVersion": "1.1.9"
11+
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ client.tts.bytes(
4949

5050
## Async Client
5151

52-
The SDK also exports an `async` client so that you can make non-blocking calls to our API.
52+
The SDK also exports an `async` client so that you can make non-blocking calls to our API. Note that if you are constructing an Async httpx client class to pass into this client, use `httpx.AsyncClient()` instead of `httpx.Client()` (e.g. for the `httpx_client` parameter of this client).
5353

5454
```python
5555
import asyncio
@@ -234,7 +234,7 @@ from respeecher import Respeecher
234234
client = Respeecher(
235235
...,
236236
httpx_client=httpx.Client(
237-
proxies="http://my.test.proxy.example.com",
237+
proxy="http://my.test.proxy.example.com",
238238
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
239239
),
240240
)

poetry.lock

Lines changed: 38 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[project]
22
name = "respeecher"
3+
dynamic = ["version"]
34

45
[tool.poetry]
56
name = "respeecher"
6-
version = "1.0.3"
7+
version = "1.1.9"
78
description = "Respeecher API SDK"
89
readme = "README.md"
910
authors = []
@@ -30,7 +31,7 @@ packages = [
3031
{ include = "respeecher", from = "src"}
3132
]
3233

33-
[project.urls]
34+
[tool.poetry.urls]
3435
Repository = 'https://github.com/respeecher/respeecher-python'
3536

3637
[tool.poetry.dependencies]
@@ -45,6 +46,7 @@ websockets = ">=12.0"
4546
mypy = "==1.13.0"
4647
pytest = "^7.4.0"
4748
pytest-asyncio = "^0.23.5"
49+
pytest-xdist = "^3.6.1"
4850
python-dateutil = "^2.9.0"
4951
types-python-dateutil = "^2.9.0.20240316"
5052
ruff = "==0.11.5"

reference.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Reference
22
## Tts
3-
<details><summary><code>client.tts.<a href="src/respeecher/tts/client.py">bytes</a>(...)</code></summary>
3+
<details><summary><code>client.tts.<a href="src/respeecher/tts/client.py">bytes</a>(...) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]</code></summary>
44
<dl>
55
<dd>
66

@@ -87,7 +87,7 @@ client.tts.bytes(
8787
</dl>
8888
</details>
8989

90-
<details><summary><code>client.tts.<a href="src/respeecher/tts/client.py">sse</a>(...)</code></summary>
90+
<details><summary><code>client.tts.<a href="src/respeecher/tts/client.py">sse</a>(...) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[ServerSentEvent]]]</code></summary>
9191
<dl>
9292
<dd>
9393

@@ -177,7 +177,7 @@ for chunk in response.data:
177177
</details>
178178

179179
## Voices
180-
<details><summary><code>client.voices.<a href="src/respeecher/voices/client.py">list</a>()</code></summary>
180+
<details><summary><code>client.voices.<a href="src/respeecher/voices/client.py">list</a>() -> AsyncHttpResponse[typing.List[Voice]]</code></summary>
181181
<dl>
182182
<dd>
183183

src/respeecher/__init__.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,50 @@
22

33
# isort: skip_file
44

5-
from . import tts, voices
6-
from .client import AsyncRespeecher, Respeecher
7-
from .environment import RespeecherEnvironment
8-
from .version import __version__
9-
from .voices import Gender, SamplingParams, SamplingParamsParams, Voice, VoiceParams
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from . import tts, voices
10+
from .client import AsyncRespeecher, Respeecher
11+
from .environment import RespeecherEnvironment
12+
from .version import __version__
13+
from .voices import Gender, SamplingParams, SamplingParamsParams, Voice, VoiceParams
14+
_dynamic_imports: typing.Dict[str, str] = {
15+
"AsyncRespeecher": ".client",
16+
"Gender": ".voices",
17+
"Respeecher": ".client",
18+
"RespeecherEnvironment": ".environment",
19+
"SamplingParams": ".voices",
20+
"SamplingParamsParams": ".voices",
21+
"Voice": ".voices",
22+
"VoiceParams": ".voices",
23+
"__version__": ".version",
24+
"tts": ".tts",
25+
"voices": ".voices",
26+
}
27+
28+
29+
def __getattr__(attr_name: str) -> typing.Any:
30+
module_name = _dynamic_imports.get(attr_name)
31+
if module_name is None:
32+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
33+
try:
34+
module = import_module(module_name, __package__)
35+
if module_name == f".{attr_name}":
36+
return module
37+
else:
38+
return getattr(module, attr_name)
39+
except ImportError as e:
40+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
41+
except AttributeError as e:
42+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
43+
44+
45+
def __dir__():
46+
lazy_attrs = list(_dynamic_imports.keys())
47+
return sorted(lazy_attrs)
48+
1049

1150
__all__ = [
1251
"AsyncRespeecher",

src/respeecher/client.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
# This file was auto-generated by Fern from our API Definition.
22

3+
from __future__ import annotations
4+
35
import os
46
import typing
57

68
import httpx
79
from .core.api_error import ApiError
810
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
911
from .environment import RespeecherEnvironment
10-
from .tts.client import AsyncTtsClient, TtsClient
11-
from .voices.client import AsyncVoicesClient, VoicesClient
12+
13+
if typing.TYPE_CHECKING:
14+
from .tts.client import AsyncTtsClient, TtsClient
15+
from .voices.client import AsyncVoicesClient, VoicesClient
1216

1317

1418
class Respeecher:
@@ -76,8 +80,24 @@ def __init__(
7680
else httpx.Client(timeout=_defaulted_timeout),
7781
timeout=_defaulted_timeout,
7882
)
79-
self.tts = TtsClient(client_wrapper=self._client_wrapper)
80-
self.voices = VoicesClient(client_wrapper=self._client_wrapper)
83+
self._tts: typing.Optional[TtsClient] = None
84+
self._voices: typing.Optional[VoicesClient] = None
85+
86+
@property
87+
def tts(self):
88+
if self._tts is None:
89+
from .tts.client import TtsClient # noqa: E402
90+
91+
self._tts = TtsClient(client_wrapper=self._client_wrapper)
92+
return self._tts
93+
94+
@property
95+
def voices(self):
96+
if self._voices is None:
97+
from .voices.client import VoicesClient # noqa: E402
98+
99+
self._voices = VoicesClient(client_wrapper=self._client_wrapper)
100+
return self._voices
81101

82102

83103
class AsyncRespeecher:
@@ -145,5 +165,21 @@ def __init__(
145165
else httpx.AsyncClient(timeout=_defaulted_timeout),
146166
timeout=_defaulted_timeout,
147167
)
148-
self.tts = AsyncTtsClient(client_wrapper=self._client_wrapper)
149-
self.voices = AsyncVoicesClient(client_wrapper=self._client_wrapper)
168+
self._tts: typing.Optional[AsyncTtsClient] = None
169+
self._voices: typing.Optional[AsyncVoicesClient] = None
170+
171+
@property
172+
def tts(self):
173+
if self._tts is None:
174+
from .tts.client import AsyncTtsClient # noqa: E402
175+
176+
self._tts = AsyncTtsClient(client_wrapper=self._client_wrapper)
177+
return self._tts
178+
179+
@property
180+
def voices(self):
181+
if self._voices is None:
182+
from .voices.client import AsyncVoicesClient # noqa: E402
183+
184+
self._voices = AsyncVoicesClient(client_wrapper=self._client_wrapper)
185+
return self._voices

src/respeecher/core/__init__.py

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,82 @@
22

33
# isort: skip_file
44

5-
from .api_error import ApiError
6-
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
7-
from .datetime_utils import serialize_datetime
8-
from .events import EventEmitterMixin, EventType
9-
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
10-
from .http_client import AsyncHttpClient, HttpClient
11-
from .http_response import AsyncHttpResponse, HttpResponse
12-
from .jsonable_encoder import jsonable_encoder
13-
from .pydantic_utilities import (
14-
IS_PYDANTIC_V2,
15-
UniversalBaseModel,
16-
UniversalRootModel,
17-
parse_obj_as,
18-
universal_field_validator,
19-
universal_root_validator,
20-
update_forward_refs,
21-
)
22-
from .query_encoder import encode_query
23-
from .remove_none_from_dict import remove_none_from_dict
24-
from .request_options import RequestOptions
25-
from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from .api_error import ApiError
10+
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
11+
from .datetime_utils import serialize_datetime
12+
from .events import EventEmitterMixin, EventType
13+
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
14+
from .http_client import AsyncHttpClient, HttpClient
15+
from .http_response import AsyncHttpResponse, HttpResponse
16+
from .jsonable_encoder import jsonable_encoder
17+
from .pydantic_utilities import (
18+
IS_PYDANTIC_V2,
19+
UniversalBaseModel,
20+
UniversalRootModel,
21+
parse_obj_as,
22+
universal_field_validator,
23+
universal_root_validator,
24+
update_forward_refs,
25+
)
26+
from .query_encoder import encode_query
27+
from .remove_none_from_dict import remove_none_from_dict
28+
from .request_options import RequestOptions
29+
from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
30+
_dynamic_imports: typing.Dict[str, str] = {
31+
"ApiError": ".api_error",
32+
"AsyncClientWrapper": ".client_wrapper",
33+
"AsyncHttpClient": ".http_client",
34+
"AsyncHttpResponse": ".http_response",
35+
"BaseClientWrapper": ".client_wrapper",
36+
"EventEmitterMixin": ".events",
37+
"EventType": ".events",
38+
"FieldMetadata": ".serialization",
39+
"File": ".file",
40+
"HttpClient": ".http_client",
41+
"HttpResponse": ".http_response",
42+
"IS_PYDANTIC_V2": ".pydantic_utilities",
43+
"RequestOptions": ".request_options",
44+
"SyncClientWrapper": ".client_wrapper",
45+
"UniversalBaseModel": ".pydantic_utilities",
46+
"UniversalRootModel": ".pydantic_utilities",
47+
"convert_and_respect_annotation_metadata": ".serialization",
48+
"convert_file_dict_to_httpx_tuples": ".file",
49+
"encode_query": ".query_encoder",
50+
"jsonable_encoder": ".jsonable_encoder",
51+
"parse_obj_as": ".pydantic_utilities",
52+
"remove_none_from_dict": ".remove_none_from_dict",
53+
"serialize_datetime": ".datetime_utils",
54+
"universal_field_validator": ".pydantic_utilities",
55+
"universal_root_validator": ".pydantic_utilities",
56+
"update_forward_refs": ".pydantic_utilities",
57+
"with_content_type": ".file",
58+
}
59+
60+
61+
def __getattr__(attr_name: str) -> typing.Any:
62+
module_name = _dynamic_imports.get(attr_name)
63+
if module_name is None:
64+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
65+
try:
66+
module = import_module(module_name, __package__)
67+
if module_name == f".{attr_name}":
68+
return module
69+
else:
70+
return getattr(module, attr_name)
71+
except ImportError as e:
72+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
73+
except AttributeError as e:
74+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
75+
76+
77+
def __dir__():
78+
lazy_attrs = list(_dynamic_imports.keys())
79+
return sorted(lazy_attrs)
80+
2681

2782
__all__ = [
2883
"ApiError",

0 commit comments

Comments
 (0)