somia 0.1.0a1__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.
somia-0.1.0a1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Somia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ recursive-include src *.py
5
+ global-exclude *.py[cod]
6
+ global-exclude __pycache__
7
+ prune **/__pycache__
somia-0.1.0a1/PKG-INFO ADDED
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: somia
3
+ Version: 0.1.0a1
4
+ Summary: Python SDK for interacting with Somia Agent API
5
+ Author: Somia
6
+ License-Expression: MIT
7
+ Keywords: somia,agents,api,sdk
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.11
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: httpx<1.0.0,>=0.27.0
20
+ Requires-Dist: pydantic<3.0.0,>=2.7.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
23
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # Somia Python SDK
27
+
28
+ > **Alpha release (`0.1.0a1`)** — early SDK for testing and evaluation. APIs may change. Install with `pip install somia --pre` or pin `pip install somia==0.1.0a1`.
29
+
30
+ Official Python client for the [Somia](https://somia-platform.com) Agent API.
31
+
32
+ The SDK is open source under the MIT license. Access to the Somia platform requires a Somia account and API key; usage of the hosted API is subject to Somia's terms and billing.
33
+
34
+ ## Supported endpoints
35
+
36
+ - `POST /api/v1/external/agent/{agent_id}/session` — create a session
37
+ - `POST /api/v1/external/agent/{agent_id}/session/{session_id}` — continue a session
38
+
39
+ ## Installation
40
+
41
+ From PyPI (pre-release):
42
+
43
+ ```bash
44
+ pip install somia --pre
45
+ ```
46
+
47
+ Or pin the exact version:
48
+
49
+ ```bash
50
+ pip install somia==0.1.0a1
51
+ ```
52
+
53
+ From source (development):
54
+
55
+ ```bash
56
+ git clone https://github.com/somia-platform/somia-python-sdk.git
57
+ cd somia-python-sdk
58
+ pip install -e ".[dev]"
59
+ ```
60
+
61
+ Requires Python 3.11+.
62
+
63
+ ## Quickstart
64
+
65
+ ```python
66
+ from somia import SomiaClient
67
+
68
+ with SomiaClient(
69
+ base_url="https://api.somia-platform.com",
70
+ api_key="your_api_key",
71
+ ) as client:
72
+ response = client.sessions.create_session(
73
+ agent_id=123,
74
+ input_data="Hello",
75
+ pipeline_version="production",
76
+ )
77
+ print(response.session_id, response.message)
78
+ ```
79
+
80
+ ## Continue an existing session
81
+
82
+ ```python
83
+ from somia import SomiaClient
84
+
85
+ with SomiaClient(
86
+ base_url="https://api.somia-platform.com",
87
+ api_key="your_api_key",
88
+ ) as client:
89
+ response = client.sessions.interact_session(
90
+ agent_id=123,
91
+ session_id="550e8400-e29b-41d4-a716-446655440000",
92
+ input_data="Can you explain it in one paragraph?",
93
+ )
94
+ print(response.message)
95
+ ```
96
+
97
+ You can also use `client.sessions.run(...)` with an optional `session_id` to create or continue in one call.
98
+
99
+ ## Streaming responses (SSE)
100
+
101
+ ```python
102
+ from somia import SomiaClient
103
+
104
+ with SomiaClient(
105
+ base_url="https://api.somia-platform.com",
106
+ api_key="your_api_key",
107
+ ) as client:
108
+ events = client.sessions.create_session(
109
+ agent_id=123,
110
+ input_data="Stream this answer",
111
+ stream=True,
112
+ )
113
+ for event in events:
114
+ if event.event_type == "chunk":
115
+ print("chunk:", event.data)
116
+ elif event.event_type == "error":
117
+ print("error:", event.data)
118
+ elif event.event_type == "end":
119
+ print("stream ended")
120
+ ```
121
+
122
+ ## Authentication
123
+
124
+ By default the SDK sends your API key in the `x-api-key` header. Override the header name if needed:
125
+
126
+ ```python
127
+ client = SomiaClient(
128
+ base_url="https://api.somia-platform.com",
129
+ api_key="your_api_key",
130
+ api_key_header="apikey",
131
+ )
132
+ ```
133
+
134
+ ## Error handling
135
+
136
+ ```python
137
+ from somia import AuthError, RateLimitError, ServiceUnavailableError, SomiaClient
138
+
139
+ try:
140
+ with SomiaClient(base_url="https://api.somia-platform.com", api_key="...") as client:
141
+ client.sessions.create_session(agent_id=123, input_data="Hi")
142
+ except AuthError:
143
+ print("Invalid API key")
144
+ except RateLimitError:
145
+ print("Rate limit exceeded")
146
+ except ServiceUnavailableError as exc:
147
+ print(f"Retry later: {exc}")
148
+ ```
149
+
150
+ Common error classes:
151
+
152
+ - `BadRequestError` — invalid payloads
153
+ - `AuthError` — missing or invalid API key
154
+ - `PermissionDeniedError` — access or usage-limit failures
155
+ - `NotFoundError` — missing agents or sessions
156
+ - `RateLimitError` — rate limits exceeded
157
+ - `ServiceUnavailableError` — platform saturation or timeouts
158
+ - `ServerError` — unexpected server-side failures
159
+ - `TransportError` — network-level failures
160
+ - `StreamParseError` — malformed SSE payloads
161
+
162
+ ## Session flow notes
163
+
164
+ - Create-session may ignore `input_data` when Begin has no required query fields.
165
+ - Interact-session always uses `session_id` in the path and forwards `input_data` as the turn payload.
166
+ - Non-streaming responses include fields such as `session_id`, `message`, `history`, `pending`, and `finished`.
167
+
168
+ ## Development
169
+
170
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, testing, versioning, and release instructions.
171
+
172
+ ## License
173
+
174
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,149 @@
1
+ # Somia Python SDK
2
+
3
+ > **Alpha release (`0.1.0a1`)** — early SDK for testing and evaluation. APIs may change. Install with `pip install somia --pre` or pin `pip install somia==0.1.0a1`.
4
+
5
+ Official Python client for the [Somia](https://somia-platform.com) Agent API.
6
+
7
+ The SDK is open source under the MIT license. Access to the Somia platform requires a Somia account and API key; usage of the hosted API is subject to Somia's terms and billing.
8
+
9
+ ## Supported endpoints
10
+
11
+ - `POST /api/v1/external/agent/{agent_id}/session` — create a session
12
+ - `POST /api/v1/external/agent/{agent_id}/session/{session_id}` — continue a session
13
+
14
+ ## Installation
15
+
16
+ From PyPI (pre-release):
17
+
18
+ ```bash
19
+ pip install somia --pre
20
+ ```
21
+
22
+ Or pin the exact version:
23
+
24
+ ```bash
25
+ pip install somia==0.1.0a1
26
+ ```
27
+
28
+ From source (development):
29
+
30
+ ```bash
31
+ git clone https://github.com/somia-platform/somia-python-sdk.git
32
+ cd somia-python-sdk
33
+ pip install -e ".[dev]"
34
+ ```
35
+
36
+ Requires Python 3.11+.
37
+
38
+ ## Quickstart
39
+
40
+ ```python
41
+ from somia import SomiaClient
42
+
43
+ with SomiaClient(
44
+ base_url="https://api.somia-platform.com",
45
+ api_key="your_api_key",
46
+ ) as client:
47
+ response = client.sessions.create_session(
48
+ agent_id=123,
49
+ input_data="Hello",
50
+ pipeline_version="production",
51
+ )
52
+ print(response.session_id, response.message)
53
+ ```
54
+
55
+ ## Continue an existing session
56
+
57
+ ```python
58
+ from somia import SomiaClient
59
+
60
+ with SomiaClient(
61
+ base_url="https://api.somia-platform.com",
62
+ api_key="your_api_key",
63
+ ) as client:
64
+ response = client.sessions.interact_session(
65
+ agent_id=123,
66
+ session_id="550e8400-e29b-41d4-a716-446655440000",
67
+ input_data="Can you explain it in one paragraph?",
68
+ )
69
+ print(response.message)
70
+ ```
71
+
72
+ You can also use `client.sessions.run(...)` with an optional `session_id` to create or continue in one call.
73
+
74
+ ## Streaming responses (SSE)
75
+
76
+ ```python
77
+ from somia import SomiaClient
78
+
79
+ with SomiaClient(
80
+ base_url="https://api.somia-platform.com",
81
+ api_key="your_api_key",
82
+ ) as client:
83
+ events = client.sessions.create_session(
84
+ agent_id=123,
85
+ input_data="Stream this answer",
86
+ stream=True,
87
+ )
88
+ for event in events:
89
+ if event.event_type == "chunk":
90
+ print("chunk:", event.data)
91
+ elif event.event_type == "error":
92
+ print("error:", event.data)
93
+ elif event.event_type == "end":
94
+ print("stream ended")
95
+ ```
96
+
97
+ ## Authentication
98
+
99
+ By default the SDK sends your API key in the `x-api-key` header. Override the header name if needed:
100
+
101
+ ```python
102
+ client = SomiaClient(
103
+ base_url="https://api.somia-platform.com",
104
+ api_key="your_api_key",
105
+ api_key_header="apikey",
106
+ )
107
+ ```
108
+
109
+ ## Error handling
110
+
111
+ ```python
112
+ from somia import AuthError, RateLimitError, ServiceUnavailableError, SomiaClient
113
+
114
+ try:
115
+ with SomiaClient(base_url="https://api.somia-platform.com", api_key="...") as client:
116
+ client.sessions.create_session(agent_id=123, input_data="Hi")
117
+ except AuthError:
118
+ print("Invalid API key")
119
+ except RateLimitError:
120
+ print("Rate limit exceeded")
121
+ except ServiceUnavailableError as exc:
122
+ print(f"Retry later: {exc}")
123
+ ```
124
+
125
+ Common error classes:
126
+
127
+ - `BadRequestError` — invalid payloads
128
+ - `AuthError` — missing or invalid API key
129
+ - `PermissionDeniedError` — access or usage-limit failures
130
+ - `NotFoundError` — missing agents or sessions
131
+ - `RateLimitError` — rate limits exceeded
132
+ - `ServiceUnavailableError` — platform saturation or timeouts
133
+ - `ServerError` — unexpected server-side failures
134
+ - `TransportError` — network-level failures
135
+ - `StreamParseError` — malformed SSE payloads
136
+
137
+ ## Session flow notes
138
+
139
+ - Create-session may ignore `input_data` when Begin has no required query fields.
140
+ - Interact-session always uses `session_id` in the path and forwards `input_data` as the turn payload.
141
+ - Non-streaming responses include fields such as `session_id`, `message`, `history`, `pending`, and `finished`.
142
+
143
+ ## Development
144
+
145
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, testing, versioning, and release instructions.
146
+
147
+ ## License
148
+
149
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "somia"
7
+ version = "0.1.0a1"
8
+ description = "Python SDK for interacting with Somia Agent API"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ { name = "Somia" }
15
+ ]
16
+ keywords = ["somia", "agents", "api", "sdk"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Libraries",
25
+ "Typing :: Typed",
26
+ ]
27
+ dependencies = [
28
+ "httpx>=0.27.0,<1.0.0",
29
+ "pydantic>=2.7.0,<3.0.0"
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=8.0.0",
35
+ "pytest-cov>=5.0.0"
36
+ ]
37
+
38
+ [tool.setuptools]
39
+ package-dir = { "" = "src" }
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
46
+ addopts = "-q"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,37 @@
1
+ from somia.client import AgentSessionsClient, SomiaClient
2
+ from somia.exceptions import (
3
+ ApiError,
4
+ AuthError,
5
+ BadRequestError,
6
+ NotFoundError,
7
+ PermissionDeniedError,
8
+ RateLimitError,
9
+ ServerError,
10
+ ServiceUnavailableError,
11
+ SomiaError,
12
+ StreamParseError,
13
+ TransportError,
14
+ )
15
+ from somia.models import AgentExecutionRequest, AgentSessionResponse, StreamEvent
16
+
17
+ __version__ = "0.1.0a1"
18
+
19
+ __all__ = [
20
+ "AgentExecutionRequest",
21
+ "AgentSessionResponse",
22
+ "AgentSessionsClient",
23
+ "ApiError",
24
+ "AuthError",
25
+ "BadRequestError",
26
+ "NotFoundError",
27
+ "PermissionDeniedError",
28
+ "RateLimitError",
29
+ "ServerError",
30
+ "ServiceUnavailableError",
31
+ "SomiaClient",
32
+ "SomiaError",
33
+ "StreamEvent",
34
+ "StreamParseError",
35
+ "TransportError",
36
+ "__version__",
37
+ ]
@@ -0,0 +1,96 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from typing import Any, Dict, Iterator, Optional, Set
5
+
6
+ import httpx
7
+
8
+ from somia.exceptions import TransportError, raise_for_status
9
+ from somia.models import StreamEvent
10
+ from somia.streaming import parse_sse_events
11
+
12
+
13
+ class HttpTransport:
14
+
15
+ def __init__(
16
+ self,
17
+ *,
18
+ base_url: str,
19
+ api_key: str,
20
+ timeout: float = 60.0,
21
+ retries: int = 2,
22
+ retry_backoff_seconds: float = 0.5,
23
+ api_key_header: str = "x-api-key",
24
+ transient_status_codes: Optional[Set[int]] = None,
25
+ transport: Optional[httpx.BaseTransport] = None,
26
+ ) -> None:
27
+ self._retries = max(0, retries)
28
+ self._retry_backoff_seconds = max(0.0, retry_backoff_seconds)
29
+ self._transient_status_codes = transient_status_codes or {429, 500, 502, 503, 504}
30
+ client_kwargs: Dict[str, Any] = {
31
+ "base_url": base_url.rstrip("/"),
32
+ "timeout": httpx.Timeout(timeout),
33
+ "headers": {
34
+ api_key_header: api_key,
35
+ "content-type": "application/json",
36
+ },
37
+ }
38
+ if transport is not None:
39
+ client_kwargs["transport"] = transport
40
+ self._client = httpx.Client(**client_kwargs)
41
+
42
+ def close(self) -> None:
43
+ self._client.close()
44
+
45
+ def post_json(self, path: str, payload: Dict[str, Any]) -> Dict[str, Any]:
46
+ last_error: Optional[Exception] = None
47
+ for attempt in range(self._retries + 1):
48
+ try:
49
+ response = self._client.post(path, json=payload)
50
+ except httpx.HTTPError as exc:
51
+ if attempt >= self._retries:
52
+ raise TransportError(str(exc)) from exc
53
+ self._sleep_backoff(attempt)
54
+ continue
55
+
56
+ if response.status_code in self._transient_status_codes and attempt < self._retries:
57
+ last_error = TransportError(
58
+ f"Transient HTTP status {response.status_code} for {path}",
59
+ )
60
+ self._sleep_backoff(attempt)
61
+ continue
62
+
63
+ body = self._decode_json_or_text(response)
64
+ raise_for_status(response.status_code, body)
65
+ if isinstance(body, dict):
66
+ return body
67
+ raise TransportError("Expected JSON object response from API.")
68
+
69
+ if last_error is not None:
70
+ raise last_error
71
+ raise TransportError("Request failed without a recoverable response.")
72
+
73
+ def post_stream(self, path: str, payload: Dict[str, Any]) -> Iterator[StreamEvent]:
74
+ try:
75
+ with self._client.stream("POST", path, json=payload) as response:
76
+ if response.status_code >= 400:
77
+ body = self._decode_json_or_text(response)
78
+ raise_for_status(response.status_code, body)
79
+ for event in parse_sse_events(response.iter_lines()):
80
+ yield event
81
+ except httpx.HTTPError as exc:
82
+ raise TransportError(str(exc)) from exc
83
+
84
+ def _sleep_backoff(self, attempt: int) -> None:
85
+ sleep_seconds = self._retry_backoff_seconds * (2 ** attempt)
86
+ if sleep_seconds > 0:
87
+ time.sleep(sleep_seconds)
88
+
89
+ @staticmethod
90
+ def _decode_json_or_text(response: httpx.Response) -> Any:
91
+ try:
92
+ return response.json()
93
+ except ValueError:
94
+ if response.text:
95
+ return response.text
96
+ return None
@@ -0,0 +1,147 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, Iterator, Optional, Union
4
+
5
+ from somia._http import HttpTransport
6
+ from somia.models import AgentExecutionRequest, AgentSessionResponse, StreamEvent
7
+
8
+
9
+ class AgentSessionsClient:
10
+
11
+ def __init__(self, transport: HttpTransport) -> None:
12
+ self._transport = transport
13
+
14
+ def create_session(
15
+ self,
16
+ agent_id: int,
17
+ *,
18
+ input_data: Optional[Any] = None,
19
+ stream: bool = False,
20
+ pipeline_version: Union[int, str] = "production",
21
+ trace_enabled: bool = False,
22
+ test: bool = False,
23
+ source: Optional[str] = None,
24
+ ) -> Union[AgentSessionResponse, Iterator[StreamEvent]]:
25
+ payload = self._payload(
26
+ input_data=input_data,
27
+ stream=stream,
28
+ pipeline_version=pipeline_version,
29
+ trace_enabled=trace_enabled,
30
+ test=test,
31
+ source=source,
32
+ )
33
+ path = f"/api/v1/external/agent/{agent_id}/session"
34
+ if stream:
35
+ return self._transport.post_stream(path, payload)
36
+ return AgentSessionResponse.model_validate(self._transport.post_json(path, payload))
37
+
38
+ def interact_session(
39
+ self,
40
+ agent_id: int,
41
+ session_id: str,
42
+ *,
43
+ input_data: Optional[Any] = None,
44
+ stream: bool = False,
45
+ pipeline_version: Union[int, str] = "production",
46
+ trace_enabled: bool = False,
47
+ test: bool = False,
48
+ source: Optional[str] = None,
49
+ ) -> Union[AgentSessionResponse, Iterator[StreamEvent]]:
50
+ payload = self._payload(
51
+ input_data=input_data,
52
+ stream=stream,
53
+ pipeline_version=pipeline_version,
54
+ trace_enabled=trace_enabled,
55
+ test=test,
56
+ source=source,
57
+ )
58
+ path = f"/api/v1/external/agent/{agent_id}/session/{session_id}"
59
+ if stream:
60
+ return self._transport.post_stream(path, payload)
61
+ return AgentSessionResponse.model_validate(self._transport.post_json(path, payload))
62
+
63
+ def run(
64
+ self,
65
+ agent_id: int,
66
+ *,
67
+ input_data: Optional[Any] = None,
68
+ session_id: Optional[str] = None,
69
+ stream: bool = False,
70
+ pipeline_version: Union[int, str] = "production",
71
+ trace_enabled: bool = False,
72
+ test: bool = False,
73
+ source: Optional[str] = None,
74
+ ) -> Union[AgentSessionResponse, Iterator[StreamEvent]]:
75
+ if session_id:
76
+ return self.interact_session(
77
+ agent_id,
78
+ session_id,
79
+ input_data=input_data,
80
+ stream=stream,
81
+ pipeline_version=pipeline_version,
82
+ trace_enabled=trace_enabled,
83
+ test=test,
84
+ source=source,
85
+ )
86
+ return self.create_session(
87
+ agent_id,
88
+ input_data=input_data,
89
+ stream=stream,
90
+ pipeline_version=pipeline_version,
91
+ trace_enabled=trace_enabled,
92
+ test=test,
93
+ source=source,
94
+ )
95
+
96
+ @staticmethod
97
+ def _payload(
98
+ *,
99
+ input_data: Optional[Any],
100
+ stream: bool,
101
+ pipeline_version: Union[int, str],
102
+ trace_enabled: bool,
103
+ test: bool,
104
+ source: Optional[str],
105
+ ) -> Dict[str, Any]:
106
+ request = AgentExecutionRequest(
107
+ input_data=input_data,
108
+ stream=stream,
109
+ pipeline_version=pipeline_version,
110
+ trace_enabled=trace_enabled,
111
+ test=test,
112
+ source=source,
113
+ )
114
+ return request.model_dump(exclude_none=True)
115
+
116
+
117
+ class SomiaClient:
118
+
119
+ def __init__(
120
+ self,
121
+ *,
122
+ base_url: str,
123
+ api_key: str,
124
+ timeout: float = 60.0,
125
+ retries: int = 2,
126
+ retry_backoff_seconds: float = 0.5,
127
+ api_key_header: str = "x-api-key",
128
+ ) -> None:
129
+ self._transport = HttpTransport(
130
+ base_url=base_url,
131
+ api_key=api_key,
132
+ timeout=timeout,
133
+ retries=retries,
134
+ retry_backoff_seconds=retry_backoff_seconds,
135
+ api_key_header=api_key_header,
136
+ )
137
+ self.sessions = AgentSessionsClient(self._transport)
138
+ self.agents = self.sessions
139
+
140
+ def close(self) -> None:
141
+ self._transport.close()
142
+
143
+ def __enter__(self) -> "SomiaClient":
144
+ return self
145
+
146
+ def __exit__(self, exc_type, exc, tb) -> None:
147
+ self.close()