athena-intelligence 0.1.230__py3-none-any.whl → 0.1.242__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.

Potentially problematic release.


This version of athena-intelligence might be problematic. Click here for more details.

Files changed (45) hide show
  1. athena/__init__.py +217 -68
  2. athena/agents/__init__.py +33 -1
  3. athena/agents/client.py +81 -18
  4. athena/assets/client.py +12 -2
  5. athena/base_client.py +118 -18
  6. athena/client.py +14 -8
  7. athena/core/__init__.py +73 -20
  8. athena/core/client_wrapper.py +2 -2
  9. athena/core/force_multipart.py +4 -2
  10. athena/core/http_response.py +1 -1
  11. athena/core/pydantic_utilities.py +5 -2
  12. athena/errors/__init__.py +42 -7
  13. athena/query/__init__.py +28 -1
  14. athena/query/types/__init__.py +30 -1
  15. athena/tools/__init__.py +47 -3
  16. athena/tools/client.py +157 -26
  17. athena/tools/sheets/__init__.py +30 -0
  18. athena/tools/sheets/client.py +59 -94
  19. athena/tools/sheets/raw_client.py +60 -74
  20. athena/tools/sheets/types/__init__.py +36 -0
  21. athena/tools/sheets/types/update_sheet_range_request_values_item_item.py +5 -0
  22. athena/tools/types/__init__.py +28 -1
  23. athena/types/__init__.py +181 -51
  24. athena/types/aop_execute_response_out.py +2 -1
  25. athena/types/backgroundcolor.py +7 -0
  26. athena/types/border_model.py +23 -0
  27. athena/types/border_style.py +7 -0
  28. athena/types/borders_model.py +23 -0
  29. athena/types/cell_format.py +49 -0
  30. athena/types/cell_format_horizontal_alignment.py +5 -0
  31. athena/types/cell_format_vertical_alignment.py +5 -0
  32. athena/types/color.py +7 -0
  33. athena/types/conversation_asset_info.py +3 -2
  34. athena/types/conversation_message.py +42 -0
  35. athena/types/conversation_result.py +67 -0
  36. athena/types/number_format_model.py +28 -0
  37. athena/types/number_format_type.py +21 -0
  38. athena/types/sheet.py +53 -0
  39. athena/types/text_format_model.py +28 -0
  40. athena/types/textrotation.py +5 -0
  41. athena/types/theme_color.py +20 -0
  42. athena/types/wrap_strategy.py +5 -0
  43. {athena_intelligence-0.1.230.dist-info → athena_intelligence-0.1.242.dist-info}/METADATA +1 -1
  44. {athena_intelligence-0.1.230.dist-info → athena_intelligence-0.1.242.dist-info}/RECORD +45 -26
  45. {athena_intelligence-0.1.230.dist-info → athena_intelligence-0.1.242.dist-info}/WHEEL +0 -0
athena/base_client.py CHANGED
@@ -1,16 +1,20 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import typing
4
6
 
5
7
  import httpx
6
- from .agents.client import AgentsClient, AsyncAgentsClient
7
- from .aop.client import AopClient, AsyncAopClient
8
- from .assets.client import AssetsClient, AsyncAssetsClient
9
8
  from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
10
9
  from .environment import AthenaEnvironment
11
- from .query.client import AsyncQueryClient, QueryClient
12
- from .threads.client import AsyncThreadsClient, ThreadsClient
13
- from .tools.client import AsyncToolsClient, ToolsClient
10
+
11
+ if typing.TYPE_CHECKING:
12
+ from .agents.client import AgentsClient, AsyncAgentsClient
13
+ from .aop.client import AopClient, AsyncAopClient
14
+ from .assets.client import AssetsClient, AsyncAssetsClient
15
+ from .query.client import AsyncQueryClient, QueryClient
16
+ from .threads.client import AsyncThreadsClient, ThreadsClient
17
+ from .tools.client import AsyncToolsClient, ToolsClient
14
18
 
15
19
 
16
20
  class BaseAthena:
@@ -78,12 +82,60 @@ class BaseAthena:
78
82
  else httpx.Client(timeout=_defaulted_timeout),
79
83
  timeout=_defaulted_timeout,
80
84
  )
