Skip to content

Commit 8c1fa8d

Browse files
committed
Release 1.2.0
1 parent 8aa7d4d commit 8c1fa8d

File tree

9 files changed

+193
-37
lines changed

9 files changed

+193
-37
lines changed

poetry.lock

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

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "speechify-api"
33

44
[tool.poetry]
55
name = "speechify-api"
6-
version = "1.1.0"
6+
version = "1.2.0"
77
description = "Official Speechify API SDK"
88
readme = "README.md"
99
authors = [

reference.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,7 @@ Please refer to the list of the supported languages and recommendations regardin
9090
<dl>
9191
<dd>
9292

93-
**model:** `typing.Optional[GetSpeechRequestModel]`
94-
95-
Model used for audio synthesis
96-
simba-base ModelBase ModelBase is deprecated. Use simba-english or simba-multilingual instead. @deprecated
97-
simba-english ModelEnglish
98-
simba-multilingual ModelMultilingual
99-
simba-turbo ModelTurbo
93+
**model:** `typing.Optional[GetSpeechRequestModel]` — Model used for audio synthesis. `simba-base` and `simba-turbo` are deprecated. Use `simba-english` or `simba-multilingual` instead.
10094

10195
</dd>
10296
</dl>

src/speechify/core/client_wrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def get_headers(self) -> typing.Dict[str, str]:
2222
headers: typing.Dict[str, str] = {
2323
"X-Fern-Language": "Python",
2424
"X-Fern-SDK-Name": "speechify-api",
25-
"X-Fern-SDK-Version": "1.1.0",
25+
"X-Fern-SDK-Version": "1.2.0",
2626
}
2727
headers["Authorization"] = f"Bearer {self._get_token()}"
2828
return headers

src/speechify/tts/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@
2828
OAuthErrorError,
2929
SpeechMarks,
3030
)
31-
from .errors import BadRequestError, ForbiddenError, InternalServerError, NotFoundError, PaymentRequiredError
31+
from .errors import (
32+
BadRequestError,
33+
ForbiddenError,
34+
InternalServerError,
35+
NotFoundError,
36+
PaymentRequiredError,
37+
UnauthorizedError,
38+
)
3239
from . import audio, auth, voices
3340
from .audio import AudioStreamRequestAccept, GetSpeechRequestAudioFormat, GetSpeechRequestModel, GetStreamRequestModel
3441
from .auth import CreateAccessTokenRequestScope
@@ -71,6 +78,7 @@
7178
"OAuthErrorError",
7279
"PaymentRequiredError",
7380
"SpeechMarks",
81+
"UnauthorizedError",
7482
"VoicesCreateRequestGender",
7583
"audio",
7684
"auth",

