airia 0.1.4__tar.gz → 0.1.6__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.
- {airia-0.1.4 → airia-0.1.6}/PKG-INFO +126 -19
- {airia-0.1.4 → airia-0.1.6}/README.md +125 -18
- {airia-0.1.4 → airia-0.1.6}/airia/client/async_client.py +163 -29
- {airia-0.1.4 → airia-0.1.6}/airia/client/base_client.py +32 -1
- {airia-0.1.4 → airia-0.1.6}/airia/client/sync_client.py +140 -12
- airia-0.1.6/airia/types/__init__.py +71 -0
- airia-0.1.6/airia/types/api/get_pipeline_config.py +65 -0
- {airia-0.1.4/airia/types → airia-0.1.6/airia/types/api}/pipeline_execution.py +4 -2
- {airia-0.1.4 → airia-0.1.6}/airia/types/request_data.py +2 -2
- airia-0.1.6/airia/types/sse_messages.py +269 -0
- airia-0.1.6/airia/utils/sse_parser.py +91 -0
- {airia-0.1.4 → airia-0.1.6}/airia.egg-info/PKG-INFO +126 -19
- {airia-0.1.4 → airia-0.1.6}/airia.egg-info/SOURCES.txt +6 -1
- {airia-0.1.4 → airia-0.1.6}/pyproject.toml +1 -1
- {airia-0.1.4 → airia-0.1.6}/tests/test_anthropic_gateway.py +31 -18
- {airia-0.1.4 → airia-0.1.6}/tests/test_execute_pipeline.py +41 -48
- airia-0.1.6/tests/test_get_active_pipelines_ids.py +191 -0
- airia-0.1.6/tests/test_get_pipeline_config.py +394 -0
- {airia-0.1.4 → airia-0.1.6}/tests/test_openai_gateway.py +29 -18
- airia-0.1.4/airia/types/__init__.py +0 -19
- {airia-0.1.4 → airia-0.1.6}/LICENSE +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia/__init__.py +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia/client/__init__.py +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia/exceptions.py +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia/logs.py +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia/types/api_version.py +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia.egg-info/dependency_links.txt +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia.egg-info/requires.txt +0 -0
- {airia-0.1.4 → airia-0.1.6}/airia.egg-info/top_level.txt +0 -0
- {airia-0.1.4 → airia-0.1.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: airia
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Python SDK for Airia API
|
|
5
5
|
Author-email: Airia LLC <support@airia.com>
|
|
6
6
|
License: MIT
|
|
@@ -176,6 +176,20 @@ This will create both wheel and source distribution in the `dist/` directory.
|
|
|
176
176
|
|
|
177
177
|
## Quick Start
|
|
178
178
|
|
|
179
|
+
### Client Instantiation
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from airia import AiriaClient
|
|
183
|
+
|
|
184
|
+
client = AiriaClient(
|
|
185
|
+
base_url="https://api.airia.ai", # Default: "https://api.airia.ai"
|
|
186
|
+
api_key=None, # Or set AIRIA_API_KEY environment variable
|
|
187
|
+
timeout=30.0, # Request timeout in seconds (default: 30.0)
|
|
188
|
+
log_requests=False, # Enable request/response logging (default: False)
|
|
189
|
+
custom_logger=None # Use custom logger (default: None - uses built-in)
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
179
193
|
### Synchronous Usage
|
|
180
194
|
|
|
181
195
|
```python
|
|
@@ -208,8 +222,8 @@ response = client.execute_pipeline(
|
|
|
208
222
|
async_output=True
|
|
209
223
|
)
|
|
210
224
|
|
|
211
|
-
for c in
|
|
212
|
-
print(c
|
|
225
|
+
for c in response.stream:
|
|
226
|
+
print(c)
|
|
213
227
|
```
|
|
214
228
|
|
|
215
229
|
### Asynchronous Usage
|
|
@@ -219,13 +233,12 @@ import asyncio
|
|
|
219
233
|
from airia import AiriaAsyncClient
|
|
220
234
|
|
|
221
235
|
async def main():
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
print(response.result)
|
|
236
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
237
|
+
response = await client.execute_pipeline(
|
|
238
|
+
pipeline_id="your_pipeline_id",
|
|
239
|
+
user_input="Tell me about quantum computing"
|
|
240
|
+
)
|
|
241
|
+
print(response.result)
|
|
229
242
|
|
|
230
243
|
asyncio.run(main())
|
|
231
244
|
```
|
|
@@ -237,19 +250,111 @@ import asyncio
|
|
|
237
250
|
from airia import AiriaAsyncClient
|
|
238
251
|
|
|
239
252
|
async def main():
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
print(c, end="")
|
|
253
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
254
|
+
response = await client.execute_pipeline(
|
|
255
|
+
pipeline_id="your_pipeline_id",
|
|
256
|
+
user_input="Tell me about quantum computing",
|
|
257
|
+
async_output=True
|
|
258
|
+
)
|
|
259
|
+
async for c in response.stream:
|
|
260
|
+
print(c)
|
|
249
261
|
|
|
250
262
|
asyncio.run(main())
|
|
251
263
|
```
|
|
252
264
|
|
|
265
|
+
## Streaming Event Parsing
|
|
266
|
+
|
|
267
|
+
When using streaming mode (`async_output=True`), the API returns Server-Sent Events (SSE) that contain different types of messages throughout the pipeline execution. You can parse and filter these events to extract specific information.
|
|
268
|
+
|
|
269
|
+
### Available Message Types
|
|
270
|
+
|
|
271
|
+
The streaming response includes various message types defined in `airia.types`. Here are the key ones:
|
|
272
|
+
|
|
273
|
+
- `AgentModelStreamFragmentMessage` - Contains actual LLM output chunks
|
|
274
|
+
- `AgentModelStreamStartMessage` - Indicates LLM streaming has started
|
|
275
|
+
- `AgentModelStreamEndMessage` - Indicates LLM streaming has ended
|
|
276
|
+
- `AgentStepStartMessage` - Indicates a pipeline step has started
|
|
277
|
+
- `AgentStepEndMessage` - Indicates a pipeline step has ended
|
|
278
|
+
- `AgentOutputMessage` - Contains step output
|
|
279
|
+
|
|
280
|
+
<details>
|
|
281
|
+
<summary>Click to expand the full list of message types</summary>
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
[
|
|
285
|
+
AgentPingMessage,
|
|
286
|
+
AgentStartMessage,
|
|
287
|
+
AgentEndMessage,
|
|
288
|
+
AgentStepStartMessage,
|
|
289
|
+
AgentStepHaltMessage,
|
|
290
|
+
AgentStepEndMessage,
|
|
291
|
+
AgentOutputMessage,
|
|
292
|
+
AgentAgentCardMessage,
|
|
293
|
+
AgentDatasearchMessage,
|
|
294
|
+
AgentInvocationMessage,
|
|
295
|
+
AgentModelMessage,
|
|
296
|
+
AgentPythonCodeMessage,
|
|
297
|
+
AgentToolActionMessage,
|
|
298
|
+
AgentModelStreamStartMessage,
|
|
299
|
+
AgentModelStreamEndMessage,
|
|
300
|
+
AgentModelStreamErrorMessage,
|
|
301
|
+
AgentModelStreamUsageMessage,
|
|
302
|
+
AgentModelStreamFragmentMessage,
|
|
303
|
+
AgentAgentCardStreamStartMessage,
|
|
304
|
+
AgentAgentCardStreamErrorMessage,
|
|
305
|
+
AgentAgentCardStreamFragmentMessage,
|
|
306
|
+
AgentAgentCardStreamEndMessage,
|
|
307
|
+
AgentToolRequestMessage,
|
|
308
|
+
AgentToolResponseMessage,
|
|
309
|
+
]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
</details>
|
|
313
|
+
|
|
314
|
+
### Filtering LLM Output
|
|
315
|
+
|
|
316
|
+
To extract only the actual LLM output text from the stream:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
from airia import AiriaClient
|
|
320
|
+
from airia.types import AgentModelStreamFragmentMessage
|
|
321
|
+
|
|
322
|
+
client = AiriaClient(api_key="your_api_key")
|
|
323
|
+
|
|
324
|
+
response = client.execute_pipeline(
|
|
325
|
+
pipeline_id="your_pipeline_id",
|
|
326
|
+
user_input="Tell me about quantum computing",
|
|
327
|
+
async_output=True
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
# Filter and display only LLM output
|
|
331
|
+
for event in response.stream:
|
|
332
|
+
if isinstance(event, AgentModelStreamFragmentMessage) and event.index != -1:
|
|
333
|
+
print(event.content, end="", flush=True)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Pipeline Configuration Retrieval
|
|
337
|
+
|
|
338
|
+
You can retrieve detailed configuration information about a pipeline using the `get_pipeline_config` method:
|
|
339
|
+
|
|
340
|
+
> To get a list of all active pipeline ids, run the `get_active_pipelines_ids` method.
|
|
341
|
+
|
|
342
|
+
```python
|
|
343
|
+
from airia import AiriaClient
|
|
344
|
+
|
|
345
|
+
client = AiriaClient(api_key="your_api_key")
|
|
346
|
+
|
|
347
|
+
# Get pipeline configuration
|
|
348
|
+
config = client.get_pipeline_config(pipeline_id="your_pipeline_id")
|
|
349
|
+
|
|
350
|
+
# Access configuration details
|
|
351
|
+
print(f"Pipeline Name: {config.deployment_name}")
|
|
352
|
+
print(f"Description: {config.deployment_description}")
|
|
353
|
+
print(f"Active Version: {config.active_version.version_number}")
|
|
354
|
+
print(f"Success Count: {config.execution_stats.success_count}")
|
|
355
|
+
print(f"Failure Count: {config.execution_stats.failure_count}")
|
|
356
|
+
```
|
|
357
|
+
|
|
253
358
|
## Gateway Usage
|
|
254
359
|
|
|
255
360
|
Airia provides gateway capabilities for popular AI services like OpenAI and Anthropic, allowing you to use your Airia API key with these services.
|
|
@@ -292,6 +397,8 @@ response = client.anthropic.messages.create(
|
|
|
292
397
|
print(response.content[0].text)
|
|
293
398
|
```
|
|
294
399
|
|
|
400
|
+
You can set the Gateway URL by passing the `gateway_url` parameter when using the gateway constructors. The default values are `https://gateway.airia.ai/openai/v1` for OpenAI and `https://gateway.airia.ai/anthropic` for Anthropic.
|
|
401
|
+
|
|
295
402
|
### Asynchronous Gateway Usage
|
|
296
403
|
|
|
297
404
|
Both gateways also support asynchronous usage:
|
|
@@ -146,6 +146,20 @@ This will create both wheel and source distribution in the `dist/` directory.
|
|
|
146
146
|
|
|
147
147
|
## Quick Start
|
|
148
148
|
|
|
149
|
+
### Client Instantiation
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from airia import AiriaClient
|
|
153
|
+
|
|
154
|
+
client = AiriaClient(
|
|
155
|
+
base_url="https://api.airia.ai", # Default: "https://api.airia.ai"
|
|
156
|
+
api_key=None, # Or set AIRIA_API_KEY environment variable
|
|
157
|
+
timeout=30.0, # Request timeout in seconds (default: 30.0)
|
|
158
|
+
log_requests=False, # Enable request/response logging (default: False)
|
|
159
|
+
custom_logger=None # Use custom logger (default: None - uses built-in)
|
|
160
|
+
)
|
|
161
|
+
```
|
|
162
|
+
|
|
149
163
|
### Synchronous Usage
|
|
150
164
|
|
|
151
165
|
```python
|
|
@@ -178,8 +192,8 @@ response = client.execute_pipeline(
|
|
|
178
192
|
async_output=True
|
|
179
193
|
)
|
|
180
194
|
|
|
181
|
-
for c in
|
|
182
|
-
print(c
|
|
195
|
+
for c in response.stream:
|
|
196
|
+
print(c)
|
|
183
197
|
```
|
|
184
198
|
|
|
185
199
|
### Asynchronous Usage
|
|
@@ -189,13 +203,12 @@ import asyncio
|
|
|
189
203
|
from airia import AiriaAsyncClient
|
|
190
204
|
|
|
191
205
|
async def main():
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
print(response.result)
|
|
206
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
207
|
+
response = await client.execute_pipeline(
|
|
208
|
+
pipeline_id="your_pipeline_id",
|
|
209
|
+
user_input="Tell me about quantum computing"
|
|
210
|
+
)
|
|
211
|
+
print(response.result)
|
|
199
212
|
|
|
200
213
|
asyncio.run(main())
|
|
201
214
|
```
|
|
@@ -207,19 +220,111 @@ import asyncio
|
|
|
207
220
|
from airia import AiriaAsyncClient
|
|
208
221
|
|
|
209
222
|
async def main():
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
print(c, end="")
|
|
223
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
224
|
+
response = await client.execute_pipeline(
|
|
225
|
+
pipeline_id="your_pipeline_id",
|
|
226
|
+
user_input="Tell me about quantum computing",
|
|
227
|
+
async_output=True
|
|
228
|
+
)
|
|
229
|
+
async for c in response.stream:
|
|
230
|
+
print(c)
|
|
219
231
|
|
|
220
232
|
asyncio.run(main())
|
|
221
233
|
```
|
|
222
234
|
|
|
235
|
+
## Streaming Event Parsing
|
|
236
|
+
|
|
237
|
+
When using streaming mode (`async_output=True`), the API returns Server-Sent Events (SSE) that contain different types of messages throughout the pipeline execution. You can parse and filter these events to extract specific information.
|
|
238
|
+
|
|
239
|
+
### Available Message Types
|
|
240
|
+
|
|
241
|
+
The streaming response includes various message types defined in `airia.types`. Here are the key ones:
|
|
242
|
+
|
|
243
|
+
- `AgentModelStreamFragmentMessage` - Contains actual LLM output chunks
|
|
244
|
+
- `AgentModelStreamStartMessage` - Indicates LLM streaming has started
|
|
245
|
+
- `AgentModelStreamEndMessage` - Indicates LLM streaming has ended
|
|
246
|
+
- `AgentStepStartMessage` - Indicates a pipeline step has started
|
|
247
|
+
- `AgentStepEndMessage` - Indicates a pipeline step has ended
|
|
248
|
+
- `AgentOutputMessage` - Contains step output
|
|
249
|
+
|
|
250
|
+
<details>
|
|
251
|
+
<summary>Click to expand the full list of message types</summary>
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
[
|
|
255
|
+
AgentPingMessage,
|
|
256
|
+
AgentStartMessage,
|
|
257
|
+
AgentEndMessage,
|
|
258
|
+
AgentStepStartMessage,
|
|
259
|
+
AgentStepHaltMessage,
|
|
260
|
+
AgentStepEndMessage,
|
|
261
|
+
AgentOutputMessage,
|
|
262
|
+
AgentAgentCardMessage,
|
|
263
|
+
AgentDatasearchMessage,
|
|
264
|
+
AgentInvocationMessage,
|
|
265
|
+
AgentModelMessage,
|
|
266
|
+
AgentPythonCodeMessage,
|
|
267
|
+
AgentToolActionMessage,
|
|
268
|
+
AgentModelStreamStartMessage,
|
|
269
|
+
AgentModelStreamEndMessage,
|
|
270
|
+
AgentModelStreamErrorMessage,
|
|
271
|
+
AgentModelStreamUsageMessage,
|
|
272
|
+
AgentModelStreamFragmentMessage,
|
|
273
|
+
AgentAgentCardStreamStartMessage,
|
|
274
|
+
AgentAgentCardStreamErrorMessage,
|
|
275
|
+
AgentAgentCardStreamFragmentMessage,
|
|
276
|
+
AgentAgentCardStreamEndMessage,
|
|
277
|
+
AgentToolRequestMessage,
|
|
278
|
+
AgentToolResponseMessage,
|
|
279
|
+
]
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
</details>
|
|
283
|
+
|
|
284
|
+
### Filtering LLM Output
|
|
285
|
+
|
|
286
|
+
To extract only the actual LLM output text from the stream:
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
from airia import AiriaClient
|
|
290
|
+
from airia.types import AgentModelStreamFragmentMessage
|
|
291
|
+
|
|
292
|
+
client = AiriaClient(api_key="your_api_key")
|
|
293
|
+
|
|
294
|
+
response = client.execute_pipeline(
|
|
295
|
+
pipeline_id="your_pipeline_id",
|
|
296
|
+
user_input="Tell me about quantum computing",
|
|
297
|
+
async_output=True
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# Filter and display only LLM output
|
|
301
|
+
for event in response.stream:
|
|
302
|
+
if isinstance(event, AgentModelStreamFragmentMessage) and event.index != -1:
|
|
303
|
+
print(event.content, end="", flush=True)
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Pipeline Configuration Retrieval
|
|
307
|
+
|
|
308
|
+
You can retrieve detailed configuration information about a pipeline using the `get_pipeline_config` method:
|
|
309
|
+
|
|
310
|
+
> To get a list of all active pipeline ids, run the `get_active_pipelines_ids` method.
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
from airia import AiriaClient
|
|
314
|
+
|
|
315
|
+
client = AiriaClient(api_key="your_api_key")
|
|
316
|
+
|
|
317
|
+
# Get pipeline configuration
|
|
318
|
+
config = client.get_pipeline_config(pipeline_id="your_pipeline_id")
|
|
319
|
+
|
|
320
|
+
# Access configuration details
|
|
321
|
+
print(f"Pipeline Name: {config.deployment_name}")
|
|
322
|
+
print(f"Description: {config.deployment_description}")
|
|
323
|
+
print(f"Active Version: {config.active_version.version_number}")
|
|
324
|
+
print(f"Success Count: {config.execution_stats.success_count}")
|
|
325
|
+
print(f"Failure Count: {config.execution_stats.failure_count}")
|
|
326
|
+
```
|
|
327
|
+
|
|
223
328
|
## Gateway Usage
|
|
224
329
|
|
|
225
330
|
Airia provides gateway capabilities for popular AI services like OpenAI and Anthropic, allowing you to use your Airia API key with these services.
|
|
@@ -262,6 +367,8 @@ response = client.anthropic.messages.create(
|
|
|
262
367
|
print(response.content[0].text)
|
|
263
368
|
```
|
|
264
369
|
|
|
370
|
+
You can set the Gateway URL by passing the `gateway_url` parameter when using the gateway constructors. The default values are `https://gateway.airia.ai/openai/v1` for OpenAI and `https://gateway.airia.ai/anthropic` for Anthropic.
|
|
371
|
+
|
|
265
372
|
### Asynchronous Gateway Usage
|
|
266
373
|
|
|
267
374
|
Both gateways also support asynchronous usage:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import weakref
|
|
1
3
|
from typing import Any, AsyncIterator, Dict, List, Literal, Optional, overload
|
|
2
4
|
from urllib.parse import urljoin
|
|
3
5
|
|
|
@@ -7,12 +9,14 @@ import loguru
|
|
|
7
9
|
from ..exceptions import AiriaAPIError
|
|
8
10
|
from ..types import (
|
|
9
11
|
ApiVersion,
|
|
12
|
+
GetPipelineConfigResponse,
|
|
10
13
|
PipelineExecutionDebugResponse,
|
|
11
14
|
PipelineExecutionResponse,
|
|
12
15
|
PipelineExecutionV1StreamedResponse,
|
|
13
16
|
PipelineExecutionV2AsyncStreamedResponse,
|
|
14
17
|
RequestData,
|
|
15
18
|
)
|
|
19
|
+
from ..utils.sse_parser import async_parse_sse_stream_chunked
|
|
16
20
|
from .base_client import AiriaBaseClient
|
|
17
21
|
|
|
18
22
|
|
|
@@ -21,6 +25,7 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
21
25
|
|
|
22
26
|
def __init__(
|
|
23
27
|
self,
|
|
28
|
+
base_url: str = "https://api.airia.ai/",
|
|
24
29
|
api_key: Optional[str] = None,
|
|
25
30
|
timeout: float = 30.0,
|
|
26
31
|
log_requests: bool = False,
|
|
@@ -30,20 +35,52 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
30
35
|
Initialize the asynchronous Airia API client.
|
|
31
36
|
|
|
32
37
|
Args:
|
|
38
|
+
base_url: Base URL of the Airia API.
|
|
33
39
|
api_key: API key for authentication. If not provided, will attempt to use AIRIA_API_KEY environment variable.
|
|
34
40
|
timeout: Request timeout in seconds.
|
|
35
41
|
log_requests: Whether to log API requests and responses. Default is False.
|
|
36
42
|
custom_logger: Optional custom logger object to use for logging. If not provided, will use a default logger when `log_requests` is True.
|
|
37
43
|
"""
|
|
38
|
-
super().__init__(
|
|
44
|
+
super().__init__(
|
|
45
|
+
base_url=base_url,
|
|
46
|
+
api_key=api_key,
|
|
47
|
+
timeout=timeout,
|
|
48
|
+
log_requests=log_requests,
|
|
49
|
+
custom_logger=custom_logger,
|
|
50
|
+
)
|
|
39
51
|
|
|
40
52
|
# Session will be initialized in __aenter__
|
|
41
|
-
self.session = None
|
|
42
53
|
self.headers = {"Content-Type": "application/json"}
|
|
43
|
-
|
|
54
|
+
self.session = aiohttp.ClientSession(headers=self.headers)
|
|
55
|
+
|
|
56
|
+
# Register finalizer to clean up session when client is garbage collected
|
|
57
|
+
self._finalizer = weakref.finalize(self, self._cleanup_session, self.session)
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def _cleanup_session(session: aiohttp.ClientSession):
|
|
61
|
+
"""Static method to clean up session - called by finalizer"""
|
|
62
|
+
if session and not session.closed:
|
|
63
|
+
# Create a new event loop if none exists
|
|
64
|
+
try:
|
|
65
|
+
loop = asyncio.get_event_loop()
|
|
66
|
+
if loop.is_closed():
|
|
67
|
+
raise RuntimeError("Event loop is closed")
|
|
68
|
+
except RuntimeError:
|
|
69
|
+
loop = asyncio.new_event_loop()
|
|
70
|
+
asyncio.set_event_loop(loop)
|
|
71
|
+
|
|
72
|
+
# Close the session
|
|
73
|
+
if not loop.is_running():
|
|
74
|
+
loop.run_until_complete(session.close())
|
|
75
|
+
else:
|
|
76
|
+
# If loop is running, schedule the close operation
|
|
77
|
+
asyncio.create_task(session.close())
|
|
78
|
+
|
|
44
79
|
@classmethod
|
|
45
80
|
def with_openai_gateway(
|
|
46
81
|
cls,
|
|
82
|
+
base_url: str = "https://api.airia.ai/",
|
|
83
|
+
gateway_url: str = "https://gateway.airia.ai/openai/v1",
|
|
47
84
|
api_key: Optional[str] = None,
|
|
48
85
|
timeout: float = 30.0,
|
|
49
86
|
log_requests: bool = False,
|
|
@@ -54,6 +91,8 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
54
91
|
Initialize the asynchronous Airia API client with AsyncOpenAI gateway capabilities.
|
|
55
92
|
|
|
56
93
|
Args:
|
|
94
|
+
base_url: Base URL of the Airia API.
|
|
95
|
+
gateway_url: Base URL of the Airia Gateway API.
|
|
57
96
|
api_key: API key for authentication. If not provided, will attempt to use AIRIA_API_KEY environment variable.
|
|
58
97
|
timeout: Request timeout in seconds.
|
|
59
98
|
log_requests: Whether to log API requests and responses. Default is False.
|
|
@@ -65,15 +104,17 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
65
104
|
api_key = cls._get_api_key(api_key)
|
|
66
105
|
cls.openai = AsyncOpenAI(
|
|
67
106
|
api_key=api_key,
|
|
68
|
-
base_url=
|
|
107
|
+
base_url=gateway_url,
|
|
69
108
|
**kwargs,
|
|
70
109
|
)
|
|
71
110
|
|
|
72
|
-
return cls(api_key, timeout, log_requests, custom_logger)
|
|
111
|
+
return cls(base_url, api_key, timeout, log_requests, custom_logger)
|
|
73
112
|
|
|
74
113
|
@classmethod
|
|
75
114
|
def with_anthropic_gateway(
|
|
76
115
|
cls,
|
|
116
|
+
base_url: str = "https://api.airia.ai/",
|
|
117
|
+
gateway_url: str = "https://gateway.airia.ai/anthropic",
|
|
77
118
|
api_key: Optional[str] = None,
|
|
78
119
|
timeout: float = 30.0,
|
|
79
120
|
log_requests: bool = False,
|
|
@@ -84,6 +125,8 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
84
125
|
Initialize the asynchronous Airia API client with AsyncAnthropic gateway capabilities.
|
|
85
126
|
|
|
86
127
|
Args:
|
|
128
|
+
base_url: Base URL of the Airia API.
|
|
129
|
+
gateway_url: Base URL of the Airia Gateway API.
|
|
87
130
|
api_key: API key for authentication. If not provided, will attempt to use AIRIA_API_KEY environment variable.
|
|
88
131
|
timeout: Request timeout in seconds.
|
|
89
132
|
log_requests: Whether to log API requests and responses. Default is False.
|
|
@@ -95,29 +138,11 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
95
138
|
api_key = cls._get_api_key(api_key)
|
|
96
139
|
cls.anthropic = AsyncAnthropic(
|
|
97
140
|
api_key=api_key,
|
|
98
|
-
base_url=
|
|
141
|
+
base_url=gateway_url,
|
|
99
142
|
**kwargs,
|
|
100
143
|
)
|
|
101
144
|
|
|
102
|
-
return cls(api_key, timeout, log_requests, custom_logger)
|
|
103
|
-
|
|
104
|
-
async def __aenter__(self):
|
|
105
|
-
"""Async context manager entry point."""
|
|
106
|
-
self.session = aiohttp.ClientSession(headers=self.headers)
|
|
107
|
-
return self
|
|
108
|
-
|
|
109
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
110
|
-
"""Async context manager exit point."""
|
|
111
|
-
if self.session:
|
|
112
|
-
await self.session.close()
|
|
113
|
-
self.session = None
|
|
114
|
-
|
|
115
|
-
def _check_session(self):
|
|
116
|
-
"""Check if the client session is initialized."""
|
|
117
|
-
if not self.session:
|
|
118
|
-
raise RuntimeError(
|
|
119
|
-
"Client session not initialized. Use async with AiriaAsyncClient() as client: ..."
|
|
120
|
-
)
|
|
145
|
+
return cls(base_url, api_key, timeout, log_requests, custom_logger)
|
|
121
146
|
|
|
122
147
|
def _handle_exception(
|
|
123
148
|
self, e: aiohttp.ClientResponseError, url: str, correlation_id: str
|
|
@@ -241,8 +266,10 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
241
266
|
response.raise_for_status()
|
|
242
267
|
|
|
243
268
|
# Yields the response content as a stream if streaming
|
|
244
|
-
async for
|
|
245
|
-
|
|
269
|
+
async for message in async_parse_sse_stream_chunked(
|
|
270
|
+
response.content.iter_any()
|
|
271
|
+
):
|
|
272
|
+
yield message
|
|
246
273
|
|
|
247
274
|
except aiohttp.ClientResponseError as e:
|
|
248
275
|
self._handle_exception(e, request_data.url, request_data.correlation_id)
|
|
@@ -399,8 +426,6 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
399
426
|
... )
|
|
400
427
|
>>> print(response.result)
|
|
401
428
|
"""
|
|
402
|
-
self._check_session()
|
|
403
|
-
|
|
404
429
|
request_data = self._pre_execute_pipeline(
|
|
405
430
|
pipeline_id=pipeline_id,
|
|
406
431
|
user_input=user_input,
|
|
@@ -446,3 +471,112 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
446
471
|
return PipelineExecutionV1StreamedResponse(**resp)
|
|
447
472
|
|
|
448
473
|
return PipelineExecutionV2AsyncStreamedResponse(stream=resp)
|
|
474
|
+
|
|
475
|
+
async def get_active_pipelines_ids(
|
|
476
|
+
self,
|
|
477
|
+
correlation_id: Optional[str] = None,
|
|
478
|
+
api_version: str = ApiVersion.V1.value,
|
|
479
|
+
) -> List[str]:
|
|
480
|
+
"""
|
|
481
|
+
Retrieve a list of active pipeline IDs.
|
|
482
|
+
|
|
483
|
+
This method fetches all currently active pipeline IDs from the Airia API.
|
|
484
|
+
These IDs can be used with other methods like execute_pipeline() or
|
|
485
|
+
get_pipeline_config().
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
api_version (str, optional): API version to use for the request.
|
|
489
|
+
Must be one of the supported versions. Defaults to "v1".
|
|
490
|
+
correlation_id (str, optional): Unique identifier for request tracing
|
|
491
|
+
and logging. If not provided, a new UUID will be automatically
|
|
492
|
+
generated.
|
|
493
|
+
|
|
494
|
+
Returns:
|
|
495
|
+
List[str]: A list of active pipeline ID strings. Returns an empty list
|
|
496
|
+
if no active pipelines are found.
|
|
497
|
+
|
|
498
|
+
Raises:
|
|
499
|
+
ValueError: If the provided API version is not supported.
|
|
500
|
+
AiriaAPIError: If the API request fails, including network errors,
|
|
501
|
+
authentication failures, or server errors.
|
|
502
|
+
|
|
503
|
+
Example:
|
|
504
|
+
>>> client = AiriaClient(api_key="your_api_key")
|
|
505
|
+
>>> pipeline_ids = client.get_active_pipelines_ids()
|
|
506
|
+
>>> print(f"Found {len(pipeline_ids)} active pipelines")
|
|
507
|
+
>>> for pipeline_id in pipeline_ids:
|
|
508
|
+
... print(f"Pipeline ID: {pipeline_id}")
|
|
509
|
+
"""
|
|
510
|
+
request_data = self._pre_get_active_pipelines_ids(
|
|
511
|
+
correlation_id=correlation_id, api_version=api_version
|
|
512
|
+
)
|
|
513
|
+
resp = await self._make_request("GET", request_data)
|
|
514
|
+
|
|
515
|
+
if "items" not in resp or len(resp["items"]) == 0:
|
|
516
|
+
return []
|
|
517
|
+
|
|
518
|
+
pipeline_ids = [r["activeVersion"]["pipelineId"] for r in resp["items"]]
|
|
519
|
+
|
|
520
|
+
return pipeline_ids
|
|
521
|
+
|
|
522
|
+
async def get_pipeline_config(
|
|
523
|
+
self,
|
|
524
|
+
pipeline_id: str,
|
|
525
|
+
correlation_id: Optional[str] = None,
|
|
526
|
+
api_version: str = ApiVersion.V1.value,
|
|
527
|
+
) -> GetPipelineConfigResponse:
|
|
528
|
+
"""
|
|
529
|
+
Retrieve configuration details for a specific pipeline.
|
|
530
|
+
|
|
531
|
+
This method fetches comprehensive information about a pipeline including its
|
|
532
|
+
deployment details, execution statistics, version information, and metadata.
|
|
533
|
+
|
|
534
|
+
Args:
|
|
535
|
+
pipeline_id (str): The unique identifier of the pipeline to retrieve
|
|
536
|
+
configuration for.
|
|
537
|
+
api_version (str, optional): The API version to use for the request.
|
|
538
|
+
Defaults to "v1". Valid versions are defined in ApiVersion enum.
|
|
539
|
+
correlation_id (str, optional): A unique identifier for request tracing
|
|
540
|
+
and logging. If not provided, one will be automatically generated.
|
|
541
|
+
|
|
542
|
+
Returns:
|
|
543
|
+
GetPipelineConfigResponse: A response object containing the pipeline
|
|
544
|
+
configuration.
|
|
545
|
+
|
|
546
|
+
Raises:
|
|
547
|
+
ValueError: If the provided api_version is not valid.
|
|
548
|
+
AiriaAPIError: If the API request fails, including cases where:
|
|
549
|
+
- The pipeline_id doesn't exist (404)
|
|
550
|
+
- Authentication fails (401)
|
|
551
|
+
- Access is forbidden (403)
|
|
552
|
+
- Server errors (5xx)
|
|
553
|
+
|
|
554
|
+
Example:
|
|
555
|
+
```python
|
|
556
|
+
from airia import AiriaClient
|
|
557
|
+
|
|
558
|
+
client = AiriaClient(api_key="your_api_key")
|
|
559
|
+
|
|
560
|
+
# Get pipeline configuration
|
|
561
|
+
config = client.get_pipeline_config(
|
|
562
|
+
pipeline_id="your_pipeline_id"
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
print(f"Pipeline: {config.deployment_name}")
|
|
566
|
+
print(f"Description: {config.deployment_description}")
|
|
567
|
+
print(f"Success rate: {config.execution_stats.success_count}")
|
|
568
|
+
print(f"Active version: {config.active_version.version_number}")
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
Note:
|
|
572
|
+
This method only retrieves configuration information and does not
|
|
573
|
+
execute the pipeline. Use execute_pipeline() to run the pipeline.
|
|
574
|
+
"""
|
|
575
|
+
request_data = self._pre_get_pipeline_config(
|
|
576
|
+
pipeline_id=pipeline_id,
|
|
577
|
+
correlation_id=correlation_id,
|
|
578
|
+
api_version=api_version,
|
|
579
|
+
)
|
|
580
|
+
resp = await self._make_request("GET", request_data)
|
|
581
|
+
|
|
582
|
+
return GetPipelineConfigResponse(**resp)
|