81
- self.agents = AgentsClient(client_wrapper=self._client_wrapper)
82
- self.aop = AopClient(client_wrapper=self._client_wrapper)
83
- self.assets = AssetsClient(client_wrapper=self._client_wrapper)
84
- self.query = QueryClient(client_wrapper=self._client_wrapper)
85
- self.threads = ThreadsClient(client_wrapper=self._client_wrapper)
86
- self.tools = ToolsClient(client_wrapper=self._client_wrapper)
85
+ self._agents: typing.Optional[AgentsClient] = None
86
+ self._aop: typing.Optional[AopClient] = None
87
+ self._assets: typing.Optional[AssetsClient] = None
88
+ self._query: typing.Optional[QueryClient] = None
89
+ self._threads: typing.Optional[ThreadsClient] = None
90
+ self._tools: typing.Optional[ToolsClient] = None
91
+
92
+ @property
93
+ def agents(self):
94
+ if self._agents is None:
95
+ from .agents.client import AgentsClient # noqa: E402
96
+
97
+ self._agents = AgentsClient(client_wrapper=self._client_wrapper)
98
+ return self._agents
99
+
100
+ @property
101
+ def aop(self):
102
+ if self._aop is None:
103
+ from .aop.client import AopClient # noqa: E402
104
+
105
+ self._aop = AopClient(client_wrapper=self._client_wrapper)
106
+ return self._aop
107
+
108
+ @property
109
+ def assets(self):
110
+ if self._assets is None:
111
+ from .assets.client import AssetsClient # noqa: E402
112
+
113
+ self._assets = AssetsClient(client_wrapper=self._client_wrapper)
114
+ return self._assets
115
+
116
+ @property
117
+ def query(self):
118
+ if self._query is None:
119
+ from .query.client import QueryClient # noqa: E402
120
+
121
+ self._query = QueryClient(client_wrapper=self._client_wrapper)
122
+ return self._query
123
+
124
+ @property
125
+ def threads(self):
126
+ if self._threads is None:
127
+ from .threads.client import ThreadsClient # noqa: E402
128
+
129
+ self._threads = ThreadsClient(client_wrapper=self._client_wrapper)
130
+ return self._threads
131
+
132
+ @property
133
+ def tools(self):
134
+ if self._tools is None:
135
+ from .tools.client import ToolsClient # noqa: E402
136
+
137
+ self._tools = ToolsClient(client_wrapper=self._client_wrapper)
138
+ return self._tools
87
139
 
88
140
 
89
141
  class AsyncBaseAthena:
@@ -151,12 +203,60 @@ class AsyncBaseAthena:
151
203
  else httpx.AsyncClient(timeout=_defaulted_timeout),
152
204
  timeout=_defaulted_timeout,
153
205
  )
154
- self.agents = AsyncAgentsClient(client_wrapper=self._client_wrapper)
155
- self.aop = AsyncAopClient(client_wrapper=self._client_wrapper)
156
- self.assets = AsyncAssetsClient(client_wrapper=self._client_wrapper)
157
- self.query = AsyncQueryClient(client_wrapper=self._client_wrapper)
158
- self.threads = AsyncThreadsClient(client_wrapper=self._client_wrapper)
159
- self.tools = AsyncToolsClient(client_wrapper=self._client_wrapper)
206
+ self._agents: typing.Optional[AsyncAgentsClient] = None
207
+ self._aop: typing.Optional[AsyncAopClient] = None
208
+ self._assets: typing.Optional[AsyncAssetsClient] = None
209
+ self._query: typing.Optional[AsyncQueryClient] = None
210
+ self._threads: typing.Optional[AsyncThreadsClient] = None
211
+ self._tools: typing.Optional[AsyncToolsClient] = None
212
+
213
+ @property
214
+ def agents(self):
215
+ if self._agents is None:
216
+ from .agents.client import AsyncAgentsClient # noqa: E402
217
+
218
+ self._agents = AsyncAgentsClient(client_wrapper=self._client_wrapper)
219
+ return self._agents
220
+
221
+ @property
222
+ def aop(self):
223
+ if self._aop is None:
224
+ from .aop.client import AsyncAopClient # noqa: E402
225
+
226
+ self._aop = AsyncAopClient(client_wrapper=self._client_wrapper)
227
+ return self._aop
228
+
229
+ @property
230
+ def assets(self):
231
+ if self._assets is None:
232
+ from .assets.client import AsyncAssetsClient # noqa: E402
233
+
234
+ self._assets = AsyncAssetsClient(client_wrapper=self._client_wrapper)
235
+ return self._assets
236
+
237
+ @property
238
+ def query(self):
239
+ if self._query is None:
240
+ from .query.client import AsyncQueryClient # noqa: E402
241
+
242
+ self._query = AsyncQueryClient(client_wrapper=self._client_wrapper)
243
+ return self._query
244
+
245
+ @property
246
+ def threads(self):
247
+ if self._threads is None:
248
+ from .threads.client import AsyncThreadsClient # noqa: E402
249
+
250
+ self._threads = AsyncThreadsClient(client_wrapper=self._client_wrapper)
251
+ return self._threads
252
+
253
+ @property
254
+ def tools(self):
255
+ if self._tools is None:
256
+ from .tools.client import AsyncToolsClient # noqa: E402
257
+
258
+ self._tools = AsyncToolsClient(client_wrapper=self._client_wrapper)
259
+ return self._tools
160
260
 