src/speechify/tts/audio/client.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@ def speech(
6060
Please refer to the list of the supported languages and recommendations regarding this parameter: https://docs.sws.speechify.com/docs/language-support.
6161
6262
model : typing.Optional[GetSpeechRequestModel]
63-
Model used for audio synthesis
64-
simba-base ModelBase ModelBase is deprecated. Use simba-english or simba-multilingual instead. @deprecated
65-
simba-english ModelEnglish
66-
simba-multilingual ModelMultilingual
67-
simba-turbo ModelTurbo
63+
Model used for audio synthesis. `simba-base` and `simba-turbo` are deprecated. Use `simba-english` or `simba-multilingual` instead.
6864
6965
options : typing.Optional[GetSpeechOptionsRequest]
7066
@@ -192,11 +188,7 @@ def stream(
192188
Please refer to the list of the supported languages and recommendations regarding this parameter: https://docs.sws.speechify.com/docs/language-support.
193189
194190
model : typing.Optional[GetStreamRequestModel]
195-
Model used for audio synthesis
196-
simba-base ModelBase ModelBase is deprecated. Use simba-english or simba-multilingual instead. @deprecated
197-
simba-english ModelEnglish
198-
simba-multilingual ModelMultilingual
199-
simba-turbo ModelTurbo
191+
Model used for audio synthesis. `simba-base` and `simba-turbo` are deprecated. Use `simba-english` or `simba-multilingual` instead.
200192
201193
options : typing.Optional[GetStreamOptionsRequest]
202194
@@ -316,11 +308,7 @@ async def speech(
316308
Please refer to the list of the supported languages and recommendations regarding this parameter: https://docs.sws.speechify.com/docs/language-support.
317309
318310
model : typing.Optional[GetSpeechRequestModel]
319-
Model used for audio synthesis
320-
simba-base ModelBase ModelBase is deprecated. Use simba-english or simba-multilingual instead. @deprecated
321-
simba-english ModelEnglish
322-
simba-multilingual ModelMultilingual
323-
simba-turbo ModelTurbo
311+
Model used for audio synthesis. `simba-base` and `simba-turbo` are deprecated. Use `simba-english` or `simba-multilingual` instead.
324312
325313
options : typing.Optional[GetSpeechOptionsRequest]
326314
@@ -456,11 +444,7 @@ async def stream(
456444
Please refer to the list of the supported languages and recommendations regarding this parameter: https://docs.sws.speechify.com/docs/language-support.
457445
458446
model : typing.Optional[GetStreamRequestModel]
459-
Model used for audio synthesis
460-
simba-base ModelBase ModelBase is deprecated. Use simba-english or simba-multilingual instead. @deprecated
461-
simba-english ModelEnglish
462-
simba-multilingual ModelMultilingual
463-
simba-turbo ModelTurbo
447+
Model used for audio synthesis. `simba-base` and `simba-turbo` are deprecated. Use `simba-english` or `simba-multilingual` instead.
464448
465449
options : typing.Optional[GetStreamOptionsRequest]
466450

src/speechify/tts/errors/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,13 @@
55
from .internal_server_error import InternalServerError
66
from .not_found_error import NotFoundError
77
from .payment_required_error import PaymentRequiredError
8+
from .unauthorized_error import UnauthorizedError
89

9-
__all__ = ["BadRequestError", "ForbiddenError", "InternalServerError", "NotFoundError", "PaymentRequiredError"]
10+
__all__ = [
11+
"BadRequestError",
12+
"ForbiddenError",
13+
"InternalServerError",
14+
"NotFoundError",
15+
"PaymentRequiredError",
16+
"UnauthorizedError",
17+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
from ...core.api_error import ApiError
4+
import typing
5+
6+
7+
class UnauthorizedError(ApiError):
8+
def __init__(self, body: typing.Optional[typing.Any]):
9+
super().__init__(status_code=401, body=body)

src/speechify/tts/voices/client.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from ..errors.bad_request_error import BadRequestError
1616
from ..errors.payment_required_error import PaymentRequiredError
1717
from ...core.jsonable_encoder import jsonable_encoder
18+
from ..errors.unauthorized_error import UnauthorizedError
1819
from ...core.client_wrapper import AsyncClientWrapper
1920

2021
# this is used as the default value for optional parameters
@@ -277,6 +278,82 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] =
277278
raise ApiError(status_code=_response.status_code, body=_response.text)
278279
raise ApiError(status_code=_response.status_code, body=_response_json)
279280

281+
def download_sample(
282+
self, id: str, *, request_options: typing.Optional[RequestOptions] = None
283+
) -> typing.Iterator[bytes]:
284+
"""
285+
Download a personal (cloned) voice sample
286+
287+
Parameters
288+
----------
289+
id : str
290+
The ID of the voice to download sample for
291+
292+
request_options : typing.Optional[RequestOptions]
293+
Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
294+
295+
Yields
296+
------
297+
typing.Iterator[bytes]
298+
Voice sample audio file
299+
"""
300+
with self._client_wrapper.httpx_client.stream(
301+
f"v1/voices/{jsonable_encoder(id)}/sample",
302+
method="GET",
303+
request_options=request_options,
304+
) as _response:
305+
try:
306+
if 200 <= _response.status_code < 300:
307+
_chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
308+
for _chunk in _response.iter_bytes(chunk_size=_chunk_size):
309+
yield _chunk
310+
return
311+
_response.read()
312+
if _response.status_code == 400:
313+
raise BadRequestError(
314+
typing.cast(
315+
typing.Optional[typing.Any],
316+
parse_obj_as(
317+
type_=typing.Optional[typing.Any], # type: ignore
318+
object_=_response.json(),
319+
),
320+
)
321+
)
322+
if _response.status_code == 401:
323+
raise UnauthorizedError(
324+
typing.cast(
325+
typing.Optional[typing.Any],
326+
parse_obj_as(
327+
type_=typing.Optional[typing.Any], # type: ignore
328+
object_=_response.json(),
329+
),
330+
)
331+
)
332+
if _response.status_code == 404:
333+
raise NotFoundError(
334+
typing.cast(
335+
typing.Optional[typing.Any],
336+
parse_obj_as(
337+
type_=typing.Optional[typing.Any], # type: ignore
338+
object_=_response.json(),
339+
),
340+
)
341+
)
342+
if _response.status_code == 500:
343+
raise InternalServerError(
344+
typing.cast(
345+
typing.Optional[typing.Any],
346+
parse_obj_as(
347+
type_=typing.Optional[typing.Any], # type: ignore
348+
object_=_response.json(),
349+
),
350+
)
351+
)
352+
_response_json = _response.json()
353+
except JSONDecodeError:
354+
raise ApiError(status_code=_response.status_code, body=_response.text)
355+
raise ApiError(status_code=_response.status_code, body=_response_json)
356+
280357

281358
class AsyncVoicesClient:
282359
def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -557,3 +634,79 @@ async def main() -> None:
557634
except JSONDecodeError:
558635
raise ApiError(status_code=_response.status_code, body=_response.text)
559636
raise ApiError(status_code=_response.status_code, body=_response_json)
637+
638+
async def download_sample(
639+
self, id: str, *, request_options: typing.Optional[RequestOptions] = None
640+
) -> typing.AsyncIterator[bytes]:
641+
"""
642+
Download a personal (cloned) voice sample
643+
644+
Parameters
645+
----------
646+
id : str
647+
The ID of the voice to download sample for
648+
649+
request_options : typing.Optional[RequestOptions]
650+
Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
651+
652+
Yields
653+
------
654+
typing.AsyncIterator[bytes]
655+
Voice sample audio file
656+
"""
657+
async with self._client_wrapper.httpx_client.stream(
658+
f"v1/voices/{jsonable_encoder(id)}/sample",
659+
method="GET",
660+
request_options=request_options,
661+
) as _response:
662+
try:
663+
if 200 <= _response.status_code < 300:
664+
_chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
665+
async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size):
666+
yield _chunk
667+
return
668+
await _response.aread()
669+
if _response.status_code == 400:
670+
raise BadRequestError(
671+
typing.cast(
672+
typing.Optional[typing.Any],
673+
parse_obj_as(
674+
type_=typing.Optional[typing.Any], # type: ignore
675+
object_=_response.json(),
676+
),
677+
)
678+
)
679+
if _response.status_code == 401:
680+
raise UnauthorizedError(
681+
typing.cast(
682+
typing.Optional[typing.Any],
683+
parse_obj_as(
684+
type_=typing.Optional[typing.Any], # type: ignore
685+
object_=_response.json(),
686+
),
687+
)
688+
)
689+
if _response.status_code == 404:
690+
raise NotFoundError(
691+
typing.cast(
692+
typing.Optional[typing.Any],
693+
parse_obj_as(
694+
type_=typing.Optional[typing.Any], # type: ignore
695+
object_=_response.json(),
696+
),
697+
)
698+
)
699+
if _response.status_code == 500:
700+
raise InternalServerError(
701+
typing.cast(
702+
typing.Optional[typing.Any],
703+
parse_obj_as(
704+
type_=typing.Optional[typing.Any], # type: ignore
705+
object_=_response.json(),
706+
),
707+
)
708+
)
709+
_response_json = _response.json()
710+
except JSONDecodeError:
711+
raise ApiError(status_code=_response.status_code, body=_response.text)
712+
raise ApiError(status_code=_response.status_code, body=_response_json)

0 commit comments

Comments
 (0)