deepailab 0.2.0b1__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.
- deepailab-0.2.0b1/.gitignore +7 -0
- deepailab-0.2.0b1/PKG-INFO +362 -0
- deepailab-0.2.0b1/README.md +311 -0
- deepailab-0.2.0b1/pyproject.toml +192 -0
- deepailab-0.2.0b1/src/deepailab/__init__.py +142 -0
- deepailab-0.2.0b1/src/deepailab/auth.py +369 -0
- deepailab-0.2.0b1/src/deepailab/client.py +1075 -0
- deepailab-0.2.0b1/src/deepailab/exceptions.py +280 -0
- deepailab-0.2.0b1/src/deepailab/portal.py +86 -0
- deepailab-0.2.0b1/src/deepailab/types.py +194 -0
- deepailab-0.2.0b1/tests/test_auth.py +164 -0
- deepailab-0.2.0b1/tests/test_client.py +255 -0
- deepailab-0.2.0b1/tests/test_contract.py +549 -0
- deepailab-0.2.0b1/tests/test_coverage_enhancement.py +178 -0
- deepailab-0.2.0b1/tests/test_e2e.py +609 -0
- deepailab-0.2.0b1/tests/test_portal.py +57 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepailab
|
|
3
|
+
Version: 0.2.0b1
|
|
4
|
+
Summary: Official Python SDK for DeepAI Lab API
|
|
5
|
+
Project-URL: Homepage, https://docs.deepailab.ai/sdk/python
|
|
6
|
+
Project-URL: Documentation, https://docs.deepailab.ai/sdk/python
|
|
7
|
+
Project-URL: Repository, https://github.com/deepailab/deepailab-sdk-python
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/deepailab/deepailab-sdk-python/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/deepailab/deepailab-sdk-python/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: DeepAI Lab <sdk@deepailab.ai>
|
|
11
|
+
Maintainer-email: DeepAI Lab <sdk@deepailab.ai>
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
Keywords: ai,api,deepailab,embeddings,llm,openai,python,sdk
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Requires-Dist: httpx>=0.24.0
|
|
28
|
+
Requires-Dist: pydantic>=2.0.0
|
|
29
|
+
Requires-Dist: typing-extensions>=4.5.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: flake8>=6.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: isort>=5.12.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
40
|
+
Provides-Extra: docs
|
|
41
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.22.0; extra == 'docs'
|
|
42
|
+
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == 'docs'
|
|
43
|
+
Requires-Dist: sphinx>=6.0.0; extra == 'docs'
|
|
44
|
+
Provides-Extra: test
|
|
45
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
|
|
46
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
|
|
47
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'test'
|
|
48
|
+
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
|
49
|
+
Requires-Dist: respx>=0.20.0; extra == 'test'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
# DeepAI Lab Python SDK
|
|
53
|
+
|
|
54
|
+
[](https://badge.fury.io/py/deepailab)
|
|
55
|
+
[](https://github.com/deepailab/deepailab-sdk-python/actions)
|
|
56
|
+
[](https://codecov.io/gh/deepailab/deepailab-sdk-python)
|
|
57
|
+
|
|
58
|
+
Official Python SDK for the DeepAI Lab API platform. Supports OpenAI-compatible endpoints, model marketplace, and enterprise features.
|
|
59
|
+
|
|
60
|
+
## ๐ Quick Start (30 seconds)
|
|
61
|
+
|
|
62
|
+
### Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install deepailab
|
|
66
|
+
# or
|
|
67
|
+
poetry add deepailab
|
|
68
|
+
# or
|
|
69
|
+
pipenv install deepailab
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Basic Usage
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import deepailab
|
|
76
|
+
|
|
77
|
+
client = deepailab.DeepAILab(
|
|
78
|
+
api_key="sk-deepailab-your-api-key-here",
|
|
79
|
+
# base_url="https://api.deepailab.ai" # Optional, defaults to production
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Chat completion
|
|
83
|
+
response = client.chat.completions.create(
|
|
84
|
+
model="gpt-4o",
|
|
85
|
+
messages=[
|
|
86
|
+
{"role": "user", "content": "Hello, world!"}
|
|
87
|
+
],
|
|
88
|
+
max_tokens=100
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
print(response.choices[0].message.content)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## ๐ Features
|
|
95
|
+
|
|
96
|
+
- โ
**OpenAI Compatible**: Drop-in replacement for OpenAI SDK
|
|
97
|
+
- โ
**Type Hints**: Full type safety with mypy support
|
|
98
|
+
- โ
**Async/Await**: Native asyncio support
|
|
99
|
+
- โ
**Streaming**: Server-sent events (SSE) support
|
|
100
|
+
- โ
**Error Handling**: Comprehensive exception types and retry logic
|
|
101
|
+
- โ
**Rate Limiting**: Built-in exponential backoff
|
|
102
|
+
- โ
**Observability**: Request metrics and cost tracking
|
|
103
|
+
- โ
**Multi-tenancy**: On-behalf-of (OBO) support
|
|
104
|
+
- โ
**Model Marketplace**: Access to user-published models
|
|
105
|
+
- โ
**Context Managers**: Automatic resource cleanup
|
|
106
|
+
- โ
**Cancellation**: asyncio.CancelledError support
|
|
107
|
+
|
|
108
|
+
## ๐ง API Reference
|
|
109
|
+
|
|
110
|
+
### Chat Completions
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# Synchronous
|
|
114
|
+
response = client.chat.completions.create(
|
|
115
|
+
model="gpt-4o",
|
|
116
|
+
messages=[
|
|
117
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
118
|
+
{"role": "user", "content": "Explain quantum computing"}
|
|
119
|
+
],
|
|
120
|
+
max_tokens=500,
|
|
121
|
+
temperature=0.7
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Asynchronous
|
|
125
|
+
import asyncio
|
|
126
|
+
|
|
127
|
+
async def main():
|
|
128
|
+
async with deepailab.AsyncDeepAILab(api_key="your-key") as client:
|
|
129
|
+
response = await client.chat.completions.create(
|
|
130
|
+
model="gpt-4o",
|
|
131
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
132
|
+
)
|
|
133
|
+
print(response.choices[0].message.content)
|
|
134
|
+
|
|
135
|
+
asyncio.run(main())
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Streaming
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
# Synchronous streaming
|
|
142
|
+
stream = client.chat.completions.create(
|
|
143
|
+
model="gpt-4o",
|
|
144
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
145
|
+
stream=True
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
for chunk in stream:
|
|
149
|
+
content = chunk.choices[0].delta.content
|
|
150
|
+
if content:
|
|
151
|
+
print(content, end="", flush=True)
|
|
152
|
+
|
|
153
|
+
# Asynchronous streaming
|
|
154
|
+
async def stream_example():
|
|
155
|
+
async with deepailab.AsyncDeepAILab(api_key="your-key") as client:
|
|
156
|
+
stream = await client.chat.completions.create(
|
|
157
|
+
model="gpt-4o",
|
|
158
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
159
|
+
stream=True
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
async for chunk in stream:
|
|
163
|
+
content = chunk.choices[0].delta.content
|
|
164
|
+
if content:
|
|
165
|
+
print(content, end="", flush=True)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Embeddings
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
response = client.embeddings.create(
|
|
172
|
+
model="text-embedding-3-large",
|
|
173
|
+
input=["Hello world", "How are you?"]
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
print(response.data[0].embedding) # [0.1, 0.2, ...]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Models
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
models = client.models.list()
|
|
183
|
+
for model in models.data:
|
|
184
|
+
print(f"{model.id}: {model.owned_by}")
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Model Marketplace
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
# Call a user-published model
|
|
191
|
+
result = client.model_gateway.infer(
|
|
192
|
+
user_id="user123",
|
|
193
|
+
model_id="my-model",
|
|
194
|
+
input={"text": "Analyze this sentiment"},
|
|
195
|
+
parameters={"temperature": 0.5}
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Batch processing
|
|
199
|
+
batch = client.model_gateway.batch(
|
|
200
|
+
user_id="user123",
|
|
201
|
+
model_id="my-model",
|
|
202
|
+
input_file_id="file-abc123",
|
|
203
|
+
endpoint="/v1/inference"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Check model status
|
|
207
|
+
status = client.model_gateway.status("user123", "my-model")
|
|
208
|
+
print(status.status) # 'deployed' | 'deploying' | 'failed' | 'maintenance'
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### On-Behalf-Of (Multi-tenancy)
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# Make requests on behalf of end users
|
|
215
|
+
obo_client = client.as_user(
|
|
216
|
+
user="end-user-123",
|
|
217
|
+
tenant="organization-456"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
response = obo_client.chat.completions.create(
|
|
221
|
+
model="gpt-4o",
|
|
222
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
223
|
+
)
|
|
224
|
+
# Usage will be attributed to end-user-123 and organization-456
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## ๐ Security Best Practices
|
|
228
|
+
|
|
229
|
+
### Environment Variables
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
import os
|
|
233
|
+
import deepailab
|
|
234
|
+
|
|
235
|
+
# โ
Use environment variables
|
|
236
|
+
client = deepailab.DeepAILab(
|
|
237
|
+
api_key=os.getenv("DEEPAILAB_API_KEY")
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# โ
Or use a .env file with python-dotenv
|
|
241
|
+
from dotenv import load_dotenv
|
|
242
|
+
load_dotenv()
|
|
243
|
+
|
|
244
|
+
client = deepailab.DeepAILab(
|
|
245
|
+
api_key=os.getenv("DEEPAILAB_API_KEY")
|
|
246
|
+
)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Session Tokens for Web Apps
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
# For web applications, use short-lived session tokens
|
|
253
|
+
def get_session_token(user_jwt: str) -> str:
|
|
254
|
+
"""Get a short-lived session token from your auth service."""
|
|
255
|
+
# Your implementation here
|
|
256
|
+
pass
|
|
257
|
+
|
|
258
|
+
client = deepailab.DeepAILab(
|
|
259
|
+
api_key=get_session_token(user_jwt) # Short-lived token
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## ๐ Observability & Metrics
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
def metrics_callback(metrics):
|
|
267
|
+
print(f"Request ID: {metrics.request_id}")
|
|
268
|
+
print(f"Response Time: {metrics.response_time}ms")
|
|
269
|
+
print(f"Tokens Used: {metrics.usage.total_tokens}")
|
|
270
|
+
print(f"Cost: {metrics.cost.amount} {metrics.cost.currency}")
|
|
271
|
+
|
|
272
|
+
client = deepailab.DeepAILab(
|
|
273
|
+
api_key="your-key",
|
|
274
|
+
on_metrics=metrics_callback
|
|
275
|
+
)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## ๐ Error Handling & Retries
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
import deepailab
|
|
282
|
+
from deepailab import (
|
|
283
|
+
RateLimitError,
|
|
284
|
+
AuthenticationError,
|
|
285
|
+
TimeoutError,
|
|
286
|
+
ValidationError
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
try:
|
|
290
|
+
response = client.chat.completions.create(
|
|
291
|
+
model="gpt-4o",
|
|
292
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
293
|
+
)
|
|
294
|
+
except RateLimitError as e:
|
|
295
|
+
print(f"Rate limited. Retry after: {e.retry_after}")
|
|
296
|
+
except AuthenticationError:
|
|
297
|
+
print("Invalid API key")
|
|
298
|
+
except TimeoutError:
|
|
299
|
+
print("Request timed out")
|
|
300
|
+
except ValidationError as e:
|
|
301
|
+
print(f"Validation error: {e.message}")
|
|
302
|
+
except deepailab.DeepAILabError as e:
|
|
303
|
+
print(f"Other error: {e}")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## ๐ง Configuration
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
client = deepailab.DeepAILab(
|
|
310
|
+
api_key="your-key",
|
|
311
|
+
base_url="https://api.deepailab.ai", # Custom base URL
|
|
312
|
+
timeout=30.0, # Request timeout in seconds
|
|
313
|
+
max_retries=3, # Maximum retry attempts
|
|
314
|
+
default_headers={"User-Agent": "MyApp/1.0"}, # Custom headers
|
|
315
|
+
debug=True # Enable debug logging
|
|
316
|
+
)
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## ๐งช Testing
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
# Use the test client for unit tests
|
|
323
|
+
from deepailab.testing import MockDeepAILab
|
|
324
|
+
|
|
325
|
+
def test_chat_completion():
|
|
326
|
+
client = MockDeepAILab()
|
|
327
|
+
client.mock_response("chat.completions.create", {
|
|
328
|
+
"choices": [{"message": {"content": "Hello!"}}]
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
response = client.chat.completions.create(
|
|
332
|
+
model="gpt-4o",
|
|
333
|
+
messages=[{"role": "user", "content": "Hi"}]
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
assert response.choices[0].message.content == "Hello!"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## ๐ More Examples
|
|
340
|
+
|
|
341
|
+
- [Synchronous Example](./examples/sync.py)
|
|
342
|
+
- [Asynchronous Example](./examples/async.py)
|
|
343
|
+
- [Streaming Example](./examples/streaming.py)
|
|
344
|
+
- [Model Marketplace Example](./examples/marketplace.py)
|
|
345
|
+
- [On-Behalf-Of Example](./examples/obo.py)
|
|
346
|
+
- [Django Integration](./examples/django_integration.py)
|
|
347
|
+
- [FastAPI Integration](./examples/fastapi_integration.py)
|
|
348
|
+
|
|
349
|
+
## ๐ค Contributing
|
|
350
|
+
|
|
351
|
+
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
352
|
+
|
|
353
|
+
## ๐ License
|
|
354
|
+
|
|
355
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|
|
356
|
+
|
|
357
|
+
## ๐ Support
|
|
358
|
+
|
|
359
|
+
- ๐ [Documentation](https://docs.deepailab.ai/sdk/python)
|
|
360
|
+
- ๐ [Bug Reports](https://github.com/deepailab/deepailab-sdk-python/issues)
|
|
361
|
+
- ๐ฌ [Discord Community](https://discord.gg/deepailab)
|
|
362
|
+
- ๐ง [Email Support](mailto:sdk@deepailab.ai)
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# DeepAI Lab Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/deepailab)
|
|
4
|
+
[](https://github.com/deepailab/deepailab-sdk-python/actions)
|
|
5
|
+
[](https://codecov.io/gh/deepailab/deepailab-sdk-python)
|
|
6
|
+
|
|
7
|
+
Official Python SDK for the DeepAI Lab API platform. Supports OpenAI-compatible endpoints, model marketplace, and enterprise features.
|
|
8
|
+
|
|
9
|
+
## ๐ Quick Start (30 seconds)
|
|
10
|
+
|
|
11
|
+
### Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install deepailab
|
|
15
|
+
# or
|
|
16
|
+
poetry add deepailab
|
|
17
|
+
# or
|
|
18
|
+
pipenv install deepailab
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Basic Usage
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import deepailab
|
|
25
|
+
|
|
26
|
+
client = deepailab.DeepAILab(
|
|
27
|
+
api_key="sk-deepailab-your-api-key-here",
|
|
28
|
+
# base_url="https://api.deepailab.ai" # Optional, defaults to production
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Chat completion
|
|
32
|
+
response = client.chat.completions.create(
|
|
33
|
+
model="gpt-4o",
|
|
34
|
+
messages=[
|
|
35
|
+
{"role": "user", "content": "Hello, world!"}
|
|
36
|
+
],
|
|
37
|
+
max_tokens=100
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
print(response.choices[0].message.content)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## ๐ Features
|
|
44
|
+
|
|
45
|
+
- โ
**OpenAI Compatible**: Drop-in replacement for OpenAI SDK
|
|
46
|
+
- โ
**Type Hints**: Full type safety with mypy support
|
|
47
|
+
- โ
**Async/Await**: Native asyncio support
|
|
48
|
+
- โ
**Streaming**: Server-sent events (SSE) support
|
|
49
|
+
- โ
**Error Handling**: Comprehensive exception types and retry logic
|
|
50
|
+
- โ
**Rate Limiting**: Built-in exponential backoff
|
|
51
|
+
- โ
**Observability**: Request metrics and cost tracking
|
|
52
|
+
- โ
**Multi-tenancy**: On-behalf-of (OBO) support
|
|
53
|
+
- โ
**Model Marketplace**: Access to user-published models
|
|
54
|
+
- โ
**Context Managers**: Automatic resource cleanup
|
|
55
|
+
- โ
**Cancellation**: asyncio.CancelledError support
|
|
56
|
+
|
|
57
|
+
## ๐ง API Reference
|
|
58
|
+
|
|
59
|
+
### Chat Completions
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# Synchronous
|
|
63
|
+
response = client.chat.completions.create(
|
|
64
|
+
model="gpt-4o",
|
|
65
|
+
messages=[
|
|
66
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
67
|
+
{"role": "user", "content": "Explain quantum computing"}
|
|
68
|
+
],
|
|
69
|
+
max_tokens=500,
|
|
70
|
+
temperature=0.7
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Asynchronous
|
|
74
|
+
import asyncio
|
|
75
|
+
|
|
76
|
+
async def main():
|
|
77
|
+
async with deepailab.AsyncDeepAILab(api_key="your-key") as client:
|
|
78
|
+
response = await client.chat.completions.create(
|
|
79
|
+
model="gpt-4o",
|
|
80
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
81
|
+
)
|
|
82
|
+
print(response.choices[0].message.content)
|
|
83
|
+
|
|
84
|
+
asyncio.run(main())
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Streaming
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# Synchronous streaming
|
|
91
|
+
stream = client.chat.completions.create(
|
|
92
|
+
model="gpt-4o",
|
|
93
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
94
|
+
stream=True
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
for chunk in stream:
|
|
98
|
+
content = chunk.choices[0].delta.content
|
|
99
|
+
if content:
|
|
100
|
+
print(content, end="", flush=True)
|
|
101
|
+
|
|
102
|
+
# Asynchronous streaming
|
|
103
|
+
async def stream_example():
|
|
104
|
+
async with deepailab.AsyncDeepAILab(api_key="your-key") as client:
|
|
105
|
+
stream = await client.chat.completions.create(
|
|
106
|
+
model="gpt-4o",
|
|
107
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
108
|
+
stream=True
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
async for chunk in stream:
|
|
112
|
+
content = chunk.choices[0].delta.content
|
|
113
|
+
if content:
|
|
114
|
+
print(content, end="", flush=True)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Embeddings
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
response = client.embeddings.create(
|
|
121
|
+
model="text-embedding-3-large",
|
|
122
|
+
input=["Hello world", "How are you?"]
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
print(response.data[0].embedding) # [0.1, 0.2, ...]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Models
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
models = client.models.list()
|
|
132
|
+
for model in models.data:
|
|
133
|
+
print(f"{model.id}: {model.owned_by}")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Model Marketplace
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Call a user-published model
|
|
140
|
+
result = client.model_gateway.infer(
|
|
141
|
+
user_id="user123",
|
|
142
|
+
model_id="my-model",
|
|
143
|
+
input={"text": "Analyze this sentiment"},
|
|
144
|
+
parameters={"temperature": 0.5}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Batch processing
|
|
148
|
+
batch = client.model_gateway.batch(
|
|
149
|
+
user_id="user123",
|
|
150
|
+
model_id="my-model",
|
|
151
|
+
input_file_id="file-abc123",
|
|
152
|
+
endpoint="/v1/inference"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Check model status
|
|
156
|
+
status = client.model_gateway.status("user123", "my-model")
|
|
157
|
+
print(status.status) # 'deployed' | 'deploying' | 'failed' | 'maintenance'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### On-Behalf-Of (Multi-tenancy)
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# Make requests on behalf of end users
|
|
164
|
+
obo_client = client.as_user(
|
|
165
|
+
user="end-user-123",
|
|
166
|
+
tenant="organization-456"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
response = obo_client.chat.completions.create(
|
|
170
|
+
model="gpt-4o",
|
|
171
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
172
|
+
)
|
|
173
|
+
# Usage will be attributed to end-user-123 and organization-456
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## ๐ Security Best Practices
|
|
177
|
+
|
|
178
|
+
### Environment Variables
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
import os
|
|
182
|
+
import deepailab
|
|
183
|
+
|
|
184
|
+
# โ
Use environment variables
|
|
185
|
+
client = deepailab.DeepAILab(
|
|
186
|
+
api_key=os.getenv("DEEPAILAB_API_KEY")
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# โ
Or use a .env file with python-dotenv
|
|
190
|
+
from dotenv import load_dotenv
|
|
191
|
+
load_dotenv()
|
|
192
|
+
|
|
193
|
+
client = deepailab.DeepAILab(
|
|
194
|
+
api_key=os.getenv("DEEPAILAB_API_KEY")
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Session Tokens for Web Apps
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
# For web applications, use short-lived session tokens
|
|
202
|
+
def get_session_token(user_jwt: str) -> str:
|
|
203
|
+
"""Get a short-lived session token from your auth service."""
|
|
204
|
+
# Your implementation here
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
client = deepailab.DeepAILab(
|
|
208
|
+
api_key=get_session_token(user_jwt) # Short-lived token
|
|
209
|
+
)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## ๐ Observability & Metrics
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
def metrics_callback(metrics):
|
|
216
|
+
print(f"Request ID: {metrics.request_id}")
|
|
217
|
+
print(f"Response Time: {metrics.response_time}ms")
|
|
218
|
+
print(f"Tokens Used: {metrics.usage.total_tokens}")
|
|
219
|
+
print(f"Cost: {metrics.cost.amount} {metrics.cost.currency}")
|
|
220
|
+
|
|
221
|
+
client = deepailab.DeepAILab(
|
|
222
|
+
api_key="your-key",
|
|
223
|
+
on_metrics=metrics_callback
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## ๐ Error Handling & Retries
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
import deepailab
|
|
231
|
+
from deepailab import (
|
|
232
|
+
RateLimitError,
|
|
233
|
+
AuthenticationError,
|
|
234
|
+
TimeoutError,
|
|
235
|
+
ValidationError
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
response = client.chat.completions.create(
|
|
240
|
+
model="gpt-4o",
|
|
241
|
+
messages=[{"role": "user", "content": "Hello"}]
|
|
242
|
+
)
|
|
243
|
+
except RateLimitError as e:
|
|
244
|
+
print(f"Rate limited. Retry after: {e.retry_after}")
|
|
245
|
+
except AuthenticationError:
|
|
246
|
+
print("Invalid API key")
|
|
247
|
+
except TimeoutError:
|
|
248
|
+
print("Request timed out")
|
|
249
|
+
except ValidationError as e:
|
|
250
|
+
print(f"Validation error: {e.message}")
|
|
251
|
+
except deepailab.DeepAILabError as e:
|
|
252
|
+
print(f"Other error: {e}")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## ๐ง Configuration
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
client = deepailab.DeepAILab(
|
|
259
|
+
api_key="your-key",
|
|
260
|
+
base_url="https://api.deepailab.ai", # Custom base URL
|
|
261
|
+
timeout=30.0, # Request timeout in seconds
|
|
262
|
+
max_retries=3, # Maximum retry attempts
|
|
263
|
+
default_headers={"User-Agent": "MyApp/1.0"}, # Custom headers
|
|
264
|
+
debug=True # Enable debug logging
|
|
265
|
+
)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## ๐งช Testing
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
# Use the test client for unit tests
|
|
272
|
+
from deepailab.testing import MockDeepAILab
|
|
273
|
+
|
|
274
|
+
def test_chat_completion():
|
|
275
|
+
client = MockDeepAILab()
|
|
276
|
+
client.mock_response("chat.completions.create", {
|
|
277
|
+
"choices": [{"message": {"content": "Hello!"}}]
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
response = client.chat.completions.create(
|
|
281
|
+
model="gpt-4o",
|
|
282
|
+
messages=[{"role": "user", "content": "Hi"}]
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
assert response.choices[0].message.content == "Hello!"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## ๐ More Examples
|
|
289
|
+
|
|
290
|
+
- [Synchronous Example](./examples/sync.py)
|
|
291
|
+
- [Asynchronous Example](./examples/async.py)
|
|
292
|
+
- [Streaming Example](./examples/streaming.py)
|
|
293
|
+
- [Model Marketplace Example](./examples/marketplace.py)
|
|
294
|
+
- [On-Behalf-Of Example](./examples/obo.py)
|
|
295
|
+
- [Django Integration](./examples/django_integration.py)
|
|
296
|
+
- [FastAPI Integration](./examples/fastapi_integration.py)
|
|
297
|
+
|
|
298
|
+
## ๐ค Contributing
|
|
299
|
+
|
|
300
|
+
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
301
|
+
|
|
302
|
+
## ๐ License
|
|
303
|
+
|
|
304
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|
|
305
|
+
|
|
306
|
+
## ๐ Support
|
|
307
|
+
|
|
308
|
+
- ๐ [Documentation](https://docs.deepailab.ai/sdk/python)
|
|
309
|
+
- ๐ [Bug Reports](https://github.com/deepailab/deepailab-sdk-python/issues)
|
|
310
|
+
- ๐ฌ [Discord Community](https://discord.gg/deepailab)
|
|
311
|
+
- ๐ง [Email Support](mailto:sdk@deepailab.ai)
|