161
261
 
162
262
  def _get_base_url(*, base_url: typing.Optional[str] = None, environment: AthenaEnvironment) -> str:
athena/client.py CHANGED
@@ -449,8 +449,6 @@ class Athena(BaseAthena):
449
449
  )
450
450
  """
451
451
 
452
- tools: WrappedToolsClient
453
-
454
452
  def __init__(
455
453
  self,
456
454
  *,
@@ -484,12 +482,17 @@ class Athena(BaseAthena):
484
482
  timeout=timeout,
485
483
  httpx_client=httpx_client,
486
484
  )
487
- self.tools = WrappedToolsClient(client_wrapper=self._client_wrapper)
488
- self.query = WrappedQueryClient(client_wrapper=self._client_wrapper)
485
+ self._tools: typing.Optional[WrappedToolsClient] = None
489
486
  self.llm = AthenaModel(
490
487
  base_url=base_url or environment.value, api_key=api_key, timeout=timeout
491
488
  )
492
489
 
490
+ @property
491
+ def tools(self) -> WrappedToolsClient:
492
+ if self._tools is None:
493
+ self._tools = WrappedToolsClient(client_wrapper=self._client_wrapper)
494
+ return self._tools
495
+
493
496
 
494
497
  class AsyncAthena(AsyncBaseAthena):
495
498
  """
@@ -522,8 +525,6 @@ class AsyncAthena(AsyncBaseAthena):
522
525
  )
