athena-intelligence 0.1.127__py3-none-any.whl → 0.1.184__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. athena/__init__.py +24 -3
  2. athena/agents/__init__.py +2 -0
  3. athena/agents/client.py +51 -95
  4. athena/agents/drive/__init__.py +2 -0
  5. athena/agents/drive/client.py +31 -80
  6. athena/agents/drive/raw_client.py +155 -0
  7. athena/agents/general/__init__.py +2 -0
  8. athena/agents/general/client.py +91 -238
  9. athena/agents/general/raw_client.py +369 -0
  10. athena/agents/raw_client.py +176 -0
  11. athena/agents/research/__init__.py +2 -0
  12. athena/agents/research/client.py +31 -80
  13. athena/agents/research/raw_client.py +155 -0
  14. athena/agents/sql/__init__.py +2 -0
  15. athena/agents/sql/client.py +31 -80
  16. athena/agents/sql/raw_client.py +155 -0
  17. athena/assets/__init__.py +4 -0
  18. athena/assets/client.py +144 -0
  19. athena/assets/raw_client.py +164 -0
  20. athena/base_client.py +25 -11
  21. athena/client.py +1 -1
  22. athena/core/__init__.py +5 -0
  23. athena/core/api_error.py +13 -5
  24. athena/core/client_wrapper.py +33 -8
  25. athena/core/force_multipart.py +16 -0
  26. athena/core/http_client.py +70 -26
  27. athena/core/http_response.py +55 -0
  28. athena/core/jsonable_encoder.py +0 -1
  29. athena/core/pydantic_utilities.py +70 -111
  30. athena/core/serialization.py +7 -3
  31. athena/errors/__init__.py +2 -0
  32. athena/errors/bad_request_error.py +4 -2
  33. athena/errors/content_too_large_error.py +4 -2
  34. athena/errors/internal_server_error.py +4 -3
  35. athena/errors/not_found_error.py +4 -2
  36. athena/errors/unauthorized_error.py +4 -3
  37. athena/errors/unprocessable_entity_error.py +4 -3
  38. athena/errors/unsupported_media_type_error.py +4 -2
  39. athena/query/__init__.py +2 -0
  40. athena/query/client.py +39 -219
  41. athena/query/raw_client.py +344 -0
  42. athena/query/types/__init__.py +2 -0
  43. athena/tools/__init__.py +2 -0
  44. athena/tools/calendar/__init__.py +2 -0
  45. athena/tools/calendar/client.py +35 -79
  46. athena/tools/calendar/raw_client.py +172 -0
  47. athena/tools/client.py +114 -876
  48. athena/tools/email/__init__.py +2 -0
  49. athena/tools/email/client.py +39 -115
  50. athena/tools/email/raw_client.py +248 -0
  51. athena/tools/raw_client.py +1328 -0
  52. athena/tools/structured_data_extractor/__init__.py +2 -0
  53. athena/tools/structured_data_extractor/client.py +42 -96
  54. athena/tools/structured_data_extractor/raw_client.py +240 -0
  55. athena/tools/tasks/__init__.py +2 -0
  56. athena/tools/tasks/client.py +31 -43
  57. athena/tools/tasks/raw_client.py +96 -0
  58. athena/tools/types/__init__.py +2 -0
  59. athena/types/__init__.py +24 -2
  60. athena/types/asset_content_request_out.py +3 -3
  61. athena/types/asset_node.py +3 -3
  62. athena/types/asset_not_found_error.py +2 -2
  63. athena/types/asset_screenshot_response_out.py +4 -4
  64. athena/types/chunk.py +3 -3
  65. athena/types/chunk_content_item.py +3 -2
  66. athena/types/chunk_result.py +3 -3
  67. athena/types/content.py +7 -0
  68. athena/types/custom_agent_response.py +2 -2
  69. athena/types/data_frame_request_out.py +3 -3
  70. athena/types/data_frame_unknown_format_error.py +2 -2
  71. athena/types/document_chunk.py +2 -2
  72. athena/types/drive_agent_response.py +2 -2
  73. athena/types/file_chunk_request_out.py +3 -3
  74. athena/types/file_too_large_error.py +2 -2
  75. athena/types/folder_response.py +10 -4
  76. athena/types/general_agent_config.py +3 -3
  77. athena/types/general_agent_config_enabled_tools_item.py +1 -2
  78. athena/types/general_agent_request.py +15 -4
  79. athena/types/general_agent_response.py +4 -3
  80. athena/types/general_agent_response_message.py +100 -0
  81. athena/types/general_agent_response_message_kwargs.py +74 -0
  82. athena/types/{tool.py → id.py} +1 -1
  83. athena/types/image_url_content.py +2 -2
  84. athena/types/input_message.py +29 -0
  85. athena/types/input_message_content_item.py +39 -0
  86. athena/types/paginated_assets_out.py +52 -0
  87. athena/types/parent_folder_error.py +2 -2
  88. athena/types/prompt_message.py +3 -3
  89. athena/types/public_asset_out.py +97 -0
  90. athena/types/research_agent_response.py +2 -2
  91. athena/types/save_asset_request_out.py +2 -2
  92. athena/types/sql_agent_response.py +2 -2
  93. athena/types/structured_data_extractor_response.py +3 -3
  94. athena/types/text_content.py +2 -2
  95. athena/types/type.py +1 -1
  96. {athena_intelligence-0.1.127.dist-info → athena_intelligence-0.1.184.dist-info}/METADATA +3 -7
  97. athena_intelligence-0.1.184.dist-info/RECORD +112 -0
  98. {athena_intelligence-0.1.127.dist-info → athena_intelligence-0.1.184.dist-info}/WHEEL +1 -1
  99. athena_intelligence-0.1.127.dist-info/RECORD +0 -89
