From 317b471eebfea68c70c35839a1d5c6264018446f Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:03:51 -0400 Subject: [PATCH] (chore): remove pydantic aliases (#364) --- pyproject.toml | 2 +- src/elevenlabs/core/client_wrapper.py | 2 +- src/elevenlabs/core/pydantic_utilities.py | 53 +++++++++--- src/elevenlabs/projects/client.py | 13 ++- .../pronunciation_dictionary/client.py | 9 ++- src/elevenlabs/text_to_speech/client.py | 81 +++++++++++++++---- src/elevenlabs/types/audio_output.py | 12 ++- src/elevenlabs/types/initialize_connection.py | 4 +- .../types/library_voice_response.py | 12 ++- src/elevenlabs/voices/client.py | 5 +- 10 files changed, 149 insertions(+), 44 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b0948ee..c9d0bb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "elevenlabs" -version = "1.8.2" +version = "1.9.0" description = "" readme = "README.md" authors = [] diff --git a/src/elevenlabs/core/client_wrapper.py b/src/elevenlabs/core/client_wrapper.py index 01c2ba8..6b0813a 100644 --- a/src/elevenlabs/core/client_wrapper.py +++ b/src/elevenlabs/core/client_wrapper.py @@ -16,7 +16,7 @@ def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "elevenlabs", - "X-Fern-SDK-Version": "1.8.2", + "X-Fern-SDK-Version": "1.9.0", } if self._api_key is not None: headers["xi-api-key"] = self._api_key diff --git a/src/elevenlabs/core/pydantic_utilities.py b/src/elevenlabs/core/pydantic_utilities.py index 34b1136..c14b482 100644 --- a/src/elevenlabs/core/pydantic_utilities.py +++ b/src/elevenlabs/core/pydantic_utilities.py @@ -10,6 +10,7 @@ import pydantic from .datetime_utils import serialize_datetime +from .serialization import convert_and_respect_annotation_metadata IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") @@ -56,11 +57,12 @@ def parse_obj_as(type_: typing.Type[T], object_: typing.Any) -> T: + dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read") if IS_PYDANTIC_V2: adapter = pydantic.TypeAdapter(type_) # type: ignore # Pydantic v2 - return adapter.validate_python(object_) + return adapter.validate_python(dealiased_object) else: - return pydantic.parse_obj_as(type_, object_) + return pydantic.parse_obj_as(type_, dealiased_object) def to_jsonable_with_fallback( @@ -75,13 +77,40 @@ def to_jsonable_with_fallback( class UniversalBaseModel(pydantic.BaseModel): - class Config: - populate_by_name = True - smart_union = True - allow_population_by_field_name = True - json_encoders = {dt.datetime: serialize_datetime} - # Allow fields begining with `model_` to be used in the model - protected_namespaces = () + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( + # Allow fields begining with `model_` to be used in the model + protected_namespaces=(), + ) # type: ignore # Pydantic v2 + + @pydantic.model_serializer(mode="wrap", when_used="json") # type: ignore # Pydantic v2 + def serialize_model(self, handler: pydantic.SerializerFunctionWrapHandler) -> typing.Any: # type: ignore # Pydantic v2 + serialized = handler(self) + data = {k: serialize_datetime(v) if isinstance(v, dt.datetime) else v for k, v in serialized.items()} + return data + + else: + + class Config: + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} + + @classmethod + def model_construct( + cls: typing.Type["Model"], _fields_set: typing.Optional[typing.Set[str]] = None, **values: typing.Any + ) -> "Model": + dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read") + return cls.construct(_fields_set, **dealiased_object) + + @classmethod + def construct( + cls: typing.Type["Model"], _fields_set: typing.Optional[typing.Set[str]] = None, **values: typing.Any + ) -> "Model": + dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read") + if IS_PYDANTIC_V2: + return super().model_construct(_fields_set, **dealiased_object) # type: ignore # Pydantic v2 + else: + return super().construct(_fields_set, **dealiased_object) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = { @@ -117,7 +146,7 @@ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: "exclude_none": True, "exclude_unset": False, } - return deep_union_pydantic_dicts( + dict_dump = deep_union_pydantic_dicts( super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore # Pydantic v2 super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore # Pydantic v2 ) @@ -143,7 +172,9 @@ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: **kwargs, } - return super().dict(**kwargs_with_defaults_exclude_unset_include_fields) + dict_dump = super().dict(**kwargs_with_defaults_exclude_unset_include_fields) + + return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write") def deep_union_pydantic_dicts( diff --git a/src/elevenlabs/projects/client.py b/src/elevenlabs/projects/client.py index 8ed3f28..6f8ca56 100644 --- a/src/elevenlabs/projects/client.py +++ b/src/elevenlabs/projects/client.py @@ -16,6 +16,7 @@ from ..types.edit_project_response_model import EditProjectResponseModel from ..types.project_snapshots_response import ProjectSnapshotsResponse from ..types.pronunciation_dictionary_version_locator import PronunciationDictionaryVersionLocator +from ..core.serialization import convert_and_respect_annotation_metadata from ..core.client_wrapper import AsyncClientWrapper # this is used as the default value for optional parameters @@ -729,7 +730,11 @@ def update_pronunciation_dictionaries( f"v1/projects/{jsonable_encoder(project_id)}/update-pronunciation-dictionaries", method="POST", json={ - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), }, request_options=request_options, omit=OMIT, @@ -1546,7 +1551,11 @@ async def main() -> None: f"v1/projects/{jsonable_encoder(project_id)}/update-pronunciation-dictionaries", method="POST", json={ - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), }, request_options=request_options, omit=OMIT, diff --git a/src/elevenlabs/pronunciation_dictionary/client.py b/src/elevenlabs/pronunciation_dictionary/client.py index bae8a5d..84a4c4c 100644 --- a/src/elevenlabs/pronunciation_dictionary/client.py +++ b/src/elevenlabs/pronunciation_dictionary/client.py @@ -16,6 +16,7 @@ from .types.pronunciation_dictionary_rule import PronunciationDictionaryRule from ..types.add_pronunciation_dictionary_rules_response_model import AddPronunciationDictionaryRulesResponseModel from ..core.jsonable_encoder import jsonable_encoder +from ..core.serialization import convert_and_respect_annotation_metadata from ..types.remove_pronunciation_dictionary_rules_response_model import RemovePronunciationDictionaryRulesResponseModel from ..types.get_pronunciation_dictionary_metadata_response import GetPronunciationDictionaryMetadataResponse from ..types.get_pronunciation_dictionaries_metadata_response_model import ( @@ -167,7 +168,9 @@ def add_rules_to_the_pronunciation_dictionary( f"v1/pronunciation-dictionaries/{jsonable_encoder(pronunciation_dictionary_id)}/add-rules", method="POST", json={ - "rules": rules, + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[PronunciationDictionaryRule], direction="write" + ), }, request_options=request_options, omit=OMIT, @@ -610,7 +613,9 @@ async def main() -> None: f"v1/pronunciation-dictionaries/{jsonable_encoder(pronunciation_dictionary_id)}/add-rules", method="POST", json={ - "rules": rules, + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[PronunciationDictionaryRule], direction="write" + ), }, request_options=request_options, omit=OMIT, diff --git a/src/elevenlabs/text_to_speech/client.py b/src/elevenlabs/text_to_speech/client.py index e99fcf8..95d17fa 100644 --- a/src/elevenlabs/text_to_speech/client.py +++ b/src/elevenlabs/text_to_speech/client.py @@ -8,6 +8,7 @@ from ..types.pronunciation_dictionary_version_locator import PronunciationDictionaryVersionLocator from ..core.request_options import RequestOptions from ..core.jsonable_encoder import jsonable_encoder +from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..types.http_validation_error import HttpValidationError from ..core.unchecked_base_model import construct_type @@ -130,8 +131,14 @@ def convert( "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -262,8 +269,14 @@ def convert_with_timestamps( "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -404,8 +417,14 @@ def convert_as_stream( "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -535,8 +554,14 @@ def stream_with_timestamps( "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -684,8 +709,14 @@ async def main() -> None: "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -824,8 +855,14 @@ async def main() -> None: "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -974,8 +1011,14 @@ async def main() -> None: "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, @@ -1113,8 +1156,14 @@ async def main() -> None: "text": text, "model_id": model_id, "language_code": language_code, - "voice_settings": voice_settings, - "pronunciation_dictionary_locators": pronunciation_dictionary_locators, + "voice_settings": convert_and_respect_annotation_metadata( + object_=voice_settings, annotation=VoiceSettings, direction="write" + ), + "pronunciation_dictionary_locators": convert_and_respect_annotation_metadata( + object_=pronunciation_dictionary_locators, + annotation=typing.Sequence[PronunciationDictionaryVersionLocator], + direction="write", + ), "seed": seed, "previous_text": previous_text, "next_text": next_text, diff --git a/src/elevenlabs/types/audio_output.py b/src/elevenlabs/types/audio_output.py index 96b96df..ac0c7c1 100644 --- a/src/elevenlabs/types/audio_output.py +++ b/src/elevenlabs/types/audio_output.py @@ -3,6 +3,8 @@ from ..core.unchecked_base_model import UncheckedBaseModel import typing import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata from .normalized_alignment import NormalizedAlignment from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -14,14 +16,16 @@ class AudioOutput(UncheckedBaseModel): is MP3 encoded as a base64 string. """ - is_final: typing.Optional[bool] = pydantic.Field(alias="isFinal", default=None) + is_final: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isFinal")] = pydantic.Field( + default=None + ) """ Indicates if the generation is complete. If set to `True`, `audio` will be null. """ - normalized_alignment: typing.Optional[NormalizedAlignment] = pydantic.Field( - alias="normalizedAlignment", default=None - ) + normalized_alignment: typing_extensions.Annotated[ + typing.Optional[NormalizedAlignment], FieldMetadata(alias="normalizedAlignment") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/elevenlabs/types/initialize_connection.py b/src/elevenlabs/types/initialize_connection.py index b3d7b45..efc1d88 100644 --- a/src/elevenlabs/types/initialize_connection.py +++ b/src/elevenlabs/types/initialize_connection.py @@ -5,6 +5,8 @@ import pydantic from .realtime_voice_settings import RealtimeVoiceSettings from .generation_config import GenerationConfig +import typing_extensions +from ..core.serialization import FieldMetadata from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -20,7 +22,7 @@ class InitializeConnection(UncheckedBaseModel): This property should only be provided in the first message you send. """ - xi_api_key: str = pydantic.Field(alias="xi-api-key") + xi_api_key: typing_extensions.Annotated[str, FieldMetadata(alias="xi-api-key")] = pydantic.Field() """ Your ElevenLabs API key. This is a required parameter that should be provided in the first message you send. You can find your API key in the [API Keys section](https://elevenlabs.io/docs/api-reference/websockets#api-keys). diff --git a/src/elevenlabs/types/library_voice_response.py b/src/elevenlabs/types/library_voice_response.py index 531e9bf..bba76f2 100644 --- a/src/elevenlabs/types/library_voice_response.py +++ b/src/elevenlabs/types/library_voice_response.py @@ -1,9 +1,11 @@ # This file was auto-generated by Fern from our API Definition. from ..core.unchecked_base_model import UncheckedBaseModel -import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata import typing from ..core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic class LibraryVoiceResponse(UncheckedBaseModel): @@ -20,9 +22,11 @@ class LibraryVoiceResponse(UncheckedBaseModel): language: str description: str preview_url: str - usage_character_count_1_y: int = pydantic.Field(alias="usage_character_count_1y") - usage_character_count_7_d: int = pydantic.Field(alias="usage_character_count_7d") - play_api_usage_character_count_1_y: int = pydantic.Field(alias="play_api_usage_character_count_1y") + usage_character_count_1_y: typing_extensions.Annotated[int, FieldMetadata(alias="usage_character_count_1y")] + usage_character_count_7_d: typing_extensions.Annotated[int, FieldMetadata(alias="usage_character_count_7d")] + play_api_usage_character_count_1_y: typing_extensions.Annotated[ + int, FieldMetadata(alias="play_api_usage_character_count_1y") + ] cloned_by_count: int rate: float free_users_allowed: bool diff --git a/src/elevenlabs/voices/client.py b/src/elevenlabs/voices/client.py index bcea9e2..747515c 100644 --- a/src/elevenlabs/voices/client.py +++ b/src/elevenlabs/voices/client.py @@ -12,6 +12,7 @@ from ..types.voice_settings import VoiceSettings from ..core.jsonable_encoder import jsonable_encoder from ..types.voice import Voice +from ..core.serialization import convert_and_respect_annotation_metadata from .. import core from ..types.add_voice_response_model import AddVoiceResponseModel from ..types.get_library_voices_response import GetLibraryVoicesResponse @@ -353,7 +354,7 @@ def edit_settings( _response = self._client_wrapper.httpx_client.request( f"v1/voices/{jsonable_encoder(voice_id)}/settings/edit", method="POST", - json=request, + json=convert_and_respect_annotation_metadata(object_=request, annotation=VoiceSettings, direction="write"), request_options=request_options, omit=OMIT, ) @@ -1283,7 +1284,7 @@ async def main() -> None: _response = await self._client_wrapper.httpx_client.request( f"v1/voices/{jsonable_encoder(voice_id)}/settings/edit", method="POST", - json=request, + json=convert_and_respect_annotation_metadata(object_=request, annotation=VoiceSettings, direction="write"), request_options=request_options, omit=OMIT, )