523
526
  """
524
527
 
525
- tools: WrappedAsyncToolsClient
526
-
527
528
  def __init__(
528
529
  self,
529
530
  *,
@@ -550,6 +551,7 @@ class AsyncAthena(AsyncBaseAthena):
550
551
  environment = cast(AthenaEnvironment, AutodetectedEnvironments.CURRENT)
551
552
  else:
552
553
  environment = AthenaEnvironment.PRODUCTION
554
+ self._tools: typing.Optional[WrappedAsyncToolsClient] = None
553
555
  super().__init__(
554
556
  base_url=base_url,
555
557
  environment=environment, # type: ignore[arg-type]
@@ -557,8 +559,12 @@ class AsyncAthena(AsyncBaseAthena):
557
559
  timeout=timeout,
558
560
  httpx_client=httpx_client,
559
561
  )
560
- self.tools = WrappedAsyncToolsClient(client_wrapper=self._client_wrapper)
561
- self.query = WrappedAsyncQueryClient(client_wrapper=self._client_wrapper)
562
+
563
+ @property
564
+ def tools(self) -> WrappedAsyncToolsClient:
565
+ if self._tools is None:
566
+ self._tools = WrappedAsyncToolsClient(client_wrapper=self._client_wrapper)
567
+ return self._tools
562
568
 
563
569
 
564
570
  def _read_json_frame(model: DataFrameRequestOut) -> "pd.DataFrame":
athena/core/__init__.py CHANGED
@@ -2,26 +2,79 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .api_error import ApiError
6
- from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
7
- from .datetime_utils import serialize_datetime
8
- from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
9
- from .http_client import AsyncHttpClient, HttpClient
10
- from .http_response import AsyncHttpResponse, HttpResponse
11
- from .jsonable_encoder import jsonable_encoder
12
- from .pydantic_utilities import (
13
- IS_PYDANTIC_V2,
14
- UniversalBaseModel,
15
- UniversalRootModel,
16
- parse_obj_as,
17
- universal_field_validator,
18
- universal_root_validator,
19
- update_forward_refs,
20
- )
21
- from .query_encoder import encode_query
22
- from .remove_none_from_dict import remove_none_from_dict
23
- from .request_options import RequestOptions
24
- 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 .file import File, convert_file_dict_to_httpx_tuples, with_content_type
13
+ from .http_client import AsyncHttpClient, HttpClient
14
+ from .http_response import AsyncHttpResponse, HttpResponse
15
+ from .jsonable_encoder import jsonable_encoder
16
+ from .pydantic_utilities import (
17
+ IS_PYDANTIC_V2,
18
+ UniversalBaseModel,
19
+ UniversalRootModel,
20
+ parse_obj_as,
21
+ universal_field_validator,
22
+ universal_root_validator,
23
+ update_forward_refs,
24
+ )
25
+ from .query_encoder import encode_query
26
+ from .remove_none_from_dict import remove_none_from_dict
27
+ from .request_options import RequestOptions
28
+ from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
29
+ _dynamic_imports: typing.Dict[str, str] = {
30
+ "ApiError": ".api_error",
31
+ "AsyncClientWrapper": ".client_wrapper",
32
+ "AsyncHttpClient": ".http_client",
33
+ "AsyncHttpResponse": ".http_response",
34
+ "BaseClientWrapper": ".client_wrapper",
35
+ "FieldMetadata": ".serialization",
36
+ "File": ".file",
37
+ "HttpClient": ".http_client",
38
+ "HttpResponse": ".http_response",
39
+ "IS_PYDANTIC_V2": ".pydantic_utilities",
40
+ "RequestOptions": ".request_options",
41
+ "SyncClientWrapper": ".client_wrapper",
42
+ "UniversalBaseModel": ".pydantic_utilities",
43
+ "UniversalRootModel": ".pydantic_utilities",
44
+ "convert_and_respect_annotation_metadata": ".serialization",
45
+ "convert_file_dict_to_httpx_tuples": ".file",
46
+ "encode_query": ".query_encoder",
47
+ "jsonable_encoder": ".jsonable_encoder",
48
+ "parse_obj_as": ".pydantic_utilities",
49
+ "remove_none_from_dict": ".remove_none_from_dict",
50
+ "serialize_datetime": ".datetime_utils",
51
+ "universal_field_validator": ".pydantic_utilities",
52
+ "universal_root_validator": ".pydantic_utilities",
53
+ "update_forward_refs": ".pydantic_utilities",
54
+ "with_content_type": ".file",
55
+ }
56
+
57
+
58
+ def __getattr__(attr_name: str) -> typing.Any:
59
+ module_name = _dynamic_imports.get(attr_name)
60
+ if module_name is None:
61
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
62
+ try:
63
+ module = import_module(module_name, __package__)
64
+ if module_name == f".{attr_name}":
65
+ return module
66
+ else:
67
+ return getattr(module, attr_name)
68
+ except ImportError as e:
69
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
70
+ except AttributeError as e:
71
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
72
+
73
+
74
+ def __dir__():
75
+ lazy_attrs = list(_dynamic_imports.keys())
76
+ return sorted(lazy_attrs)
77
+
25
78
 
26
79
  __all__ = [
27
80
  "ApiError",
@@ -22,10 +22,10 @@ class BaseClientWrapper:
22
22
 
23
23
  def get_headers(self) -> typing.Dict[str, str]:
24
24
  headers: typing.Dict[str, str] = {
25
- "User-Agent": "athena-intelligence/0.1.230",
25
+ "User-Agent": "athena-intelligence/0.1.242",
26
26
  "X-Fern-Language": "Python",
27
27
  "X-Fern-SDK-Name": "athena-intelligence",
28
- "X-Fern-SDK-Version": "0.1.230",
28
+ "X-Fern-SDK-Version": "0.1.242",
29
29
  **(self.get_custom_headers() or {}),
30
30
  }
31
31
  headers["X-API-KEY"] = self.api_key
@@ -1,7 +1,9 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ from typing import Any, Dict
3
4
 
4
- class ForceMultipartDict(dict):
5
+
6
+ class ForceMultipartDict(Dict[str, Any]):
5
7
  """