@@ -0,0 +1,55 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from typing import Dict, Generic, TypeVar
4
+
5
+ import httpx
6
+
7
+ T = TypeVar("T")
8
+ """Generic to represent the underlying type of the data wrapped by the HTTP response."""
9
+
10
+
11
+ class BaseHttpResponse:
12
+ """Minimalist HTTP response wrapper that exposes response headers."""
13
+
14
+ _response: httpx.Response
15
+
16
+ def __init__(self, response: httpx.Response):
17
+ self._response = response
18
+
19
+ @property
20
+ def headers(self) -> Dict[str, str]:
21
+ return dict(self._response.headers)
22
+
23
+
24
+ class HttpResponse(Generic[T], BaseHttpResponse):
25
+ """HTTP response wrapper that exposes response headers and data."""
26
+
27
+ _data: T
28
+
29
+ def __init__(self, response: httpx.Response, data: T):
30
+ super().__init__(response)
31
+ self._data = data
32
+
33
+ @property
34
+ def data(self) -> T:
35
+ return self._data
36
+
37
+ def close(self) -> None:
38
+ self._response.close()
39
+
40
+
41
+ class AsyncHttpResponse(Generic[T], BaseHttpResponse):
42
+ """HTTP response wrapper that exposes response headers and data."""
43
+
44
+ _data: T
45
+
46
+ def __init__(self, response: httpx.Response, data: T):
47
+ super().__init__(response)
48
+ self._data = data
49
+
50
+ @property
51
+ def data(self) -> T:
52
+ return self._data
53
+
54
+ async def close(self) -> None:
55
+ await self._response.aclose()
@@ -17,7 +17,6 @@ from types import GeneratorType
17
17
  from typing import Any, Callable, Dict, List, Optional, Set, Union
18
18
 
19
19
  import pydantic
20
-
21
20
  from .datetime_utils import serialize_datetime
