amigo_sdk 0.62.0__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.
@@ -0,0 +1,187 @@
1
+ from typing import Any, Optional
2
+
3
+ from amigo_sdk.config import AmigoConfig
4
+ from amigo_sdk.http_client import AmigoAsyncHttpClient, AmigoHttpClient
5
+ from amigo_sdk.resources.conversation import (
6
+ AsyncConversationResource,
7
+ ConversationResource,
8
+ )
9
+ from amigo_sdk.resources.organization import (
10
+ AsyncOrganizationResource,
11
+ OrganizationResource,
12
+ )
13
+ from amigo_sdk.resources.service import AsyncServiceResource, ServiceResource
14
+ from amigo_sdk.resources.user import AsyncUserResource, UserResource
15
+
16
+
17
+ class AsyncAmigoClient:
18
+ """Amigo API client (asynchronous)."""
19
+
20
+ def __init__(
21
+ self,
22
+ *,
23
+ api_key: Optional[str] = None,
24
+ api_key_id: Optional[str] = None,
25
+ user_id: Optional[str] = None,
26
+ organization_id: Optional[str] = None,
27
+ base_url: Optional[str] = None,
28
+ config: Optional[AmigoConfig] = None,
29
+ **httpx_kwargs: Any,
30
+ ):
31
+ """
32
+ Initialize the Amigo SDK client.
33
+
34
+ Args:
35
+ api_key: API key for authentication (or set AMIGO_API_KEY env var)
36
+ api_key_id: API key ID for authentication (or set AMIGO_API_KEY_ID env var)
37
+ user_id: User ID for API requests (or set AMIGO_USER_ID env var)
38
+ organization_id: Organization ID for API requests (or set AMIGO_ORGANIZATION_ID env var)
39
+ base_url: Base URL for the API (or set AMIGO_BASE_URL env var)
40
+ config: Pre-configured AmigoConfig instance (overrides individual params)
41
+ **httpx_kwargs: Additional arguments passed to httpx.AsyncClient
42
+ """
43
+ if config:
44
+ self._cfg = config
45
+ else:
46
+ # Build config from individual parameters, falling back to env vars
47
+ cfg_dict: dict[str, Any] = {
48
+ k: v
49
+ for k, v in [
50
+ ("api_key", api_key),
51
+ ("api_key_id", api_key_id),
52
+ ("user_id", user_id),
53
+ ("organization_id", organization_id),
54
+ ("base_url", base_url),
55
+ ]
56
+ if v is not None
57
+ }
58
+
59
+ try:
60
+ self._cfg = AmigoConfig(**cfg_dict)
61
+ except Exception as e:
62
+ raise ValueError(
63
+ "AmigoClient configuration incomplete. "
64
+ "Provide api_key, api_key_id, user_id, organization_id, base_url "
65
+ "either as kwargs or environment variables."
66
+ ) from e
67
+
68
+ # Initialize HTTP client and resources
69
+ self._http = AmigoAsyncHttpClient(self._cfg, **httpx_kwargs)
70
+ self._organization = AsyncOrganizationResource(
71
+ self._http, self._cfg.organization_id
72
+ )
73
+ self._service = AsyncServiceResource(self._http, self._cfg.organization_id)
74
+ self._conversation = AsyncConversationResource(
75
+ self._http, self._cfg.organization_id
76
+ )
77
+ self._users = AsyncUserResource(self._http, self._cfg.organization_id)
78
+
79
+ @property
80
+ def config(self) -> AmigoConfig:
81
+ """Access the configuration object."""
82
+ return self._cfg
83
+
84
+ @property
85
+ def organization(self) -> AsyncOrganizationResource:
86
+ """Access organization resource."""
87
+ return self._organization
88
+
89
+ @property
90
+ def service(self) -> AsyncServiceResource:
91
+ """Access service resource."""
92
+ return self._service
93
+
94
+ @property
95
+ def conversation(self) -> AsyncConversationResource:
96
+ """Access conversation resource."""
97
+ return self._conversation
98
+
99
+ @property
100
+ def users(self) -> AsyncUserResource:
101
+ """Access user resource."""
102
+ return self._users
103
+
104
+ async def aclose(self) -> None:
105
+ """Close the HTTP client."""
106
+ await self._http.aclose()
107
+
108
+ # async-context-manager sugar
109
+ async def __aenter__(self):
110
+ return self
111
+
112
+ async def __aexit__(self, *_):
113
+ await self.aclose()
114
+
115
+
116
+ class AmigoClient:
117
+ """Amigo API client (synchronous)."""
118
+
119
+ def __init__(
120
+ self,
121
+ *,
122
+ api_key: Optional[str] = None,
123
+ api_key_id: Optional[str] = None,
124
+ user_id: Optional[str] = None,
125
+ organization_id: Optional[str] = None,
126
+ base_url: Optional[str] = None,
127
+ config: Optional[AmigoConfig] = None,
128
+ **httpx_kwargs: Any,
129
+ ):
130
+ if config:
131
+ self._cfg = config
132
+ else:
133
+ cfg_dict: dict[str, Any] = {
134
+ k: v
135
+ for k, v in [
136
+ ("api_key", api_key),
137
+ ("api_key_id", api_key_id),
138
+ ("user_id", user_id),
139
+ ("organization_id", organization_id),
140
+ ("base_url", base_url),
141
+ ]
142
+ if v is not None
143
+ }
144
+
145
+ try:
146
+ self._cfg = AmigoConfig(**cfg_dict)
147
+ except Exception as e:
148
+ raise ValueError(
149
+ "AmigoClient configuration incomplete. "
150
+ "Provide api_key, api_key_id, user_id, organization_id, base_url "
151
+ "either as kwargs or environment variables."
152
+ ) from e
153
+
154
+ self._http = AmigoHttpClient(self._cfg, **httpx_kwargs)
155
+ self._organization = OrganizationResource(self._http, self._cfg.organization_id)
156
+ self._service = ServiceResource(self._http, self._cfg.organization_id)
157
+ self._conversation = ConversationResource(self._http, self._cfg.organization_id)
158
+ self._users = UserResource(self._http, self._cfg.organization_id)
159
+
160
+ @property
161
+ def config(self) -> AmigoConfig:
162
+ return self._cfg
163
+
164
+ @property
165
+ def organization(self) -> OrganizationResource:
166
+ return self._organization
167
+
168
+ @property
169
+ def service(self) -> ServiceResource:
170
+ return self._service
171
+
172
+ @property
173
+ def conversation(self) -> ConversationResource:
174
+ return self._conversation
175
+
176
+ @property
177
+ def users(self) -> UserResource:
178
+ return self._users
179
+
180
+ def aclose(self) -> None:
181
+ self._http.aclose()
182
+
183
+ def __enter__(self):
184
+ return self
185
+
186
+ def __exit__(self, *_):
187
+ self.aclose()
@@ -0,0 +1,260 @@
1
+ Metadata-Version: 2.4
2
+ Name: amigo_sdk
3
+ Version: 0.62.0
4
+ Summary: Amigo AI Python SDK
5
+ Author: Amigo AI
6
+ License-File: LICENSE
7
+ Classifier: Programming Language :: Python :: 3
8
+ Requires-Python: >=3.9
9
+ Requires-Dist: email-validator<3.0,>=2.0
10
+ Requires-Dist: httpx<1.0,>=0.25
11
+ Requires-Dist: pydantic-settings<3.0,>=2.0
12
+ Requires-Dist: pydantic<3.0,>=2.7
13
+ Provides-Extra: dev
14
+ Requires-Dist: datamodel-code-generator[http]<1.0,>=0.21; extra == 'dev'
15
+ Requires-Dist: pytest-asyncio<1.0,>=0.21; extra == 'dev'
16
+ Requires-Dist: pytest-cov<6.0,>=4.0; extra == 'dev'
17
+ Requires-Dist: pytest-httpx<1.0,>=0.30; extra == 'dev'
18
+ Requires-Dist: pytest<9.0,>=7.0; extra == 'dev'
19
+ Requires-Dist: python-dotenv<2.0,>=1.0; extra == 'dev'
20
+ Requires-Dist: ruff<1.0,>=0.1; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Amigo Python SDK
24
+
25
+ [![Tests](https://github.com/amigo-ai/amigo-python-sdk/actions/workflows/test.yml/badge.svg)](https://github.com/amigo-ai/amigo-python-sdk/actions/workflows/test.yml)
26
+ [![codecov](https://codecov.io/gh/amigo-ai/amigo-python-sdk/graph/badge.svg?token=1A7KVPV9ZR)](https://codecov.io/gh/amigo-ai/amigo-python-sdk)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
28
+
29
+ The official Python SDK for the Amigo API, providing a simple and intuitive interface to interact with Amigo's AI services.
30
+
31
+ ## Installation
32
+
33
+ Install the SDK using pip:
34
+
35
+ ```bash
36
+ pip install amigo_sdk
37
+ ```
38
+
39
+ Or add it to your requirements.txt:
40
+
41
+ ```txt
42
+ amigo_sdk
43
+ ```
44
+
45
+ ### API compatibility
46
+
47
+ This SDK auto-generates its types from the latest [Amigo OpenAPI schema](https://api.amigo.ai/v1/openapi.json). As a result, only the latest published SDK version is guaranteed to match the current API. If you pin to an older version, it may not include the newest endpoints or fields.
48
+
49
+ ## Quick Start (sync)
50
+
51
+ ```python
52
+ from amigo_sdk import AmigoClient
53
+ from amigo_sdk.models import GetConversationsParametersQuery
54
+
55
+ # Initialize and use the client synchronously
56
+ with AmigoClient(
57
+ api_key="your-api-key",
58
+ api_key_id="your-api-key-id",
59
+ user_id="user-id",
60
+ organization_id="your-organization-id",
61
+ ) as client:
62
+ conversations = client.conversation.get_conversations(
63
+ GetConversationsParametersQuery(limit=10, sort_by=["-created_at"])
64
+ )
65
+ print("Conversations:", conversations)
66
+ ```
67
+
68
+ ## Quick Start (async)
69
+
70
+ ```python
71
+ import asyncio
72
+
73
+ from amigo_sdk import AsyncAmigoClient
74
+ from amigo_sdk.models import GetConversationsParametersQuery
75
+
76
+
77
+ async def main():
78
+ async with AsyncAmigoClient(
79
+ api_key="your-api-key",
80
+ api_key_id="your-api-key-id",
81
+ user_id="user-id",
82
+ organization_id="your-organization-id",
83
+ ) as client:
84
+ conversations = await client.conversation.get_conversations(
85
+ GetConversationsParametersQuery(limit=10, sort_by=["-created_at"])
86
+ )
87
+ print("Conversations:", conversations)
88
+
89
+
90
+ asyncio.run(main())
91
+ ```
92
+
93
+ ## Examples
94
+
95
+ For more SDK usage examples see the [examples overview](examples/README.md). Direct links:
96
+
97
+ - **Conversation (sync)**: [examples/conversation/conversation.py](examples/conversation/conversation.py)
98
+ - **Conversation (async)**: [examples/conversation/conversation_async.py](examples/conversation/conversation_async.py)
99
+ - **User management (sync)**: [examples/user/user-management.py](examples/user/user-management.py)
100
+
101
+ ## Configuration
102
+
103
+ The SDK requires the following configuration parameters:
104
+
105
+ | Parameter | Type | Required | Description |
106
+ | ----------------- | ---- | -------- | -------------------------------------------------------------- |
107
+ | `api_key` | str | ✅ | API key from Amigo dashboard |
108
+ | `api_key_id` | str | ✅ | API key ID from Amigo dashboard |
109
+ | `user_id` | str | ✅ | User ID on whose behalf the request is made |
110
+ | `organization_id` | str | ✅ | Your organization ID |
111
+ | `base_url` | str | ❌ | Base URL of the Amigo API (defaults to `https://api.amigo.ai`) |
112
+
113
+ ### Environment Variables
114
+
115
+ You can also configure the SDK using environment variables:
116
+
117
+ ```bash
118
+ export AMIGO_API_KEY="your-api-key"
119
+ export AMIGO_API_KEY_ID="your-api-key-id"
120
+ export AMIGO_USER_ID="user-id"
121
+ export AMIGO_ORGANIZATION_ID="your-organization-id"
122
+ export AMIGO_BASE_URL="https://api.amigo.ai" # optional
123
+ ```
124
+
125
+ Then initialize the client without parameters:
126
+
127
+ ```python
128
+ from amigo_sdk import AmigoClient
129
+
130
+ # Automatically loads from environment variables
131
+ with AmigoClient() as client:
132
+ ...
133
+ ```
134
+
135
+ ### Using .env Files
136
+
137
+ Create a `.env` file in your project root:
138
+
139
+ ```env
140
+ AMIGO_API_KEY=your-api-key
141
+ AMIGO_API_KEY_ID=your-api-key-id
142
+ AMIGO_USER_ID=user-id
143
+ AMIGO_ORG_ID=your-organization-id
144
+ ```
145
+
146
+ The SDK will automatically load these variables.
147
+
148
+ ### Getting Your API Credentials
149
+
150
+ 1. **API Key & API Key ID**: Generate these from your Amigo admin dashboard or programmatically using the API
151
+ 2. **Organization ID**: Found in your Amigo dashboard URL or organization settings
152
+ 3. **User ID**: The ID of the user you want to impersonate for API calls
153
+
154
+ For detailed instructions on generating API keys, see the [Authentication Guide](https://docs.amigo.ai/developer-guide).
155
+
156
+ ## Available Resources
157
+
158
+ The SDK provides access to the following resources:
159
+
160
+ - **Organizations**: Get Organization info
161
+ - **Services**: Get available services
162
+ - **Conversation**: Manage conversations
163
+ - **User**: Manage users
164
+
165
+ ## Generated types
166
+
167
+ The SDK ships with Pydantic models generated from the latest OpenAPI schema.
168
+
169
+ - **Importing types**: Import directly from `amigo_sdk.models`
170
+
171
+ ```python
172
+ from amigo_sdk.models import (
173
+ GetConversationsParametersQuery,
174
+ ConversationCreateConversationRequest,
175
+ GetUsersParametersQuery,
176
+ )
177
+ ```
178
+
179
+ - **Using types when calling SDK functions**: Pass request/query models to resource methods.
180
+
181
+ ```python
182
+ from amigo_sdk import AmigoClient
183
+ from amigo_sdk.models import GetConversationsParametersQuery
184
+
185
+ with AmigoClient() as client:
186
+ conversations = client.conversation.get_conversations(
187
+ GetConversationsParametersQuery(limit=20, sort_by=["-created_at"])
188
+ )
189
+ ```
190
+
191
+ - **Parsing returned objects**: Responses are Pydantic models. Access fields directly or convert to dict/JSON.
192
+
193
+ ```python
194
+ # Access fields
195
+ first = conversations.conversations[0]
196
+ print(first.id, first.created_at)
197
+
198
+ # Convert to plain dict for logging/serialization
199
+ print(first.model_dump(mode="json"))
200
+ ```
201
+
202
+ ## Error Handling
203
+
204
+ The SDK provides typed error handling:
205
+
206
+ ```python
207
+ from amigo_sdk import AmigoClient
208
+ from amigo_sdk.errors import (
209
+ AuthenticationError,
210
+ NotFoundError,
211
+ BadRequestError,
212
+ ValidationError,
213
+ )
214
+
215
+ try:
216
+ with AmigoClient() as client:
217
+ org = client.organization.get()
218
+ print("Organization:", org)
219
+ except AuthenticationError as error:
220
+ print("Authentication failed:", error)
221
+ except NotFoundError as error:
222
+ print("Resource not found:", error)
223
+ except BadRequestError as error:
224
+ print("Bad request:", error)
225
+ except ValidationError as error:
226
+ print("Validation error:", error)
227
+ except Exception as error:
228
+ print("Unexpected error:", error)
229
+ ```
230
+
231
+ ## Retries
232
+
233
+ The HTTP client includes sensible, configurable retries:
234
+
235
+ - **Defaults**:
236
+
237
+ - max attempts: 3
238
+ - backoff base: 0.25s (exponential with full jitter)
239
+ - max delay per attempt: 30s
240
+ - retry on status: {408, 429, 500, 502, 503, 504}
241
+ - retry on methods: {"GET"}
242
+ - special-case: POST is retried on 429 when `Retry-After` is present
243
+ - 401 triggers a one-time token refresh and immediate retry
244
+
245
+ ## Development
246
+
247
+ For detailed development setup, testing, and contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).
248
+
249
+ ## Documentation
250
+
251
+ - **Developer Guide**: [https://docs.amigo.ai/developer-guide](https://docs.amigo.ai/developer-guide)
252
+ - **API Reference**: [https://docs.amigo.ai/api-reference](https://docs.amigo.ai/api-reference)
253
+
254
+ ## License
255
+
256
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
257
+
258
+ ## Support
259
+
260
+ For questions, issues, or feature requests, please visit our [GitHub repository](https://github.com/amigo-ai/amigo-python-sdk) or contact support through the Amigo dashboard.
@@ -0,0 +1,18 @@
1
+ amigo_sdk/__init__.py,sha256=GZ5tgkehgZLTftN7G8oWMY409UKDEoyw5Ov15xnGrhA,139
2
+ amigo_sdk/_retry_utils.py,sha256=kFjw9Wqye6MB5-B4rjLxsbSNcfYBIztcollIoncd1hY,2142
3
+ amigo_sdk/auth.py,sha256=WaM9PcEcnaC6CzNsgRKueHkdSAxNbRylzpR_3Q6guQ0,1765
4
+ amigo_sdk/config.py,sha256=0eZIo-hcJ8ODftKAr-mwB-FGJxGO5PT5T4dRpyWPqAg,1491
5
+ amigo_sdk/errors.py,sha256=RkRyF5eAASd8fIOS6YvL9rLDvLAYWqHfpHSCR7jqvl4,4840
6
+ amigo_sdk/http_client.py,sha256=v25UoUbXcMeHTnfJMcrl8RSSwCVkKUL1Jv-0HoXP1B4,13507
7
+ amigo_sdk/models.py,sha256=V-G6iL43_ZNOPDcatCJCSszGWGz-nzp_RSyGNm-rBAc,45
8
+ amigo_sdk/sdk_client.py,sha256=Kr9M9o66pOLu0T2VDvqdYMmPZzgKJyTELu7BSPgGrYQ,6152
9
+ amigo_sdk/generated/model.py,sha256=ENsXrhwNVu19tI4sm0olpu-IHnNKPIoeZNwlgWS6uug,453904
10
+ amigo_sdk/resources/conversation.py,sha256=5PkJOvLKqnriSS9K9hKw2VRPxRLTuABEbCyPy1fz1r0,14817
11
+ amigo_sdk/resources/organization.py,sha256=yX4UlOHNegRzFW4gCJrCxjiLCAGnGegasjviR1yad_Q,1211
12
+ amigo_sdk/resources/service.py,sha256=SiwEHXCQk4r1b_tGv47M08VuB7RALDHJQzWlpuD937g,1571
13
+ amigo_sdk/resources/user.py,sha256=vZPCw8i-xvcDQik8ouJbm8qVHucRbfxCWI3yYMDj8hg,3517
14
+ amigo_sdk-0.62.0.dist-info/METADATA,sha256=YJO7UIpXJOjK9ow0s8tRVDjuzo1OKMXgdUkK2QR8l1o,8350
15
+ amigo_sdk-0.62.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ amigo_sdk-0.62.0.dist-info/entry_points.txt,sha256=ivKZ8S9W6SH796zUDHeM-qHodrwmkmUItophi-jJWK0,82
17
+ amigo_sdk-0.62.0.dist-info/licenses/LICENSE,sha256=tx3FiTVbGxwBUOxQbNh05AAQlC2jd5hGvNpIkSfVbCo,1062
18
+ amigo_sdk-0.62.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ check = scripts.check:main
3
+ gen-models = scripts.gen_models:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Amigo
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.