athena-intelligence 0.1.1__tar.gz

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.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.1
2
+ Name: athena-intelligence
3
+ Version: 0.1.1
4
+ Summary:
5
+ Requires-Python: >=3.8,<4.0
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.8
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Requires-Dist: httpx (>=0.21.2)
12
+ Requires-Dist: pydantic (>=1.9.2)
13
+ Requires-Dist: typing_extensions (>=4.0.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Athena Intelligence Python Library
17
+
18
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-SDK%20generated%20by%20Fern-brightgreen)](https://github.com/fern-api/fern)
19
+ [![pypi](https://img.shields.io/pypi/v/athena-intel.svg)](https://pypi.python.org/pypi/athena-intel)
20
+
21
+ The Athena Intelligence Python Library provides convenient access to the Athena Intelligence API from
22
+ applications written in Python.
23
+
24
+ The library includes type definitions for all
25
+ request and response fields, and offers both synchronous and asynchronous clients powered by httpx.
26
+
27
+ ## Installation
28
+
29
+ Add this dependency to your project's build file:
30
+
31
+ ```bash
32
+ pip install athena-intel
33
+ # or
34
+ poetry add athena-intel
35
+ ```
36
+
37
+ ## Usage
38
+ Simply import `Athena` and start making calls to our API.
39
+
40
+ ```python
41
+ from athena.client import Athena
42
+
43
+ client = Athena(
44
+ api_key="YOUR_API_KEY" # Defaults to ATHENA_API_KEY
45
+ )
46
+ message = client.messages.get("message_id")
47
+ ```
48
+
49
+ ## Async Client
50
+ The SDK also exports an async client so that you can make non-blocking
51
+ calls to our API.
52
+
53
+ ```python
54
+ from athena.client import AsyncAthena
55
+
56
+ client = AsyncAthena(
57
+ api_key="YOUR_API_KEY" # Defaults to ATHENA_API_KEY
58
+ )
59
+
60
+ async def main() -> None:
61
+ message = client.messages.get("message_id")
62
+ print("Received message", message)
63
+
64
+ asyncio.run(main())
65
+ ```
66
+
67
+ ## Athena Module
68
+ All of the models are nested within the Athena module. Let IntelliSense
69
+ guide you!
70
+
71
+ ## Exception Handling
72
+ All errors thrown by the SDK will be subclasses of [`ApiError`](./src/athena/core/api_error.py).
73
+
74
+ ```python
75
+ import athena
76
+
77
+ try:
78
+ client.messages.get(...)
79
+ except athena.core.ApiError as e: # Handle all errors
80
+ print(e.status_code)
81
+ print(e.body)
82
+ ```
83
+
84
+ ## Advanced
85
+
86
+ ### Timeouts
87
+ By default, requests time out after 60 seconds. You can configure this with a
88
+ timeout option at the client or request level.
89
+
90
+ ```python
91
+ from athena.client import Athena
92
+
93
+ client = Athena(
94
+ # All timeouts are 20 seconds
95
+ timeout=20.0,
96
+ )
97
+
98
+ # Override timeout for a specific method
99
+ client.messages.get(..., {
100
+ timeout_in_seconds=20
101
+ })
102
+ ```
103
+
104
+ ### Custom HTTP client
105
+ You can override the httpx client to customize it for your use-case. Some common use-cases
106
+ include support for proxies and transports.
107
+
108
+ ```python
109
+ import httpx
110
+
111
+ from athena.client import Athena
112
+
113
+ client = Athena(
114
+ http_client=httpx.Client(
115
+ proxies="http://my.test.proxy.example.com",
116
+ transport=httpx.HTTPTransport(local_address="0.0.0.0"),
117
+ ),
118
+ )
119
+ ```
120
+
121
+ ## Beta Status
122
+
123
+ This SDK is in **Preview**, and there may be breaking changes between versions without a major
124
+ version update.
125
+
126
+ To ensure a reproducible environment (and minimize risk of breaking changes), we recommend pinning a specific package version.
127
+
128
+ ## Contributing
129
+
130
+ While we value open-source contributions to this SDK, this library is generated programmatically.
131
+ Additions made directly to this library would have to be moved over to our generation code,
132
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
133
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
134
+ an issue first to discuss with us!
135
+
136
+ On the other hand, contributions to the README are always very welcome!
137
+
@@ -0,0 +1,121 @@
1
+ # Athena Intelligence Python Library
2
+
3
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-SDK%20generated%20by%20Fern-brightgreen)](https://github.com/fern-api/fern)
4
+ [![pypi](https://img.shields.io/pypi/v/athena-intel.svg)](https://pypi.python.org/pypi/athena-intel)
5
+
6
+ The Athena Intelligence Python Library provides convenient access to the Athena Intelligence API from
7
+ applications written in Python.
8
+
9
+ The library includes type definitions for all
10
+ request and response fields, and offers both synchronous and asynchronous clients powered by httpx.
11
+
12
+ ## Installation
13
+
14
+ Add this dependency to your project's build file:
15
+
16
+ ```bash
17
+ pip install athena-intel
18
+ # or
19
+ poetry add athena-intel
20
+ ```
21
+
22
+ ## Usage
23
+ Simply import `Athena` and start making calls to our API.
24
+
25
+ ```python
26
+ from athena.client import Athena
27
+
28
+ client = Athena(
29
+ api_key="YOUR_API_KEY" # Defaults to ATHENA_API_KEY
30
+ )
31
+ message = client.messages.get("message_id")
32
+ ```
33
+
34
+ ## Async Client
35
+ The SDK also exports an async client so that you can make non-blocking
36
+ calls to our API.
37
+
38
+ ```python
39
+ from athena.client import AsyncAthena
40
+
41
+ client = AsyncAthena(
42
+ api_key="YOUR_API_KEY" # Defaults to ATHENA_API_KEY
43
+ )
44
+
45
+ async def main() -> None:
46
+ message = client.messages.get("message_id")
47
+ print("Received message", message)
48
+
49
+ asyncio.run(main())
50
+ ```
51
+
52
+ ## Athena Module
53
+ All of the models are nested within the Athena module. Let IntelliSense
54
+ guide you!
55
+
56
+ ## Exception Handling
57
+ All errors thrown by the SDK will be subclasses of [`ApiError`](./src/athena/core/api_error.py).
58
+
59
+ ```python
60
+ import athena
61
+
62
+ try:
63
+ client.messages.get(...)
64
+ except athena.core.ApiError as e: # Handle all errors
65
+ print(e.status_code)
66
+ print(e.body)
67
+ ```
68
+
69
+ ## Advanced
70
+
71
+ ### Timeouts
72
+ By default, requests time out after 60 seconds. You can configure this with a
73
+ timeout option at the client or request level.
74
+
75
+ ```python
76
+ from athena.client import Athena
77
+
78
+ client = Athena(
79
+ # All timeouts are 20 seconds
80
+ timeout=20.0,
81
+ )
82
+
83
+ # Override timeout for a specific method
84
+ client.messages.get(..., {
85
+ timeout_in_seconds=20
86
+ })
87
+ ```
88
+
89
+ ### Custom HTTP client
90
+ You can override the httpx client to customize it for your use-case. Some common use-cases
91
+ include support for proxies and transports.
92
+
93
+ ```python
94
+ import httpx
95
+
96
+ from athena.client import Athena
97
+
98
+ client = Athena(
99
+ http_client=httpx.Client(
100
+ proxies="http://my.test.proxy.example.com",
101
+ transport=httpx.HTTPTransport(local_address="0.0.0.0"),
102
+ ),
103
+ )
104
+ ```
105
+
106
+ ## Beta Status
107
+
108
+ This SDK is in **Preview**, and there may be breaking changes between versions without a major
109
+ version update.
110
+
111
+ To ensure a reproducible environment (and minimize risk of breaking changes), we recommend pinning a specific package version.
112
+
113
+ ## Contributing
114
+
115
+ While we value open-source contributions to this SDK, this library is generated programmatically.
116
+ Additions made directly to this library would have to be moved over to our generation code,
117
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
118
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
119
+ an issue first to discuss with us!
120
+
121
+ On the other hand, contributions to the README are always very welcome!
@@ -0,0 +1,23 @@
1
+ [tool.poetry]
2
+ name = "athena-intelligence"
3
+ version = "0.1.1"
4
+ description = ""
5
+ readme = "README.md"
6
+ authors = []
7
+ packages = [
8
+ { include = "athena", from = "src"}
9
+ ]
10
+
11
+ [tool.poetry.dependencies]
12
+ python = "^3.8"
13
+ httpx = ">=0.21.2"
14
+ pydantic = ">= 1.9.2"
15
+ typing_extensions = ">= 4.0.0"
16
+
17
+ [tool.poetry.dev-dependencies]
18
+ mypy = "^1.8.0"
19
+ pytest = "^7.4.0"
20
+
21
+ [build-system]
22
+ requires = ["poetry-core"]
23
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .resources import Message, message
4
+ from .environment import AthenaEnvironment
5
+
6
+ __all__ = ["AthenaEnvironment", "Message", "message"]
@@ -0,0 +1,110 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import os
4
+ import typing
5
+
6
+ import httpx
7
+
8
+ from .core.api_error import ApiError
9
+ from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
10
+ from .environment import AthenaEnvironment
11
+ from .resources.message.client import AsyncMessageClient, MessageClient
12
+
13
+
14
+ class Athena:
15
+ """
16
+ 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.
17
+
18
+ Parameters:
19
+ - base_url: typing.Optional[str]. The base url to use for requests from the client.
20
+
21
+ - environment: AthenaEnvironment. The environment to use for requests from the client. from .environment import AthenaEnvironment
22
+
23
+ Defaults to AthenaEnvironment.PRODUCTION
24
+
25
+ - api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
26
+
27
+ - timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds.
28
+
29
+ - httpx_client: typing.Optional[httpx.Client]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
30
+ ---
31
+ from athena.client import Athena
32
+
33
+ client = Athena(
34
+ api_key="YOUR_API_KEY",
35
+ )
36
+ """
37
+
38
+ def __init__(
39
+ self,
40
+ *,
41
+ base_url: typing.Optional[str] = None,
42
+ environment: AthenaEnvironment = AthenaEnvironment.PRODUCTION,
43
+ api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("ATHENA_API_KEY"),
44
+ timeout: typing.Optional[float] = 60,
45
+ httpx_client: typing.Optional[httpx.Client] = None
46
+ ):
47
+ if api_key is None:
48
+ raise ApiError(
49
+ body="The client must be instantiated be either passing in api_key or setting ATHENA_API_KEY"
50
+ )
51
+ self._client_wrapper = SyncClientWrapper(
52
+ base_url=_get_base_url(base_url=base_url, environment=environment),
53
+ api_key=api_key,
54
+ httpx_client=httpx.Client(timeout=timeout) if httpx_client is None else httpx_client,
55
+ )
56
+ self.message = MessageClient(client_wrapper=self._client_wrapper)
57
+
58
+
59
+ class AsyncAthena:
60
+ """
61
+ 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.
62
+
63
+ Parameters:
64
+ - base_url: typing.Optional[str]. The base url to use for requests from the client.
65
+
66
+ - environment: AthenaEnvironment. The environment to use for requests from the client. from .environment import AthenaEnvironment
67
+
68
+ Defaults to AthenaEnvironment.PRODUCTION
69
+
70
+ - api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]].
71
+
72
+ - timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds.
73
+
74
+ - httpx_client: typing.Optional[httpx.AsyncClient]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.
75
+ ---
76
+ from athena.client import AsyncAthena
77
+
78
+ client = AsyncAthena(
79
+ api_key="YOUR_API_KEY",
80
+ )
81
+ """
82
+
83
+ def __init__(
84
+ self,
85
+ *,
86
+ base_url: typing.Optional[str] = None,
87
+ environment: AthenaEnvironment = AthenaEnvironment.PRODUCTION,
88
+ api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("ATHENA_API_KEY"),
89
+ timeout: typing.Optional[float] = 60,
90
+ httpx_client: typing.Optional[httpx.AsyncClient] = None
91
+ ):
92
+ if api_key is None:
93
+ raise ApiError(
94
+ body="The client must be instantiated be either passing in api_key or setting ATHENA_API_KEY"
95
+ )
96
+ self._client_wrapper = AsyncClientWrapper(
97
+ base_url=_get_base_url(base_url=base_url, environment=environment),
98
+ api_key=api_key,
99
+ httpx_client=httpx.AsyncClient(timeout=timeout) if httpx_client is None else httpx_client,
100
+ )
101
+ self.message = AsyncMessageClient(client_wrapper=self._client_wrapper)
102
+
103
+
104
+ def _get_base_url(*, base_url: typing.Optional[str] = None, environment: AthenaEnvironment) -> str:
105
+ if base_url is not None:
106
+ return base_url
107
+ elif environment is not None:
108
+ return environment.value
109
+ else:
110
+ raise Exception("Please pass in either base_url or environment to construct the client")
@@ -0,0 +1,22 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .api_error import ApiError
4
+ from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
5
+ from .datetime_utils import serialize_datetime
6
+ from .file import File, convert_file_dict_to_httpx_tuples
7
+ from .jsonable_encoder import jsonable_encoder
8
+ from .remove_none_from_dict import remove_none_from_dict
9
+ from .request_options import RequestOptions
10
+
11
+ __all__ = [
12
+ "ApiError",
13
+ "AsyncClientWrapper",
14
+ "BaseClientWrapper",
15
+ "File",
16
+ "RequestOptions",
17
+ "SyncClientWrapper",
18
+ "convert_file_dict_to_httpx_tuples",
19
+ "jsonable_encoder",
20
+ "remove_none_from_dict",
21
+ "serialize_datetime",
22
+ ]
@@ -0,0 +1,15 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+
6
+ class ApiError(Exception):
7
+ status_code: typing.Optional[int]
8
+ body: typing.Any
9
+
10
+ def __init__(self, *, status_code: typing.Optional[int] = None, body: typing.Any = None):
11
+ self.status_code = status_code
12
+ self.body = body
13
+
14
+ def __str__(self) -> str:
15
+ return f"status_code: {self.status_code}, body: {self.body}"
@@ -0,0 +1,45 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import httpx
6
+
7
+
8
+ class BaseClientWrapper:
9
+ def __init__(self, *, api_key: typing.Union[str, typing.Callable[[], str]], base_url: str):
10
+ self._api_key = api_key
11
+ self._base_url = base_url
12
+
13
+ def get_headers(self) -> typing.Dict[str, str]:
14
+ headers: typing.Dict[str, str] = {
15
+ "X-Fern-Language": "Python",
16
+ "X-Fern-SDK-Name": "athena-intelligence",
17
+ "X-Fern-SDK-Version": "0.1.1",
18
+ }
19
+ headers["Authorization"] = f"Bearer {self._get_api_key()}"
20
+ return headers
21
+
22
+ def _get_api_key(self) -> str:
23
+ if isinstance(self._api_key, str):
24
+ return self._api_key
25
+ else:
26
+ return self._api_key()
27
+
28
+ def get_base_url(self) -> str:
29
+ return self._base_url
30
+
31
+
32
+ class SyncClientWrapper(BaseClientWrapper):
33
+ def __init__(
34
+ self, *, api_key: typing.Union[str, typing.Callable[[], str]], base_url: str, httpx_client: httpx.Client
35
+ ):
36
+ super().__init__(api_key=api_key, base_url=base_url)
37
+ self.httpx_client = httpx_client
38
+
39
+
40
+ class AsyncClientWrapper(BaseClientWrapper):
41
+ def __init__(
42
+ self, *, api_key: typing.Union[str, typing.Callable[[], str]], base_url: str, httpx_client: httpx.AsyncClient
43
+ ):
44
+ super().__init__(api_key=api_key, base_url=base_url)
45
+ self.httpx_client = httpx_client
@@ -0,0 +1,28 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+
5
+
6
+ def serialize_datetime(v: dt.datetime) -> str:
7
+ """
8
+ Serialize a datetime including timezone info.
9
+
10
+ Uses the timezone info provided if present, otherwise uses the current runtime's timezone info.
11
+
12
+ UTC datetimes end in "Z" while all other timezones are represented as offset from UTC, e.g. +05:00.
13
+ """
14
+
15
+ def _serialize_zoned_datetime(v: dt.datetime) -> str:
16
+ if v.tzinfo is not None and v.tzinfo.tzname(None) == dt.timezone.utc.tzname(None):
17
+ # UTC is a special case where we use "Z" at the end instead of "+00:00"
18
+ return v.isoformat().replace("+00:00", "Z")
19
+ else:
20
+ # Delegate to the typical +/- offset format
21
+ return v.isoformat()
22
+
23
+ if v.tzinfo is not None:
24
+ return _serialize_zoned_datetime(v)
25
+ else:
26
+ local_tz = dt.datetime.now().astimezone().tzinfo
27
+ localized_dt = v.replace(tzinfo=local_tz)
28
+ return _serialize_zoned_datetime(localized_dt)
@@ -0,0 +1,38 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ # File typing inspired by the flexibility of types within the httpx library
6
+ # https://github.com/encode/httpx/blob/master/httpx/_types.py
7
+ FileContent = typing.Union[typing.IO[bytes], bytes, str]
8
+ File = typing.Union[
9
+ # file (or bytes)
10
+ FileContent,
11
+ # (filename, file (or bytes))
12
+ typing.Tuple[typing.Optional[str], FileContent],
13
+ # (filename, file (or bytes), content_type)
14
+ typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str]],
15
+ # (filename, file (or bytes), content_type, headers)
16
+ typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str], typing.Mapping[str, str]],
17
+ ]
18
+
19
+
20
+ def convert_file_dict_to_httpx_tuples(
21
+ d: typing.Dict[str, typing.Union[File, typing.List[File]]]
22
+ ) -> typing.List[typing.Tuple[str, File]]:
23
+ """
24
+ The format we use is a list of tuples, where the first element is the
25
+ name of the file and the second is the file object. Typically HTTPX wants
26
+ a dict, but to be able to send lists of files, you have to use the list
27
+ approach (which also works for non-lists)
28
+ https://github.com/encode/httpx/pull/1032
29
+ """
30
+
31
+ httpx_tuples = []
32
+ for key, file_like in d.items():
33
+ if isinstance(file_like, list):
34
+ for file_like_item in file_like:
35
+ httpx_tuples.append((key, file_like_item))
36
+ else:
37
+ httpx_tuples.append((key, file_like))
38
+ return httpx_tuples
@@ -0,0 +1,103 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ """
4
+ jsonable_encoder converts a Python object to a JSON-friendly dict
5
+ (e.g. datetimes to strings, Pydantic models to dicts).
6
+
7
+ Taken from FastAPI, and made a bit simpler
8
+ https://github.com/tiangolo/fastapi/blob/master/fastapi/encoders.py
9
+ """
10
+
11
+ import dataclasses
12
+ import datetime as dt
13
+ from collections import defaultdict
14
+ from enum import Enum
15
+ from pathlib import PurePath
16
+ from types import GeneratorType
17
+ from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
18
+
19
+ try:
20
+ import pydantic.v1 as pydantic # type: ignore
21
+ except ImportError:
22
+ import pydantic # type: ignore
23
+
24
+ from .datetime_utils import serialize_datetime
25
+
26
+ SetIntStr = Set[Union[int, str]]
27
+ DictIntStrAny = Dict[Union[int, str], Any]
28
+
29
+
30
+ def generate_encoders_by_class_tuples(
31
+ type_encoder_map: Dict[Any, Callable[[Any], Any]]
32
+ ) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]:
33
+ encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(tuple)
34
+ for type_, encoder in type_encoder_map.items():
35
+ encoders_by_class_tuples[encoder] += (type_,)
36
+ return encoders_by_class_tuples
37
+
38
+
39
+ encoders_by_class_tuples = generate_encoders_by_class_tuples(pydantic.json.ENCODERS_BY_TYPE)
40
+
41
+
42
+ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None) -> Any:
43
+ custom_encoder = custom_encoder or {}
44
+ if custom_encoder:
45
+ if type(obj) in custom_encoder:
46
+ return custom_encoder[type(obj)](obj)
47
+ else:
48
+ for encoder_type, encoder_instance in custom_encoder.items():
49
+ if isinstance(obj, encoder_type):
50
+ return encoder_instance(obj)
51
+ if isinstance(obj, pydantic.BaseModel):
52
+ encoder = getattr(obj.__config__, "json_encoders", {})
53
+ if custom_encoder:
54
+ encoder.update(custom_encoder)
55
+ obj_dict = obj.dict(by_alias=True)
56
+ if "__root__" in obj_dict:
57
+ obj_dict = obj_dict["__root__"]
58
+ return jsonable_encoder(obj_dict, custom_encoder=encoder)
59
+ if dataclasses.is_dataclass(obj):
60
+ obj_dict = dataclasses.asdict(obj)
61
+ return jsonable_encoder(obj_dict, custom_encoder=custom_encoder)
62
+ if isinstance(obj, Enum):
63
+ return obj.value
64
+ if isinstance(obj, PurePath):
65
+ return str(obj)
66
+ if isinstance(obj, (str, int, float, type(None))):
67
+ return obj
68
+ if isinstance(obj, dt.date):
69
+ return str(obj)
70
+ if isinstance(obj, dt.datetime):
71
+ return serialize_datetime(obj)
72
+ if isinstance(obj, dict):
73
+ encoded_dict = {}
74
+ allowed_keys = set(obj.keys())
75
+ for key, value in obj.items():
76
+ if key in allowed_keys:
77
+ encoded_key = jsonable_encoder(key, custom_encoder=custom_encoder)
78
+ encoded_value = jsonable_encoder(value, custom_encoder=custom_encoder)
79
+ encoded_dict[encoded_key] = encoded_value
80
+ return encoded_dict
81
+ if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)):
82
+ encoded_list = []
83
+ for item in obj:
84
+ encoded_list.append(jsonable_encoder(item, custom_encoder=custom_encoder))
85
+ return encoded_list
86
+
87
+ if type(obj) in pydantic.json.ENCODERS_BY_TYPE:
88
+ return pydantic.json.ENCODERS_BY_TYPE[type(obj)](obj)
89
+ for encoder, classes_tuple in encoders_by_class_tuples.items():
90
+ if isinstance(obj, classes_tuple):
91
+ return encoder(obj)
92
+
93
+ try:
94
+ data = dict(obj)
95
+ except Exception as e:
96
+ errors: List[Exception] = []
97
+ errors.append(e)
98
+ try:
99
+ data = vars(obj)
100
+ except Exception as e:
101
+ errors.append(e)
102
+ raise ValueError(errors) from e
103
+ return jsonable_encoder(data, custom_encoder=custom_encoder)
@@ -0,0 +1,11 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from typing import Any, Dict, Optional
4
+
5
+
6
+ def remove_none_from_dict(original: Dict[str, Optional[Any]]) -> Dict[str, Any]:
7
+ new: Dict[str, Any] = {}
8
+ for key, value in original.items():
9
+ if value is not None:
10
+ new[key] = value
11
+ return new
@@ -0,0 +1,29 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ try:
6
+ from typing import NotRequired # type: ignore
7
+ except ImportError:
8
+ from typing_extensions import NotRequired # type: ignore
9
+
10
+
11
+ class RequestOptions(typing.TypedDict):
12
+ """
13
+ Additional options for request-specific configuration when calling APIs via the SDK.
14
+ This is used primarily as an optional final parameter for service functions.
15
+
16
+ Attributes:
17
+ - timeout_in_seconds: int. The number of seconds to await an API call before timing out.
18
+
19
+ - additional_headers: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's header dict
20
+
21
+ - additional_query_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's query parameters dict
22
+
23
+ - additional_body_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's body parameters dict
24
+ """
25
+
26
+ timeout_in_seconds: NotRequired[int]
27
+ additional_headers: NotRequired[typing.Dict[str, typing.Any]]
28
+ additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]]
29
+ additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]]
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import enum
4
+
5
+
6
+ class AthenaEnvironment(enum.Enum):
7
+ PRODUCTION = "app.athenaintelligence.ai"
File without changes
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from . import message
4
+ from .message import Message
5
+
6
+ __all__ = ["Message", "message"]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .types import Message
4
+
5
+ __all__ = ["Message"]
@@ -0,0 +1,292 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ import urllib.parse
5
+ from json.decoder import JSONDecodeError
6
+
7
+ from ...core.api_error import ApiError
8
+ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
9
+ from ...core.jsonable_encoder import jsonable_encoder
10
+ from ...core.remove_none_from_dict import remove_none_from_dict
11
+ from ...core.request_options import RequestOptions
12
+ from .types.message import Message
13
+
14
+ try:
15
+ import pydantic.v1 as pydantic # type: ignore
16
+ except ImportError:
17
+ import pydantic # type: ignore
18
+
19
+ # this is used as the default value for optional parameters
20
+ OMIT = typing.cast(typing.Any, ...)
21
+
22
+
23
+ class MessageClient:
24
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
25
+ self._client_wrapper = client_wrapper
26
+
27
+ def get(
28
+ self, message_id: typing.Optional[str], *, request_options: typing.Optional[RequestOptions] = None
29
+ ) -> Message:
30
+ """
31
+ Get an Athena message by ID.
32
+ Returns an Athena message final output.
33
+
34
+ Parameters:
35
+ - message_id: typing.Optional[str].
36
+
37
+ - request_options: typing.Optional[RequestOptions]. Request-specific configuration.
38
+ """
39
+ _response = self._client_wrapper.httpx_client.request(
40
+ "GET",
41
+ urllib.parse.urljoin(
42
+ f"{self._client_wrapper.get_base_url()}/", f"api/v0/athena/agent/{jsonable_encoder(message_id)}"
43
+ ),
44
+ params=jsonable_encoder(
45
+ request_options.get("additional_query_parameters") if request_options is not None else None
46
+ ),
47
+ headers=jsonable_encoder(
48
+ remove_none_from_dict(
49
+ {
50
+ **self._client_wrapper.get_headers(),
51
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
52
+ }
53
+ )
54
+ ),
55
+ timeout=request_options.get("timeout_in_seconds")
56
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
57
+ else 60,
58
+ )
59
+ if 200 <= _response.status_code < 300:
60
+ return pydantic.parse_obj_as(Message, _response.json()) # type: ignore
61
+ try:
62
+ _response_json = _response.json()
63
+ except JSONDecodeError:
64
+ raise ApiError(status_code=_response.status_code, body=_response.text)
65
+ raise ApiError(status_code=_response.status_code, body=_response_json)
66
+
67
+ def send(
68
+ self,
69
+ *,
70
+ content: str,
71
+ conversation_id: typing.Optional[str] = OMIT,
72
+ user_id: typing.Optional[str] = OMIT,
73
+ workspace_id: typing.Optional[str] = OMIT,
74
+ sdataset_ids: typing.Optional[typing.Sequence[str]] = OMIT,
75
+ tools: typing.Optional[typing.Sequence[str]] = OMIT,
76
+ model: typing.Optional[str] = OMIT,
77
+ documents: typing.Optional[typing.Sequence[str]] = OMIT,
78
+ config: typing.Dict[str, typing.Any],
79
+ additional_context: typing.Optional[str] = OMIT,
80
+ request_options: typing.Optional[RequestOptions] = None,
81
+ ) -> Message:
82
+ """
83
+ Send a message to Athena.
84
+ Returns an Athena message with ID, content and final output.
85
+
86
+ Parameters:
87
+ - content: str.
88
+
89
+ - conversation_id: typing.Optional[str].
90
+
91
+ - user_id: typing.Optional[str].
92
+
93
+ - workspace_id: typing.Optional[str].
94
+
95
+ - sdataset_ids: typing.Optional[typing.Sequence[str]].
96
+
97
+ - tools: typing.Optional[typing.Sequence[str]].
98
+
99
+ - model: typing.Optional[str].
100
+
101
+ - documents: typing.Optional[typing.Sequence[str]].
102
+
103
+ - config: typing.Dict[str, typing.Any].
104
+
105
+ - additional_context: typing.Optional[str].
106
+
107
+ - request_options: typing.Optional[RequestOptions]. Request-specific configuration.
108
+ """
109
+ _request: typing.Dict[str, typing.Any] = {"content": content, "config": config}
110
+ if conversation_id is not OMIT:
111
+ _request["conversation_id"] = conversation_id
112
+ if user_id is not OMIT:
113
+ _request["user_id"] = user_id
114
+ if workspace_id is not OMIT:
115
+ _request["workspace_id"] = workspace_id
116
+ if sdataset_ids is not OMIT:
117
+ _request["sdataset_ids"] = sdataset_ids
118
+ if tools is not OMIT:
119
+ _request["tools"] = tools
120
+ if model is not OMIT:
121
+ _request["model"] = model
122
+ if documents is not OMIT:
123
+ _request["documents"] = documents
124
+ if additional_context is not OMIT:
125
+ _request["additional_context"] = additional_context
126
+ _response = self._client_wrapper.httpx_client.request(
127
+ "POST",
128
+ urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v0/athena/agent"),
129
+ params=jsonable_encoder(
130
+ request_options.get("additional_query_parameters") if request_options is not None else None
131
+ ),
132
+ json=jsonable_encoder(_request)
133
+ if request_options is None or request_options.get("additional_body_parameters") is None
134
+ else {
135
+ **jsonable_encoder(_request),
136
+ **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
137
+ },
138
+ headers=jsonable_encoder(
139
+ remove_none_from_dict(
140
+ {
141
+ **self._client_wrapper.get_headers(),
142
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
143
+ }
144
+ )
145
+ ),
146
+ timeout=request_options.get("timeout_in_seconds")
147
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
148
+ else 60,
149
+ )
150
+ if 200 <= _response.status_code < 300:
151
+ return pydantic.parse_obj_as(Message, _response.json()) # type: ignore
152
+ try:
153
+ _response_json = _response.json()
154
+ except JSONDecodeError:
155
+ raise ApiError(status_code=_response.status_code, body=_response.text)
156
+ raise ApiError(status_code=_response.status_code, body=_response_json)
157
+
158
+
159
+ class AsyncMessageClient:
160
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
161
+ self._client_wrapper = client_wrapper
162
+
163
+ async def get(
164
+ self, message_id: typing.Optional[str], *, request_options: typing.Optional[RequestOptions] = None
165
+ ) -> Message:
166
+ """
167
+ Get an Athena message by ID.
168
+ Returns an Athena message final output.
169
+
170
+ Parameters:
171
+ - message_id: typing.Optional[str].
172
+
173
+ - request_options: typing.Optional[RequestOptions]. Request-specific configuration.
174
+ """
175
+ _response = await self._client_wrapper.httpx_client.request(
176
+ "GET",
177
+ urllib.parse.urljoin(
178
+ f"{self._client_wrapper.get_base_url()}/", f"api/v0/athena/agent/{jsonable_encoder(message_id)}"
179
+ ),
180
+ params=jsonable_encoder(
181
+ request_options.get("additional_query_parameters") if request_options is not None else None
182
+ ),
183
+ headers=jsonable_encoder(
184
+ remove_none_from_dict(
185
+ {
186
+ **self._client_wrapper.get_headers(),
187
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
188
+ }
189
+ )
190
+ ),
191
+ timeout=request_options.get("timeout_in_seconds")
192
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
193
+ else 60,
194
+ )
195
+ if 200 <= _response.status_code < 300:
196
+ return pydantic.parse_obj_as(Message, _response.json()) # type: ignore
197
+ try:
198
+ _response_json = _response.json()
199
+ except JSONDecodeError:
200
+ raise ApiError(status_code=_response.status_code, body=_response.text)
201
+ raise ApiError(status_code=_response.status_code, body=_response_json)
202
+
203
+ async def send(
204
+ self,
205
+ *,
206
+ content: str,
207
+ conversation_id: typing.Optional[str] = OMIT,
208
+ user_id: typing.Optional[str] = OMIT,
209
+ workspace_id: typing.Optional[str] = OMIT,
210
+ sdataset_ids: typing.Optional[typing.Sequence[str]] = OMIT,
211
+ tools: typing.Optional[typing.Sequence[str]] = OMIT,
212
+ model: typing.Optional[str] = OMIT,
213
+ documents: typing.Optional[typing.Sequence[str]] = OMIT,
214
+ config: typing.Dict[str, typing.Any],
215
+ additional_context: typing.Optional[str] = OMIT,
216
+ request_options: typing.Optional[RequestOptions] = None,
217
+ ) -> Message:
218
+ """
219
+ Send a message to Athena.
220
+ Returns an Athena message with ID, content and final output.
221
+
222
+ Parameters:
223
+ - content: str.
224
+
225
+ - conversation_id: typing.Optional[str].
226
+
227
+ - user_id: typing.Optional[str].
228
+
229
+ - workspace_id: typing.Optional[str].
230
+
231
+ - sdataset_ids: typing.Optional[typing.Sequence[str]].
232
+
233
+ - tools: typing.Optional[typing.Sequence[str]].
234
+
235
+ - model: typing.Optional[str].
236
+
237
+ - documents: typing.Optional[typing.Sequence[str]].
238
+
239
+ - config: typing.Dict[str, typing.Any].
240
+
241
+ - additional_context: typing.Optional[str].
242
+
243
+ - request_options: typing.Optional[RequestOptions]. Request-specific configuration.
244
+ """
245
+ _request: typing.Dict[str, typing.Any] = {"content": content, "config": config}
246
+ if conversation_id is not OMIT:
247
+ _request["conversation_id"] = conversation_id
248
+ if user_id is not OMIT:
249
+ _request["user_id"] = user_id
250
+ if workspace_id is not OMIT:
251
+ _request["workspace_id"] = workspace_id
252
+ if sdataset_ids is not OMIT:
253
+ _request["sdataset_ids"] = sdataset_ids
254
+ if tools is not OMIT:
255
+ _request["tools"] = tools
256
+ if model is not OMIT:
257
+ _request["model"] = model
258
+ if documents is not OMIT:
259
+ _request["documents"] = documents
260
+ if additional_context is not OMIT:
261
+ _request["additional_context"] = additional_context
262
+ _response = await self._client_wrapper.httpx_client.request(
263
+ "POST",
264
+ urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v0/athena/agent"),
265
+ params=jsonable_encoder(
266
+ request_options.get("additional_query_parameters") if request_options is not None else None
267
+ ),
268
+ json=jsonable_encoder(_request)
269
+ if request_options is None or request_options.get("additional_body_parameters") is None
270
+ else {
271
+ **jsonable_encoder(_request),
272
+ **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))),
273
+ },
274
+ headers=jsonable_encoder(
275
+ remove_none_from_dict(
276
+ {
277
+ **self._client_wrapper.get_headers(),
278
+ **(request_options.get("additional_headers", {}) if request_options is not None else {}),
279
+ }
280
+ )
281
+ ),
282
+ timeout=request_options.get("timeout_in_seconds")
283
+ if request_options is not None and request_options.get("timeout_in_seconds") is not None
284
+ else 60,
285
+ )
286
+ if 200 <= _response.status_code < 300:
287
+ return pydantic.parse_obj_as(Message, _response.json()) # type: ignore
288
+ try:
289
+ _response_json = _response.json()
290
+ except JSONDecodeError:
291
+ raise ApiError(status_code=_response.status_code, body=_response.text)
292
+ raise ApiError(status_code=_response.status_code, body=_response_json)
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .message import Message
4
+
5
+ __all__ = ["Message"]
@@ -0,0 +1,35 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ....core.datetime_utils import serialize_datetime
7
+
8
+ try:
9
+ import pydantic.v1 as pydantic # type: ignore
10
+ except ImportError:
11
+ import pydantic # type: ignore
12
+
13
+
14
+ class Message(pydantic.BaseModel):
15
+ message_id: str
16
+ conversation_id: str
17
+ sender: str
18
+ content: str
19
+ status: str
20
+ created_at: dt.datetime
21
+ config: typing.Dict[str, typing.Any]
22
+ final_output: str
23
+
24
+ def json(self, **kwargs: typing.Any) -> str:
25
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
26
+ return super().json(**kwargs_with_defaults)
27
+
28
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
29
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
30
+ return super().dict(**kwargs_with_defaults)
31
+
32
+ class Config:
33
+ frozen = True
34
+ smart_union = True
35
+ json_encoders = {dt.datetime: serialize_datetime}