22
21
  from .pydantic_utilities import (
23
22
  IS_PYDANTIC_V2,
@@ -2,90 +2,66 @@
2
2
 
3
3
  # nopycln: file
4
4
  import datetime as dt
5
- import typing
6
5
  from collections import defaultdict
7
-
8
- import typing_extensions
6
+ from typing import Any, Callable, ClassVar, Dict, List, Mapping, Optional, Set, Tuple, Type, TypeVar, Union, cast
9
7
 
10
8
  import pydantic
11
9
 
12
- from .datetime_utils import serialize_datetime
13
- from .serialization import convert_and_respect_annotation_metadata
14
-
15
10
  IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
16
11
 
17
12
  if IS_PYDANTIC_V2:
18
- # isort will try to reformat the comments on these imports, which breaks mypy
19
- # isort: off
20
- from pydantic.v1.datetime_parse import ( # type: ignore # pyright: ignore[reportMissingImports] # Pydantic v2
21
- parse_date as parse_date,
22
- )
23
- from pydantic.v1.datetime_parse import ( # pyright: ignore[reportMissingImports] # Pydantic v2
24
- parse_datetime as parse_datetime,
25
- )
26
- from pydantic.v1.json import ( # type: ignore # pyright: ignore[reportMissingImports] # Pydantic v2
27
- ENCODERS_BY_TYPE as encoders_by_type,
28
- )
29
- from pydantic.v1.typing import ( # type: ignore # pyright: ignore[reportMissingImports] # Pydantic v2
30
- get_args as get_args,
31
- )
32
- from pydantic.v1.typing import ( # pyright: ignore[reportMissingImports] # Pydantic v2
33
- get_origin as get_origin,
34
- )
35
- from pydantic.v1.typing import ( # pyright: ignore[reportMissingImports] # Pydantic v2
36
- is_literal_type as is_literal_type,
37
- )
38
- from pydantic.v1.typing import ( # pyright: ignore[reportMissingImports] # Pydantic v2
39
- is_union as is_union,
40
- )
41
- from pydantic.v1.fields import ModelField as ModelField # type: ignore # pyright: ignore[reportMissingImports] # Pydantic v2
13
+ from pydantic.v1.datetime_parse import parse_date as parse_date
14
+ from pydantic.v1.datetime_parse import parse_datetime as parse_datetime
15
+ from pydantic.v1.fields import ModelField as ModelField
16
+ from pydantic.v1.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[attr-defined]
17
+ from pydantic.v1.typing import get_args as get_args
18
+ from pydantic.v1.typing import get_origin as get_origin
19
+ from pydantic.v1.typing import is_literal_type as is_literal_type
20
+ from pydantic.v1.typing import is_union as is_union
42
21
  else:
43
- from pydantic.datetime_parse import parse_date as parse_date # type: ignore # Pydantic v1
44
- from pydantic.datetime_parse import parse_datetime as parse_datetime # type: ignore # Pydantic v1
45
- from pydantic.fields import ModelField as ModelField # type: ignore # Pydantic v1
46
- from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore # Pydantic v1
47
- from pydantic.typing import get_args as get_args # type: ignore # Pydantic v1
48
- from pydantic.typing import get_origin as get_origin # type: ignore # Pydantic v1
49
- from pydantic.typing import is_literal_type as is_literal_type # type: ignore # Pydantic v1
50
- from pydantic.typing import is_union as is_union # type: ignore # Pydantic v1
51
-
52
- # isort: on
22
+ from pydantic.datetime_parse import parse_date as parse_date # type: ignore[no-redef]
23
+ from pydantic.datetime_parse import parse_datetime as parse_datetime # type: ignore[no-redef]
24
+ from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef]
25
+ from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[no-redef]
26
+ from pydantic.typing import get_args as get_args # type: ignore[no-redef]
27
+ from pydantic.typing import get_origin as get_origin # type: ignore[no-redef]
28
+ from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef]
29
+ from pydantic.typing import is_union as is_union # type: ignore[no-redef]
53
30
 
31
+ from .datetime_utils import serialize_datetime
32
+ from .serialization import convert_and_respect_annotation_metadata
33
+ from typing_extensions import TypeAlias
54
34
 
55
- T = typing.TypeVar("T")
56
- Model = typing.TypeVar("Model", bound=pydantic.BaseModel)
35
+ T = TypeVar("T")
36
+ Model = TypeVar("Model", bound=pydantic.BaseModel)
57
37
 
58
38
 
59
- def parse_obj_as(type_: typing.Type[T], object_: typing.Any) -> T:
39
+ def parse_obj_as(type_: Type[T], object_: Any) -> T:
60
40
  dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read")
61
41
  if IS_PYDANTIC_V2:
62
- adapter = pydantic.TypeAdapter(type_) # type: ignore # Pydantic v2
42
+ adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined]
63
43
  return adapter.validate_python(dealiased_object)
64
- else:
65
- return pydantic.parse_obj_as(type_, dealiased_object)
44
+ return pydantic.parse_obj_as(type_, dealiased_object)
66
45
 
67
46
 