6
8
  A dictionary subclass that always evaluates to True in boolean contexts.
7
9
 
@@ -9,7 +11,7 @@ class ForceMultipartDict(dict):
9
11
  the dictionary is empty, which would normally evaluate to False.
10
12
  """
11
13
 
12
- def __bool__(self):
14
+ def __bool__(self) -> bool:
13
15
  return True
14
16
 
15
17
 
@@ -4,8 +4,8 @@ from typing import Dict, Generic, TypeVar
4
4
 
5
5
  import httpx
6
6
 
7
+ # Generic to represent the underlying type of the data wrapped by the HTTP response.
7
8
  T = TypeVar("T")
8
- """Generic to represent the underlying type of the data wrapped by the HTTP response."""
9
9
 
10
10
 
11
11
  class BaseHttpResponse:
@@ -61,7 +61,7 @@ class UniversalBaseModel(pydantic.BaseModel):
61
61
 
62
62
  @pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined]
63
63
  def serialize_model(self) -> Any: # type: ignore[name-defined]
64
- serialized = self.model_dump()
64
+ serialized = self.dict() # type: ignore[attr-defined]
65
65
  data = {k: serialize_datetime(v) if isinstance(v, dt.datetime) else v for k, v in serialized.items()}
66
66
  return data
67
67
 
@@ -147,7 +147,10 @@ class UniversalBaseModel(pydantic.BaseModel):
147
147
 
148
148
  dict_dump = super().dict(**kwargs_with_defaults_exclude_unset_include_fields)
149
149
 
150
- return convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write")
150
+ return cast(
151
+ Dict[str, Any],
152
+ convert_and_respect_annotation_metadata(object_=dict_dump, annotation=self.__class__, direction="write"),
153
+ )
151
154
 
152
155
 
153
156
  def _union_list_of_pydantic_dicts(source: List[Any], destination: List[Any]) -> List[Any]:
athena/errors/__init__.py CHANGED
@@ -2,13 +2,48 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .bad_request_error import BadRequestError
6
- from .content_too_large_error import ContentTooLargeError
7
- from .internal_server_error import InternalServerError
8
- from .not_found_error import NotFoundError
9
- from .unauthorized_error import UnauthorizedError
10
- from .unprocessable_entity_error import UnprocessableEntityError
11
- from .unsupported_media_type_error import UnsupportedMediaTypeError
5
+ import typing
6
+ from importlib import import_module
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from .bad_request_error import BadRequestError
10
+ from .content_too_large_error import ContentTooLargeError
11
+ from .internal_server_error import InternalServerError
12
+ from .not_found_error import NotFoundError
13
+ from .unauthorized_error import UnauthorizedError
14
+ from .unprocessable_entity_error import UnprocessableEntityError
15
+ from .unsupported_media_type_error import UnsupportedMediaTypeError
16
+ _dynamic_imports: typing.Dict[str, str] = {
17
+ "BadRequestError": ".bad_request_error",
18
+ "ContentTooLargeError": ".content_too_large_error",
19
+ "InternalServerError": ".internal_server_error",
20
+ "NotFoundError": ".not_found_error",
21
+ "UnauthorizedError": ".unauthorized_error",
22
+ "UnprocessableEntityError": ".unprocessable_entity_error",
23
+ "UnsupportedMediaTypeError": ".unsupported_media_type_error",
24
+ }
25
+
26
+
27
+ def __getattr__(attr_name: str) -> typing.Any:
28
+ module_name = _dynamic_imports.get(attr_name)
29
+ if module_name is None:
30
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
31
+ try:
32
+ module = import_module(module_name, __package__)
33
+ if module_name == f".{attr_name}":
34
+ return module
35
+ else:
36
+ return getattr(module, attr_name)
37
+ except ImportError as e:
38
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
39
+ except AttributeError as e:
40
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
41
+
42
+
43
+ def __dir__():
44
+ lazy_attrs = list(_dynamic_imports.keys())
45
+ return sorted(lazy_attrs)
46
+
12
47
 
13
48
  __all__ = [
14
49
  "BadRequestError",
athena/query/__init__.py CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .types import QueryExecuteRequestDatabaseAssetIds
5
+ import typing
6
+ from importlib import import_module
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from .types import QueryExecuteRequestDatabaseAssetIds
10
+ _dynamic_imports: typing.Dict[str, str] = {"QueryExecuteRequestDatabaseAssetIds": ".types"}
11
+
12
+
13
+ def __getattr__(attr_name: str) -> typing.Any:
14
+ module_name = _dynamic_imports.get(attr_name)
15
+ if module_name is None:
16
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
17
+ try:
18
+ module = import_module(module_name, __package__)
19
+ if module_name == f".{attr_name}":
20
+ return module
21
+ else:
22
+ return getattr(module, attr_name)
23
+ except ImportError as e:
24
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
25
+ except AttributeError as e:
26
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
27
+
28
+
29
+ def __dir__():
30
+ lazy_attrs = list(_dynamic_imports.keys())
31
+ return sorted(lazy_attrs)
32
+
6
33
 
7
34
  __all__ = ["QueryExecuteRequestDatabaseAssetIds"]
@@ -2,6 +2,35 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .query_execute_request_database_asset_ids import QueryExecuteRequestDatabaseAssetIds
5
+ import typing
6
+ from importlib import import_module
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from .query_execute_request_database_asset_ids import QueryExecuteRequestDatabaseAssetIds
10
+ _dynamic_imports: typing.Dict[str, str] = {
11
+ "QueryExecuteRequestDatabaseAssetIds": ".query_execute_request_database_asset_ids"
12
+ }
13
+
14
+
15
+ def __getattr__(attr_name: str) -> typing.Any:
16
+ module_name = _dynamic_imports.get(attr_name)
17
+ if module_name is None:
18
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
19
+ try:
20
+ module = import_module(module_name, __package__)
21
+ if module_name == f".{attr_name}":
22
+ return module
23
+ else:
24
+ return getattr(module, attr_name)
25
+ except ImportError as e:
26
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
27
+ except AttributeError as e:
28
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
29
+
30
+
31
+ def __dir__():
32
+ lazy_attrs = list(_dynamic_imports.keys())
33
+ return sorted(lazy_attrs)
34
+
6
35
 
7
36
  __all__ = ["QueryExecuteRequestDatabaseAssetIds"]
athena/tools/__init__.py CHANGED
@@ -2,7 +2,51 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .types import ToolsDataFrameRequestColumnsItem
6
- from . import calendar, email, sheets, structured_data_extractor, tasks
5
+ import typing
6
+ from importlib import import_module
7
7
 
8
- __all__ = ["ToolsDataFrameRequestColumnsItem", "calendar", "email", "sheets", "structured_data_extractor", "tasks"]
8
+ if typing.TYPE_CHECKING:
9
+ from .types import ToolsDataFrameRequestColumnsItem
10
+ from . import calendar, email, sheets, structured_data_extractor, tasks
11
+ from .sheets import UpdateSheetRangeRequestValuesItemItem
12
+ _dynamic_imports: typing.Dict[str, str] = {
13
+ "ToolsDataFrameRequestColumnsItem": ".types",
14
+ "UpdateSheetRangeRequestValuesItemItem": ".sheets",
15
+ "calendar": ".calendar",
16
+ "email": ".email",
17
+ "sheets": ".sheets",
18
+ "structured_data_extractor": ".structured_data_extractor",
19
+ "tasks": ".tasks",
20
+ }
21
+
22
+
23
+ def __getattr__(attr_name: str) -> typing.Any:
24
+ module_name = _dynamic_imports.get(attr_name)
25
+ if module_name is None:
26
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
27
+ try:
28
+ module = import_module(module_name, __package__)
29
+ if module_name == f".{attr_name}":
30
+ return module
31
+ else:
32
+ return getattr(module, attr_name)
33
+ except ImportError as e:
34
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
35
+ except AttributeError as e:
36
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
37
+
38
+
39
+ def __dir__():
40
+ lazy_attrs = list(_dynamic_imports.keys())
41
+ return sorted(lazy_attrs)
42
+
43
+
44
+ __all__ = [
45
+ "ToolsDataFrameRequestColumnsItem",
46
+ "UpdateSheetRangeRequestValuesItemItem",
47
+ "calendar",
48
+ "email",
49
+ "sheets",
50
+ "structured_data_extractor",
51
+ "tasks",
52
+ ]