athena-intelligence 0.1.100__py3-none-any.whl → 0.1.102__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.
athena/__init__.py CHANGED
@@ -18,6 +18,7 @@ from .errors import (
18
18
  )
19
19
  from . import query, tools
20
20
  from .environment import AthenaEnvironment
21
+ from .query import QueryExecuteRequestDatabaseAssetIds
21
22
  from .tools import ToolsDataFrameRequestColumnsItem
22
23
  from .version import __version__
23
24
 
@@ -31,6 +32,7 @@ __all__ = [
31
32
  "FileFetchError",
32
33
  "InternalServerError",
33
34
  "NotFoundError",
35
+ "QueryExecuteRequestDatabaseAssetIds",
34
36
  "SqlUnauthorizedError",
35
37
  "ToolsDataFrameRequestColumnsItem",
36
38
  "UnauthorizedError",
athena/client.py CHANGED
@@ -1,14 +1,17 @@
1
+ import enum
1
2
  import io
2
3
  import os
3
4
  import typing
4
5
  import warnings
5
6
 
6
7
  import httpx
8
+ from typing import cast, List, Union
7
9
  from typing_extensions import TypeVar, ParamSpec
8
10
 
9
11
  from .base_client import BaseAthena, AsyncBaseAthena
10
12
  from .environment import AthenaEnvironment
11
13
  from .tools.client import AsyncToolsClient, ToolsClient
14
+ from .query.client import AsyncQueryClient, QueryClient
12
15
  from .types.data_frame_request_out import DataFrameRequestOut
13
16
 
14
17
  if typing.TYPE_CHECKING:
@@ -32,6 +35,10 @@ def _inherit_signature_and_doc(
32
35
  return decorator
33
36
 
34
37
 
38
+ class SpecialEnvironments(enum.Enum):
39
+ AUTODETECT_ENVIRONMENT = 'AUTO'
40
+
41
+
35
42
  class WrappedToolsClient(ToolsClient):
36
43
 
37
44
  def get_file(self, asset_id: str) -> io.BytesIO:
@@ -89,6 +96,25 @@ class WrappedToolsClient(ToolsClient):
89
96
  return _to_pandas_df(file_bytes, *args, **kwargs)
90
97
 
91
98
 
99
+ class WrappedQueryClient(QueryClient):
100
+
101
+ @_inherit_signature_and_doc(QueryClient.execute, {'DataFrameRequestOut': 'pd.DataFrame'})
102
+ def execute(self, *, sql_command: str, database_asset_ids: Union[str, List[str]], **kwargs) -> 'pd.DataFrame':
103
+ _check_pandas_installed()
104
+ model = super().execute(
105
+ sql_command=sql_command,
106
+ database_asset_ids=database_asset_ids,
107
+ **kwargs
108
+ )
109
+ return _read_json_frame(model)
110
+
111
+ @_inherit_signature_and_doc(QueryClient.execute_snippet, {'DataFrameRequestOut': 'pd.DataFrame'})
112
+ def execute_snippet(self, *, snippet_asset_id: str, **kwargs) -> 'pd.DataFrame':
113
+ _check_pandas_installed()
114
+ model = super().execute_snippet(snippet_asset_id=snippet_asset_id, **kwargs)
115
+ return _read_json_frame(model)
116
+
117
+
92
118
  def _add_docs_for_async_variant(obj):
93
119
  def decorator(decorated):
94
120
  doc = obj.__doc__
@@ -123,6 +149,25 @@ class WrappedAsyncToolsClient(AsyncToolsClient):
123
149
  return _to_pandas_df(file_bytes, *args, **kwargs)
124
150
 
125
151
 
152
+ class WrappedAsyncQueryClient(AsyncQueryClient):
153
+
154
+ @_inherit_signature_and_doc(AsyncQueryClient.execute, {'DataFrameRequestOut': 'pd.DataFrame'})
155
+ async def execute(self, *, sql_command: str, database_asset_ids: Union[str, List[str]], **kwargs) -> 'pd.DataFrame':
156
+ _check_pandas_installed()
157
+ model = await super().execute(
158
+ sql_command=sql_command,
159
+ database_asset_ids=database_asset_ids,
160
+ **kwargs
161
+ )
162
+ return _read_json_frame(model)
163
+
164
+ @_inherit_signature_and_doc(AsyncQueryClient.execute_snippet, {'DataFrameRequestOut': 'pd.DataFrame'})
165
+ async def execute_snippet(self, *, snippet_asset_id: str, **kwargs) -> 'pd.DataFrame':
166
+ _check_pandas_installed()
167
+ model = await super().execute_snippet(snippet_asset_id=snippet_asset_id, **kwargs)
168
+ return _read_json_frame(model)
169
+
170
+
126
171
  class Athena(BaseAthena):
127
172
  """
128
173
  Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propogate to these functions.
@@ -133,13 +178,9 @@ class Athena(BaseAthena):
133
178
  The base url to use for requests from the client.
134
179
 
135
180
  environment : AthenaEnvironment
136
- The environment to use for requests from the client. from .environment import AthenaEnvironment
137
-
138
-
139
-
140
- Defaults to AthenaEnvironment.PRODUCTION
141
-
181
+ The environment to use for requests from the client.
142
182
 
183
+ Defaults to `AthenaEnvironment.PRODUCTION` when outside of athena notebook environment.
143
184
 
144
185
  api_key: typing.Optional[str]. The API key. Required when used outside of the athena notebook environment.
145
186
  timeout : typing.Optional[float]
@@ -163,7 +204,7 @@ class Athena(BaseAthena):
163
204
  self,
164
205
  *,
165
206
  base_url: typing.Optional[str] = None,
166
- environment: AthenaEnvironment = AthenaEnvironment.PRODUCTION,
207
+ environment: Union[AthenaEnvironment, SpecialEnvironments] = SpecialEnvironments.AUTODETECT_ENVIRONMENT, # type: ignore[arg-type]
167
208
  api_key: typing.Optional[str] = None,
168
209
  timeout: typing.Optional[float] = 60,
169
210
  httpx_client: typing.Optional[httpx.Client] = None
@@ -176,14 +217,24 @@ class Athena(BaseAthena):
176
217
  "Athena() missing 1 required keyword-only argument: 'api_key'"
177
218
  ' (ATHENA_API_KEY environment variable not found)'
178
219
  )
220
+ if environment == SpecialEnvironments.AUTODETECT_ENVIRONMENT:
221
+ if 'ATHENA_API_URL' in os.environ:
222
+
223
+ class AutodetectedEnvironments:
224
+ CURRENT = os.environ['ATHENA_API_URL']
225
+
226
+ environment = cast(AthenaEnvironment, AutodetectedEnvironments.CURRENT)
227
+ else:
228
+ environment = AthenaEnvironment.PRODUCTION
179
229
  super().__init__(
180
230
  base_url=base_url,
181
- environment=environment,
231
+ environment=environment, # type: ignore[arg-type]
182
232
  api_key=api_key,
183
233
  timeout=timeout,
184
234
  httpx_client=httpx_client,
185
235
  )
186
236
  self.tools = WrappedToolsClient(client_wrapper=self._client_wrapper)
237
+ self.query = WrappedQueryClient(client_wrapper=self._client_wrapper)
187
238
 
188
239
 
189
240
  class AsyncAthena(AsyncBaseAthena):
@@ -197,13 +248,9 @@ class AsyncAthena(AsyncBaseAthena):
197
248
  The base url to use for requests from the client.
198
249
 
199
250
  environment : AthenaEnvironment
200
- The environment to use for requests from the client. from .environment import AthenaEnvironment
201
-
202
-
203
-
204
- Defaults to AthenaEnvironment.PRODUCTION
205
-
251
+ The environment to use for requests from the client.
206
252
 
253
+ Defaults to `AthenaEnvironment.PRODUCTION` when outside of athena notebook environment.
207
254
 
208
255
  api_key: typing.Optional[str]. The API key. Required when used outside of the athena notebook environment.
209
256
  timeout : typing.Optional[float]
@@ -227,7 +274,7 @@ class AsyncAthena(AsyncBaseAthena):
227
274
  self,
228
275
  *,
229
276
  base_url: typing.Optional[str] = None,
230
- environment: AthenaEnvironment = AthenaEnvironment.PRODUCTION,
277
+ environment: Union[AthenaEnvironment, SpecialEnvironments] = SpecialEnvironments.AUTODETECT_ENVIRONMENT, # type: ignore[arg-type]
231
278
  api_key: typing.Optional[str] = None,
232
279
  timeout: typing.Optional[float] = 60,
233
280
  httpx_client: typing.Optional[httpx.AsyncClient] = None
@@ -240,14 +287,24 @@ class AsyncAthena(AsyncBaseAthena):
240
287
  "AsyncAthena() missing 1 required keyword-only argument: 'api_key'"
241
288
  ' (ATHENA_API_KEY environment variable not found)'
242
289
  )
290
+ if environment == SpecialEnvironments.AUTODETECT_ENVIRONMENT:
291
+ if 'ATHENA_API_URL' in os.environ:
292
+
293
+ class AutodetectedEnvironments:
294
+ CURRENT = os.environ['ATHENA_API_URL']
295
+
296
+ environment = cast(AthenaEnvironment, AutodetectedEnvironments.CURRENT)
297
+ else:
298
+ environment = AthenaEnvironment.PRODUCTION
243
299
  super().__init__(
244
300
  base_url=base_url,
245
- environment=environment,
301
+ environment=environment, # type: ignore[arg-type]
246
302
  api_key=api_key,
247
303
  timeout=timeout,
248
304
  httpx_client=httpx_client,
249
305
  )
250
306
  self.tools = WrappedAsyncToolsClient(client_wrapper=self._client_wrapper)
307
+ self.query = WrappedAsyncQueryClient(client_wrapper=self._client_wrapper)
251
308
 
252
309
 
253
310
  def _read_json_frame(model: DataFrameRequestOut) -> 'pd.DataFrame':
@@ -17,7 +17,7 @@ class BaseClientWrapper:
17
17
  headers: typing.Dict[str, str] = {
18
18
  "X-Fern-Language": "Python",
19
19
  "X-Fern-SDK-Name": "athena-intelligence",
20
- "X-Fern-SDK-Version": "0.1.100",
20
+ "X-Fern-SDK-Version": "0.1.102",
21
21
  }
22
22
  headers["X-API-KEY"] = self.api_key
23
23
  return headers
athena/query/__init__.py CHANGED
@@ -1,2 +1,5 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ from .types import QueryExecuteRequestDatabaseAssetIds
4
+
5
+ __all__ = ["QueryExecuteRequestDatabaseAssetIds"]
athena/query/client.py CHANGED
@@ -5,6 +5,7 @@ from json.decoder import JSONDecodeError
5
5
 
6
6
  from ..core.api_error import ApiError
7
7
  from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.jsonable_encoder import jsonable_encoder
8
9
  from ..core.pydantic_utilities import pydantic_v1
9
10
  from ..core.request_options import RequestOptions
10
11
  from ..errors.internal_server_error import InternalServerError
@@ -12,6 +13,7 @@ from ..errors.unauthorized_error import UnauthorizedError
12
13
  from ..errors.unprocessable_entity_error import UnprocessableEntityError
13
14
  from ..types.data_frame_request_out import DataFrameRequestOut
14
15
  from ..types.sql_unauthorized_error import SqlUnauthorizedError
16
+ from .types.query_execute_request_database_asset_ids import QueryExecuteRequestDatabaseAssetIds
15
17
 
16
18
 
17
19
  class QueryClient:
@@ -19,6 +21,64 @@ class QueryClient:
19
21
  self._client_wrapper = client_wrapper
20
22
 
21
23
  def execute(
24
+ self,
25
+ *,
26
+ sql_command: str,
27
+ database_asset_ids: QueryExecuteRequestDatabaseAssetIds,
28
+ request_options: typing.Optional[RequestOptions] = None
29
+ ) -> DataFrameRequestOut:
30
+ """
31
+ Get the result of an SQL query over given assets.
32
+
33
+ Parameters
34
+ ----------
35
+ sql_command : str
36
+ SQL query string
37
+
38
+ database_asset_ids : QueryExecuteRequestDatabaseAssetIds
39
+ Single ID or list of asset IDs
40
+
41
+ request_options : typing.Optional[RequestOptions]
42
+ Request-specific configuration.
43
+
44
+ Returns
45
+ -------
46
+ DataFrameRequestOut
47
+ Successful Response
48
+
49
+ Examples
50
+ --------
51
+ from athena.client import Athena
52
+
53
+ client = Athena(
54
+ api_key="YOUR_API_KEY",
55
+ )
56
+ client.query.execute(
57
+ sql_command="sql_command",
58
+ database_asset_ids="database_asset_ids",
59
+ )
60
+ """
61
+ _response = self._client_wrapper.httpx_client.request(
62
+ "api/v0/query/sql/code/execute",
63
+ method="GET",
64
+ params={"sql_command": sql_command, "database_asset_ids": jsonable_encoder(database_asset_ids)},
65
+ request_options=request_options,
66
+ )
67
+ if 200 <= _response.status_code < 300:
68
+ return pydantic_v1.parse_obj_as(DataFrameRequestOut, _response.json()) # type: ignore
69
+ if _response.status_code == 401:
70
+ raise UnauthorizedError(pydantic_v1.parse_obj_as(SqlUnauthorizedError, _response.json())) # type: ignore
71
+ if _response.status_code == 422:
72
+ raise UnprocessableEntityError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
73
+ if _response.status_code == 500:
74
+ raise InternalServerError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
75
+ try:
76
+ _response_json = _response.json()
77
+ except JSONDecodeError:
78
+ raise ApiError(status_code=_response.status_code, body=_response.text)
79
+ raise ApiError(status_code=_response.status_code, body=_response_json)
80
+
81
+ def execute_snippet(
22
82
  self, *, snippet_asset_id: str, request_options: typing.Optional[RequestOptions] = None
23
83
  ) -> DataFrameRequestOut:
24
84
  """
@@ -43,7 +103,7 @@ class QueryClient:
43
103
  client = Athena(
44
104
  api_key="YOUR_API_KEY",
45
105
  )
46
- client.query.execute(
106
+ client.query.execute_snippet(
47
107
  snippet_asset_id="snippet_asset_id",
48
108
  )
49
109
  """
@@ -73,6 +133,64 @@ class AsyncQueryClient:
73
133
  self._client_wrapper = client_wrapper
74
134
 
75
135
  async def execute(
136
+ self,
137
+ *,
138
+ sql_command: str,
139
+ database_asset_ids: QueryExecuteRequestDatabaseAssetIds,
140
+ request_options: typing.Optional[RequestOptions] = None
141
+ ) -> DataFrameRequestOut:
142
+ """
143
+ Get the result of an SQL query over given assets.
144
+
145
+ Parameters
146
+ ----------
147
+ sql_command : str
148
+ SQL query string
149
+
150
+ database_asset_ids : QueryExecuteRequestDatabaseAssetIds
151
+ Single ID or list of asset IDs
152
+
153
+ request_options : typing.Optional[RequestOptions]
154
+ Request-specific configuration.
155
+
156
+ Returns
157
+ -------
158
+ DataFrameRequestOut
159
+ Successful Response
160
+
161
+ Examples
162
+ --------
163
+ from athena.client import AsyncAthena
164
+
165
+ client = AsyncAthena(
166
+ api_key="YOUR_API_KEY",
167
+ )
168
+ await client.query.execute(
169
+ sql_command="sql_command",
170
+ database_asset_ids="database_asset_ids",
171
+ )
172
+ """
173
+ _response = await self._client_wrapper.httpx_client.request(
174
+ "api/v0/query/sql/code/execute",
175
+ method="GET",
176
+ params={"sql_command": sql_command, "database_asset_ids": jsonable_encoder(database_asset_ids)},
177
+ request_options=request_options,
178
+ )
179
+ if 200 <= _response.status_code < 300:
180
+ return pydantic_v1.parse_obj_as(DataFrameRequestOut, _response.json()) # type: ignore
181
+ if _response.status_code == 401:
182
+ raise UnauthorizedError(pydantic_v1.parse_obj_as(SqlUnauthorizedError, _response.json())) # type: ignore
183
+ if _response.status_code == 422:
184
+ raise UnprocessableEntityError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
185
+ if _response.status_code == 500:
186
+ raise InternalServerError(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore
187
+ try:
188
+ _response_json = _response.json()
189
+ except JSONDecodeError:
190
+ raise ApiError(status_code=_response.status_code, body=_response.text)
191
+ raise ApiError(status_code=_response.status_code, body=_response_json)
192
+
193
+ async def execute_snippet(
76
194
  self, *, snippet_asset_id: str, request_options: typing.Optional[RequestOptions] = None
77
195
  ) -> DataFrameRequestOut:
78
196
  """
@@ -97,7 +215,7 @@ class AsyncQueryClient:
97
215
  client = AsyncAthena(
98
216
  api_key="YOUR_API_KEY",
99
217
  )
100
- await client.query.execute(
218
+ await client.query.execute_snippet(
101
219
  snippet_asset_id="snippet_asset_id",
102
220
  )
103
221
  """
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .query_execute_request_database_asset_ids import QueryExecuteRequestDatabaseAssetIds
4
+
5
+ __all__ = ["QueryExecuteRequestDatabaseAssetIds"]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ QueryExecuteRequestDatabaseAssetIds = typing.Union[str, typing.List[str]]
@@ -8,6 +8,8 @@ from ..core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1
8
8
 
9
9
 
10
10
  class SqlUnauthorizedError(pydantic_v1.BaseModel):
11
+ message: str
12
+
11
13
  def json(self, **kwargs: typing.Any) -> str:
12
14
  kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
13
15
  return super().json(**kwargs_with_defaults)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: athena-intelligence
3
- Version: 0.1.100
3
+ Version: 0.1.102
4
4
  Summary: Athena Intelligence Python Library
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -1,9 +1,9 @@
1
- athena/__init__.py,sha256=_1vtiajlFbHjHlAngtGg_C_XyqinPbX9lbn2D-zjgWc,1094
1
+ athena/__init__.py,sha256=lGo6ASUYoueZCu_oWrD7ruCsa0nLRNo9qZ_-2RV4WxY,1192
2
2
  athena/base_client.py,sha256=TlP599mOBvj7Tk8IpFe5dgrDM98GJu3lEQh_zwl4vtA,5439
3
- athena/client.py,sha256=2jxJ8mZWLa9LOH9XCxbxwLV6qVPXw53gi7GiYUTcpZg,9346
3
+ athena/client.py,sha256=z58lccIOrRq-Qp_Vs3rxqSmBtESUwhHrLlhAZd-O0ao,12352
4
4
  athena/core/__init__.py,sha256=UFXpYzcGxWQUucU1TkjOQ9mGWN3A5JohluOIWVYKU4I,973
5
5
  athena/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
6
- athena/core/client_wrapper.py,sha256=De-MIVXRtOZtBkHGrEavMifAIjhtpKVddLmCkL5sCzM,1806
6
+ athena/core/client_wrapper.py,sha256=Q4TSQemyLKOkvsjr4up2880ddYGycZ-8PHxNfijtNow,1806
7
7
  athena/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
8
8
  athena/core/file.py,sha256=sy1RUGZ3aJYuw998bZytxxo6QdgKmlnlgBaMvwEKCGg,1480
9
9
  athena/core/http_client.py,sha256=Z4NuAsJD-51yqmoME17O5sxwx5orSp1wsnd6bPyKcgA,17768
@@ -20,8 +20,10 @@ athena/errors/unauthorized_error.py,sha256=6qGByG08vA3iFHmK5ReHUK2AiGeCsK3Vf50C5
20
20
  athena/errors/unprocessable_entity_error.py,sha256=OztAzRntOJVxbZtXwoR4epahhG6chKOB5chVLUC8D9Q,257
21
21
  athena/errors/unsupported_media_type_error.py,sha256=fQ7TYQ3QYcT_YzFzO4f8_bLger7UQfZmuF22I9jYxFA,340
22
22
  athena/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- athena/query/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
24
- athena/query/client.py,sha256=q2ucGRJX5TY0sEJvYVzKKZcuDjYzhgUS-SoPQ4MIRfQ,4634
23
+ athena/query/__init__.py,sha256=EIeVs3aDVNAqLyWetSrQldzc2yUdJkf_cJXyrLdMDj0,171
24
+ athena/query/client.py,sha256=3i_yiGD7JM204TsTwY7R1CvGRs0odCh6QkYeNggHbc8,9147
25
+ athena/query/types/__init__.py,sha256=WX-Or2h5NY2sv93ojrZsHcmiFHGYdqd0yxNo-5iGHR4,206
26
+ athena/query/types/query_execute_request_database_asset_ids.py,sha256=aoVl5Xb34Q27hYGuVTnByGIxtHkL67wAwzXh7eJctew,154
25
27
  athena/tools/__init__.py,sha256=3n7oOoMebo06MAQqYRE2CX9Q0fTNnKBYE0cTlh1MPkM,165
26
28
  athena/tools/client.py,sha256=sMV_--PzUReXXILfKJeS8g9GQzYxxPDZI59wlos_rSo,10565
27
29
  athena/tools/types/__init__.py,sha256=cA-ZQm6veQAP3_vKu9KkZpISsQqgTBN_Z--FGY1c2iA,197
@@ -33,8 +35,8 @@ athena/types/data_frame_request_out_data_item_item.py,sha256=KMTJRr-1bdKDNMbUeri
33
35
  athena/types/data_frame_request_out_index_item.py,sha256=bW7oe912trpkYKodj-I_AiTXXy61yWzliekcsUZkZE0,141
34
36
  athena/types/data_frame_unknown_format_error.py,sha256=lbgAUArEgIYZt3P5Ji4Clp-xyXnKJR7-v5VzXwKu0J8,1168
35
37
  athena/types/file_fetch_error.py,sha256=iR7IXjj2C4lJFcWV3aS2gfhmT3CE-_hhBDSWFaCktHU,1162
36
- athena/types/sql_unauthorized_error.py,sha256=c3LR7lDgg66km9J0BYDCRu0hdDYaPqpnfcE3YXXKkVM,1105
38
+ athena/types/sql_unauthorized_error.py,sha256=QSQbBlOBVYYjvcmSLZbsr4twcanPeMxIl74sKUU3Hac,1123
37
39
  athena/version.py,sha256=8aYAOJtVLaJLpRp6mTiEIhnl8gXA7yE0aDtZ-3mKQ4k,87
38
- athena_intelligence-0.1.100.dist-info/METADATA,sha256=JInGWwIplFb6naHD9zUXn3e5KXrpXlsGvdFya138JCg,5274
39
- athena_intelligence-0.1.100.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
40
- athena_intelligence-0.1.100.dist-info/RECORD,,
40
+ athena_intelligence-0.1.102.dist-info/METADATA,sha256=p7kjPFWHqAU4uvLgawWmeBMiKo1NPX6eqb5RHZptpuw,5274
41
+ athena_intelligence-0.1.102.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
42
+ athena_intelligence-0.1.102.dist-info/RECORD,,