68
- def to_jsonable_with_fallback(
69
- obj: typing.Any, fallback_serializer: typing.Callable[[typing.Any], typing.Any]
70
- ) -> typing.Any:
47
+ def to_jsonable_with_fallback(obj: Any, fallback_serializer: Callable[[Any], Any]) -> Any:
71
48
  if IS_PYDANTIC_V2:
72
49
  from pydantic_core import to_jsonable_python
73
50
 
74
51
  return to_jsonable_python(obj, fallback=fallback_serializer)
75
- else:
76
- return fallback_serializer(obj)
52
+ return fallback_serializer(obj)
77
53
 
78
54
 
79
55
  class UniversalBaseModel(pydantic.BaseModel):
80
56
  if IS_PYDANTIC_V2:
81
- model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
57
+ model_config: ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( # type: ignore[typeddict-unknown-key]
82
58
  # Allow fields beginning with `model_` to be used in the model
83
59
  protected_namespaces=(),
84
- ) # type: ignore # Pydantic v2
60
+ )
85
61
 
86
- @pydantic.model_serializer(mode="wrap", when_used="json") # type: ignore # Pydantic v2
87
- def serialize_model(self, handler: pydantic.SerializerFunctionWrapHandler) -> typing.Any: # type: ignore # Pydantic v2
88
- serialized = handler(self)
62
+ @pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined]
63
+ def serialize_model(self) -> Any: # type: ignore[name-defined]
64
+ serialized = self.model_dump()
89
65
  data = {k: serialize_datetime(v) if isinstance(v, dt.datetime) else v for k, v in serialized.items()}
90
66
  return data
91
67
 
@@ -96,34 +72,28 @@ class UniversalBaseModel(pydantic.BaseModel):
96
72
  json_encoders = {dt.datetime: serialize_datetime}
97
73
 
98
74
  @classmethod
99
- def model_construct(
100
- cls: typing.Type["Model"], _fields_set: typing.Optional[typing.Set[str]] = None, **values: typing.Any
101
- ) -> "Model":
75
+ def model_construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model":
102
76
  dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read")
103
77
  return cls.construct(_fields_set, **dealiased_object)
104
78
 
105
79
  @classmethod
106
- def construct(
107
- cls: typing.Type["Model"], _fields_set: typing.Optional[typing.Set[str]] = None, **values: typing.Any
108
- ) -> "Model":
80
+ def construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model":
109
81
  dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read")
110
82
  if IS_PYDANTIC_V2:
111
- return super().model_construct(_fields_set, **dealiased_object) # type: ignore # Pydantic v2
112
- else:
113
- return super().construct(_fields_set, **dealiased_object)
83
+ return super().model_construct(_fields_set, **dealiased_object) # type: ignore[misc]
84
+ return super().construct(_fields_set, **dealiased_object)
114
85
 
