Skip to content

Commit

Permalink
(fix): remove pydantic warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
fern-api[bot] committed Sep 18, 2024
1 parent 8110b5c commit a9e6d06
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 178 deletions.
194 changes: 97 additions & 97 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "elevenlabs"
version = "1.8.1"
version = "1.8.2"
description = ""
readme = "README.md"
authors = []
Expand Down
3 changes: 2 additions & 1 deletion src/elevenlabs/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .api_error import ApiError
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
from .datetime_utils import serialize_datetime
from .file import File, convert_file_dict_to_httpx_tuples
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
from .http_client import AsyncHttpClient, HttpClient
from .jsonable_encoder import jsonable_encoder
from .pydantic_utilities import (
Expand Down Expand Up @@ -47,4 +47,5 @@
"universal_field_validator",
"universal_root_validator",
"update_forward_refs",
"with_content_type",
]
2 changes: 1 addition & 1 deletion src/elevenlabs/core/client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.1",
"X-Fern-SDK-Version": "1.8.2",
}
if self._api_key is not None:
headers["xi-api-key"] = self._api_key
Expand Down
41 changes: 30 additions & 11 deletions src/elevenlabs/core/file.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# This file was auto-generated by Fern from our API Definition.

import typing
from typing import IO, Dict, List, Mapping, Optional, Tuple, Union, cast

# File typing inspired by the flexibility of types within the httpx library
# https://github.com/encode/httpx/blob/master/httpx/_types.py
FileContent = typing.Union[typing.IO[bytes], bytes, str]
File = typing.Union[
FileContent = Union[IO[bytes], bytes, str]
File = Union[
# file (or bytes)
FileContent,
# (filename, file (or bytes))
typing.Tuple[typing.Optional[str], FileContent],
Tuple[Optional[str], FileContent],
# (filename, file (or bytes), content_type)
typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str]],
Tuple[Optional[str], FileContent, Optional[str]],
# (filename, file (or bytes), content_type, headers)
typing.Tuple[
typing.Optional[str],
Tuple[
Optional[str],
FileContent,
typing.Optional[str],
typing.Mapping[str, str],
Optional[str],
Mapping[str, str],
],
]


def convert_file_dict_to_httpx_tuples(
d: typing.Dict[str, typing.Union[File, typing.List[File]]],
) -> typing.List[typing.Tuple[str, File]]:
d: Dict[str, Union[File, List[File]]],
) -> List[Tuple[str, File]]:
"""
The format we use is a list of tuples, where the first element is the
name of the file and the second is the file object. Typically HTTPX wants
Expand All @@ -41,3 +41,22 @@ def convert_file_dict_to_httpx_tuples(
else:
httpx_tuples.append((key, file_like))
return httpx_tuples


def with_content_type(*, file: File, content_type: str) -> File:
""" """
if isinstance(file, tuple):
if len(file) == 2:
filename, content = cast(Tuple[Optional[str], FileContent], file) # type: ignore
return (filename, content, content_type)
elif len(file) == 3:
filename, content, _ = cast(Tuple[Optional[str], FileContent, Optional[str]], file) # type: ignore
return (filename, content, content_type)
elif len(file) == 4:
filename, content, _, headers = cast( # type: ignore
Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], file
)
return (filename, content, content_type, headers)
else:
raise ValueError(f"Unexpected tuple length: {len(file)}")
return (None, file, content_type)
82 changes: 58 additions & 24 deletions src/elevenlabs/core/pydantic_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,30 +99,64 @@ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
Override the default dict method to `exclude_unset` by default. This function patches
`exclude_unset` to work include fields within non-None default values.
"""
_fields_set = self.__fields_set__

fields = _get_model_fields(self.__class__)
for name, field in fields.items():
if name not in _fields_set:
default = _get_field_default(field)

# If the default values are non-null act like they've been set
# This effectively allows exclude_unset to work like exclude_none where
# the latter passes through intentionally set none values.
if default != None:
_fields_set.add(name)

kwargs_with_defaults_exclude_unset: typing.Any = {
"by_alias": True,
"exclude_unset": True,
"include": _fields_set,
**kwargs,
}

# Note: the logic here is multi-plexed given the levers exposed in Pydantic V1 vs V2
# Pydantic V1's .dict can be extremely slow, so we do not want to call it twice.
#
# We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
# that we have less control over, and this is less intrusive than custom serializers for now.
if IS_PYDANTIC_V2:
return super().model_dump(**kwargs_with_defaults_exclude_unset) # type: ignore # Pydantic v2
kwargs_with_defaults_exclude_unset: typing.Any = {
**kwargs,
"by_alias": True,
"exclude_unset": True,
"exclude_none": False,
}
kwargs_with_defaults_exclude_none: typing.Any = {
**kwargs,
"by_alias": True,
"exclude_none": True,
"exclude_unset": False,
}
return 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
)

else:
return super().dict(**kwargs_with_defaults_exclude_unset)
_fields_set = self.__fields_set__

fields = _get_model_fields(self.__class__)
for name, field in fields.items():
if name not in _fields_set:
default = _get_field_default(field)

# If the default values are non-null act like they've been set
# This effectively allows exclude_unset to work like exclude_none where
# the latter passes through intentionally set none values.
if default != None:
_fields_set.add(name)

kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
"by_alias": True,
"exclude_unset": True,
"include": _fields_set,
**kwargs,
}

return super().dict(**kwargs_with_defaults_exclude_unset_include_fields)


def deep_union_pydantic_dicts(
source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
) -> typing.Dict[str, typing.Any]:
for key, value in source.items():
if isinstance(value, dict):
node = destination.setdefault(key, {})
deep_union_pydantic_dicts(value, node)
else:
destination[key] = value

return destination


if IS_PYDANTIC_V2:
Expand All @@ -149,11 +183,11 @@ def encode_by_type(o: typing.Any) -> typing.Any:
return encoder(o)


def update_forward_refs(model: typing.Type["Model"]) -> None:
def update_forward_refs(model: typing.Type["Model"], **localns: typing.Any) -> None:
if IS_PYDANTIC_V2:
model.model_rebuild(raise_errors=False) # type: ignore # Pydantic v2
else:
model.update_forward_refs()
model.update_forward_refs(**localns)


# Mirrors Pydantic's internal typing
Expand Down
Loading

0 comments on commit a9e6d06

Please sign in to comment.