115
- def json(self, **kwargs: typing.Any) -> str:
116
- kwargs_with_defaults: typing.Any = {
86
+ def json(self, **kwargs: Any) -> str:
87
+ kwargs_with_defaults = {
117
88
  "by_alias": True,
118
89
  "exclude_unset": True,
119
90
  **kwargs,
120
91
  }
121
92
  if IS_PYDANTIC_V2:
122
- return super().model_dump_json(**kwargs_with_defaults) # type: ignore # Pydantic v2
123
- else:
124
- return super().json(**kwargs_with_defaults)
93
+ return super().model_dump_json(**kwargs_with_defaults) # type: ignore[misc]
94
+ return super().json(**kwargs_with_defaults)
125
95
 
126
- def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
96
+ def dict(self, **kwargs: Any) -> Dict[str, Any]:
127
97
  """
128
98
  Override the default dict method to `exclude_unset` by default. This function patches
129
99
  `exclude_unset` to work include fields within non-None default values.
@@ -134,21 +104,21 @@ class UniversalBaseModel(pydantic.BaseModel):
134
104
  # We'd ideally do the same for Pydantic V2, but it shells out to a library to serialize models
135
105
  # that we have less control over, and this is less intrusive than custom serializers for now.
136
106
  if IS_PYDANTIC_V2:
137
- kwargs_with_defaults_exclude_unset: typing.Any = {
107
+ kwargs_with_defaults_exclude_unset = {
138
108
  **kwargs,
139
109
  "by_alias": True,
140
110
  "exclude_unset": True,
141
111
  "exclude_none": False,
142
112
  }
143
- kwargs_with_defaults_exclude_none: typing.Any = {
113
+ kwargs_with_defaults_exclude_none = {
144
114
  **kwargs,
145
115
  "by_alias": True,
146
116
  "exclude_none": True,
147
117
  "exclude_unset": False,
148
118
  }
149
119
  dict_dump = deep_union_pydantic_dicts(
150
- super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore # Pydantic v2
151
- super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore # Pydantic v2
120
+ super().model_dump(**kwargs_with_defaults_exclude_unset), # type: ignore[misc]
121
+ super().model_dump(**kwargs_with_defaults_exclude_none), # type: ignore[misc]
152
122
  )
153
123
 
154
124
  else:
@@ -168,7 +138,7 @@ class UniversalBaseModel(pydantic.BaseModel):
168
138
  if default is not None:
169
139
  self.__fields_set__.add(name)
170
140
 
171
- kwargs_with_defaults_exclude_unset_include_fields: typing.Any = {
141
+ kwargs_with_defaults_exclude_unset_include_fields = {
172
142
  "by_alias": True,
173
143
  "exclude_unset": True,
174
144
  "include": _fields_set,
@@ -180,12 +150,10 @@ class UniversalBaseModel(pydantic.BaseModel):
180
150
  return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write")
181
151
 
182
152
 
183
- def _union_list_of_pydantic_dicts(
184
- source: typing.List[typing.Any], destination: typing.List[typing.Any]
185
- ) -> typing.List[typing.Any]:
186
- converted_list: typing.List[typing.Any] = []
153
+ def _union_list_of_pydantic_dicts(source: List[Any], destination: List[Any]) -> List[Any]:
154
+ converted_list: List[Any] = []
187
155
  for i, item in enumerate(source):
188
- destination_value = destination[i] # type: ignore
156
+ destination_value = destination[i]
189
157
  if isinstance(item, dict):
190
158
  converted_list.append(deep_union_pydantic_dicts(item, destination_value))
191
159
  elif isinstance(item, list):
@@ -195,9 +163,7 @@ def _union_list_of_pydantic_dicts(
195
163
  return converted_list
196
164
 
197
165
 
198
- def deep_union_pydantic_dicts(
199
- source: typing.Dict[str, typing.Any], destination: typing.Dict[str, typing.Any]
200
- ) -> typing.Dict[str, typing.Any]:
166
+ def deep_union_pydantic_dicts(source: Dict[str, Any], destination: Dict[str, Any]) -> Dict[str, Any]:
201
167
  for key, value in source.items():
202
168
  node = destination.setdefault(key, {})
203
169
  if isinstance(value, dict):
@@ -215,18 +181,16 @@ def deep_union_pydantic_dicts(
215
181
 
216
182
  if IS_PYDANTIC_V2:
217
183
 
218
- class V2RootModel(UniversalBaseModel, pydantic.RootModel): # type: ignore # Pydantic v2
184
+ class V2RootModel(UniversalBaseModel, pydantic.RootModel): # type: ignore[misc, name-defined, type-arg]
219
185
  pass
220
186
 
221
- UniversalRootModel: typing_extensions.TypeAlias = V2RootModel # type: ignore
187
+ UniversalRootModel: TypeAlias = V2RootModel # type: ignore[misc]
222
188
  else:
223
- UniversalRootModel: typing_extensions.TypeAlias = UniversalBaseModel # type: ignore
189
+ UniversalRootModel: TypeAlias = UniversalBaseModel # type: ignore[misc, no-redef]
224
190
 
225
191
 
226
- def encode_by_type(o: typing.Any) -> typing.Any:
227
- encoders_by_class_tuples: typing.Dict[typing.Callable[[typing.Any], typing.Any], typing.Tuple[typing.Any, ...]] = (
228
- defaultdict(tuple)
229
- )
192
+ def encode_by_type(o: Any) -> Any:
193
+ encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(tuple)
230
194
  for type_, encoder in encoders_by_type.items():
231
195
  encoders_by_class_tuples[encoder] += (type_,)
232
196
 
@@ -237,54 +201,49 @@ def encode_by_type(o: typing.Any) -> typing.Any:
237
201
  return encoder(o)
238
202
 
239
203
 
240
- def update_forward_refs(model: typing.Type["Model"], **localns: typing.Any) -> None:
204
+ def update_forward_refs(model: Type["Model"], **localns: Any) -> None:
241
205
  if IS_PYDANTIC_V2:
242
- model.model_rebuild(raise_errors=False) # type: ignore # Pydantic v2
206
+ model.model_rebuild(raise_errors=False) # type: ignore[attr-defined]
243
207
  else:
244
208
  model.update_forward_refs(**localns)
245
209
 
246
210
 
247
211
  # Mirrors Pydantic's internal typing
248
- AnyCallable = typing.Callable[..., typing.Any]
212
+ AnyCallable = Callable[..., Any]
249
213
 
250
214
 
251
215
  def universal_root_validator(
252
216
  pre: bool = False,
253
- ) -> typing.Callable[[AnyCallable], AnyCallable]:
217
+ ) -> Callable[[AnyCallable], AnyCallable]:
254
218
  def decorator(func: AnyCallable) -> AnyCallable:
255
219
  if IS_PYDANTIC_V2:
256
- return pydantic.model_validator(mode="before" if pre else "after")(func) # type: ignore # Pydantic v2
257
- else:
258
- return pydantic.root_validator(pre=pre)(func) # type: ignore # Pydantic v1
220
+ return cast(AnyCallable, pydantic.model_validator(mode="before" if pre else "after")(func)) # type: ignore[attr-defined]
221
+ return cast(AnyCallable, pydantic.root_validator(pre=pre)(func)) # type: ignore[call-overload]
259
222
 
260
223
  return decorator
261
224
 
262
225
 
263
- def universal_field_validator(field_name: str, pre: bool = False) -> typing.Callable[[AnyCallable], AnyCallable]:
226
+ def universal_field_validator(field_name: str, pre: bool = False) -> Callable[[AnyCallable], AnyCallable]:
264
227
  def decorator(func: AnyCallable) -> AnyCallable:
265
228
  if IS_PYDANTIC_V2:
266
- return pydantic.field_validator(field_name, mode="before" if pre else "after")(func) # type: ignore # Pydantic v2
267
- else:
268
- return pydantic.validator(field_name, pre=pre)(func) # type: ignore # Pydantic v1
229
+ return cast(AnyCallable, pydantic.field_validator(field_name, mode="before" if pre else "after")(func)) # type: ignore[attr-defined]
230
+ return cast(AnyCallable, pydantic.validator(field_name, pre=pre)(func))
269
231
 
270
232
  return decorator
271
233
 
272
234
 
273
- PydanticField = typing.Union[ModelField, pydantic.fields.FieldInfo]
235
+ PydanticField = Union[ModelField, pydantic.fields.FieldInfo]
274
236
 
275
237
 
276
- def _get_model_fields(
277
- model: typing.Type["Model"],
278
- ) -> typing.Mapping[str, PydanticField]:
238
+ def _get_model_fields(model: Type["Model"]) -> Mapping[str, PydanticField]:
279
239
  if IS_PYDANTIC_V2:
280
- return model.model_fields # type: ignore # Pydantic v2
281
- else:
282
- return model.__fields__ # type: ignore # Pydantic v1
240
+ return cast(Mapping[str, PydanticField], model.model_fields) # type: ignore[attr-defined]
241
+ return cast(Mapping[str, PydanticField], model.__fields__)
283
242
 
284
243
 
285
- def _get_field_default(field: PydanticField) -> typing.Any:
244
+ def _get_field_default(field: PydanticField) -> Any:
286
245
  try:
287
- value = field.get_default() # type: ignore # Pydantic < v1.10.15
246
+ value = field.get_default() # type: ignore[union-attr]
288
247
  except:
289
248
  value = field.default
290
249
  if IS_PYDANTIC_V2:
@@ -4,9 +4,8 @@ import collections
4
4
  import inspect
5
5
  import typing
6
6
 
7
- import typing_extensions
8
-
9
7
  import pydantic
8
+ import typing_extensions
10
9
 
11
10
 
12
11
  class FieldMetadata:
@@ -161,7 +160,12 @@ def _convert_mapping(
161
160
  direction: typing.Literal["read", "write"],
162
161
  ) -> typing.Mapping[str, object]:
163
162
  converted_object: typing.Dict[str, object] = {}
164
- annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
163
+ try:
164
+ annotations = typing_extensions.get_type_hints(expected_type, include_extras=True)
165
+ except NameError:
166
+ # The TypedDict contains a circular reference, so
167
+ # we use the __annotations__ attribute directly.
168
+ annotations = getattr(expected_type, "__annotations__", {})
165
169
  aliases_to_field_names = _get_alias_to_field_name(annotations)
166
170
  for key, value in object_.items():
167
171
  if direction == "read" and key in aliases_to_field_names:
athena/errors/__init__.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
3
5
  from .bad_request_error import BadRequestError
4
6
  from .content_too_large_error import ContentTooLargeError
5
7
  from .internal_server_error import InternalServerError
@@ -1,9 +1,11 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ import typing
4
+
3
5
  from ..core.api_error import ApiError
4
6
  from ..types.parent_folder_error import ParentFolderError
5
7
 
6
8
 
7
9
  class BadRequestError(ApiError):
8
- def __init__(self, body: ParentFolderError):
9
- super().__init__(status_code=400, body=body)
10
+ def __init__(self, body: ParentFolderError, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=400, headers=headers, body=body)
@@ -1,9 +1,11 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ import typing
4
+
3
5
  from ..core.api_error import ApiError
4
6
  from ..types.file_too_large_error import FileTooLargeError
5
7
 
6
8
 
7
9
  class ContentTooLargeError(ApiError):
8
- def __init__(self, body: FileTooLargeError):
9
- super().__init__(status_code=413, body=body)
10
+ def __init__(self, body: FileTooLargeError, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=413, headers=headers, body=body)
@@ -1,9 +1,10 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- from ..core.api_error import ApiError
4
3
  import typing
5
4
 
5
+ from ..core.api_error import ApiError
6
+
6
7
 
7
8
  class InternalServerError(ApiError):
8
- def __init__(self, body: typing.Optional[typing.Any]):
9
- super().__init__(status_code=500, body=body)
9
+ def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None):
10
+ super().__init__(status_code=500, headers=headers, body=body)
@@ -1,9 +1,11 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ import typing
4
+
3
5
  from ..core.api_error import ApiError
4
6
  from ..types.asset_not_found_error import AssetNotFoundError
5
7
 
6
8
 
7
9
  class NotFoundError(ApiError):
8
- def __init__(self, body: AssetNotFoundError):
9
- super().__init__(status_code=404, body=body)
10
+ def __init__(self, body: AssetNotFoundError, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=404, headers=headers, body=body)
@@ -1,9 +1,10 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- from ..core.api_error import ApiError
4
3
  import typing
5
4
 
5
+ from ..core.api_error import ApiError
6
+
6
7
 
7
8
  class UnauthorizedError(ApiError):
8
- def __init__(self, body: typing.Optional[typing.Any]):
9
- super().__init__(status_code=401, body=body)
9
+ def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None):
10
+ super().__init__(status_code=401, headers=headers, body=body)
@@ -1,9 +1,10 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- from ..core.api_error import ApiError
4
3
  import typing
5
4
 
5
+ from ..core.api_error import ApiError
6
+
6
7
 
7
8
  class UnprocessableEntityError(ApiError):
8
- def __init__(self, body: typing.Optional[typing.Any]):
9
- super().__init__(status_code=422, body=body)
9
+ def __init__(self, body: typing.Optional[typing.Any], headers: typing.Optional[typing.Dict[str, str]] = None):
10
+ super().__init__(status_code=422, headers=headers, body=body)
@@ -1,9 +1,11 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ import typing
4
+
3
5
  from ..core.api_error import ApiError
4
6
  from ..types.data_frame_unknown_format_error import DataFrameUnknownFormatError
5
7
 
6
8
 
7
9
  class UnsupportedMediaTypeError(ApiError):
8
- def __init__(self, body: DataFrameUnknownFormatError):
9
- super().__init__(status_code=415, body=body)
10
+ def __init__(self, body: DataFrameUnknownFormatError, headers: typing.Optional[typing.Dict[str, str]] = None):
11
+ super().__init__(status_code=415, headers=headers, body=body)
athena/query/__init__.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
3
5
  from .types import QueryExecuteRequestDatabaseAssetIds
4
6
 
5
7
  __all__ = ["QueryExecuteRequestDatabaseAssetIds"]