airia 0.1.2__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.
- airia/__init__.py +6 -0
- airia/exceptions.py +33 -0
- airia/logs.py +159 -0
- airia-0.1.2.dist-info/METADATA +422 -0
- airia-0.1.2.dist-info/RECORD +8 -0
- airia-0.1.2.dist-info/WHEEL +5 -0
- airia-0.1.2.dist-info/licenses/LICENSE +21 -0
- airia-0.1.2.dist-info/top_level.txt +1 -0
airia/__init__.py
ADDED
airia/exceptions.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class AiriaAPIError(Exception):
|
|
2
|
+
'''
|
|
3
|
+
Custom exception for Airia API errors.
|
|
4
|
+
|
|
5
|
+
This exception is raised when an API request to the Airia service fails.
|
|
6
|
+
It contains both the HTTP status code and error message to help with
|
|
7
|
+
debugging and proper error handling.
|
|
8
|
+
|
|
9
|
+
Attributes:
|
|
10
|
+
status_code (int): The HTTP status code returned by the API
|
|
11
|
+
message (str): The error message describing what went wrong
|
|
12
|
+
'''
|
|
13
|
+
|
|
14
|
+
def __init__(self, status_code: int, message: str):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the exception with a status code and error message.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
status_code (int): The HTTP status code of the failed request
|
|
20
|
+
message (str): A descriptive error message
|
|
21
|
+
"""
|
|
22
|
+
super().__init__(f"{status_code}: {message}")
|
|
23
|
+
self.status_code = status_code
|
|
24
|
+
self.message = message
|
|
25
|
+
|
|
26
|
+
def __str__(self) -> str:
|
|
27
|
+
"""
|
|
28
|
+
Return a string representation of the exception.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
str: A formatted string containing the status code and message
|
|
32
|
+
"""
|
|
33
|
+
return f"{self.status_code}: {self.message}"
|
airia/logs.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import uuid
|
|
4
|
+
from contextvars import ContextVar
|
|
5
|
+
from typing import BinaryIO, Optional, TextIO, Union, overload
|
|
6
|
+
|
|
7
|
+
import loguru
|
|
8
|
+
from loguru import logger
|
|
9
|
+
|
|
10
|
+
# Create a context variable to store correlation ID
|
|
11
|
+
correlation_id_context: ContextVar[str] = ContextVar('correlation_id', default='')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_correlation_id() -> str:
|
|
15
|
+
"""
|
|
16
|
+
Get the current correlation ID from context or return empty string if not set.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
str: The current correlation ID
|
|
20
|
+
"""
|
|
21
|
+
return correlation_id_context.get()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_correlation_id(correlation_id: Optional[str] = None) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Set a correlation ID in the current context.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
correlation_id (Optional[str]): The correlation ID to set. If None, a new UUID will be generated.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
str: The correlation ID that was set
|
|
33
|
+
"""
|
|
34
|
+
if correlation_id is None:
|
|
35
|
+
correlation_id = str(uuid.uuid4())
|
|
36
|
+
correlation_id_context.set(correlation_id)
|
|
37
|
+
return correlation_id
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def clear_correlation_id() -> None:
|
|
41
|
+
"""Clear the correlation ID from the current context."""
|
|
42
|
+
correlation_id_context.set('')
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Define a function to be used as a filter to inject correlation_id
|
|
46
|
+
def correlation_id_filter(record):
|
|
47
|
+
record["extra"]["correlation_id"] = get_correlation_id() or "no-correlation-id"
|
|
48
|
+
return record
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@overload
|
|
52
|
+
def configure_logging(
|
|
53
|
+
format_string: str = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
|
|
54
|
+
level: str = "INFO",
|
|
55
|
+
sink: Union[TextIO, BinaryIO] = ...,
|
|
56
|
+
rotation: None = None,
|
|
57
|
+
retention: None = None,
|
|
58
|
+
include_correlation_id: bool = True,
|
|
59
|
+
) -> "loguru.Logger": ...
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@overload
|
|
63
|
+
def configure_logging(
|
|
64
|
+
format_string: str = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
|
|
65
|
+
level: str = "INFO",
|
|
66
|
+
sink: Union[str, os.PathLike[str]] = ...,
|
|
67
|
+
rotation: Optional[str] = None,
|
|
68
|
+
retention: Optional[str] = None,
|
|
69
|
+
include_correlation_id: bool = True,
|
|
70
|
+
) -> "loguru.Logger": ...
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def configure_logging(
|
|
74
|
+
format_string: str = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
|
|
75
|
+
level: str = "INFO",
|
|
76
|
+
sink: Union[os.PathLike[str], TextIO, BinaryIO] = sys.stderr,
|
|
77
|
+
rotation: Optional[str] = None,
|
|
78
|
+
retention: Optional[str] = None,
|
|
79
|
+
include_correlation_id: bool = True,
|
|
80
|
+
) -> "loguru.Logger":
|
|
81
|
+
"""
|
|
82
|
+
Configure the loguru logger with custom settings.
|
|
83
|
+
Check [Loguru Documentation](https://loguru.readthedocs.io/en/stable/api/logger.html) for more details.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
format_string (str): The format string for log messages.
|
|
87
|
+
level (str): The minimum logging level. Default: "INFO"
|
|
88
|
+
sink: Where to send the log. Default: sys.stderr
|
|
89
|
+
rotation (str, optional): When to rotate the log file.
|
|
90
|
+
Example: "10 MB", "1 day"
|
|
91
|
+
Only used when sink is a file path.
|
|
92
|
+
retention (str, optional): How long to keep log files.
|
|
93
|
+
Example: "1 week", "10 days"
|
|
94
|
+
Only used when sink is a file path.
|
|
95
|
+
include_correlation_id (bool): Whether to include correlation ID in log messages.
|
|
96
|
+
Default: True
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
The configured logger object
|
|
100
|
+
"""
|
|
101
|
+
# Remove any existing handlers
|
|
102
|
+
logger.remove()
|
|
103
|
+
|
|
104
|
+
# Modify format string to include correlation ID if requested
|
|
105
|
+
if include_correlation_id:
|
|
106
|
+
format_string = "<magenta>[{extra[correlation_id]}]</magenta> " + format_string
|
|
107
|
+
|
|
108
|
+
# Add rotation and retention only for file paths
|
|
109
|
+
kwargs = {
|
|
110
|
+
"format": format_string,
|
|
111
|
+
"level": level,
|
|
112
|
+
"filter": correlation_id_filter, # Add the filter for each handler
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if isinstance(sink, (str, os.PathLike)):
|
|
116
|
+
if rotation is not None:
|
|
117
|
+
kwargs["rotation"] = rotation
|
|
118
|
+
if retention is not None:
|
|
119
|
+
kwargs["retention"] = retention
|
|
120
|
+
|
|
121
|
+
# Add the new handler
|
|
122
|
+
logger.add(sink, **kwargs)
|
|
123
|
+
|
|
124
|
+
return logger
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# Example usage:
|
|
128
|
+
if __name__ == "__main__":
|
|
129
|
+
# Basic configuration (uses sys.stderr)
|
|
130
|
+
log = configure_logging()
|
|
131
|
+
log.info("Basic logging configured successfully")
|
|
132
|
+
|
|
133
|
+
# Set a correlation ID
|
|
134
|
+
set_correlation_id("request-123")
|
|
135
|
+
log.info("This log has a correlation ID")
|
|
136
|
+
|
|
137
|
+
# Change correlation ID
|
|
138
|
+
set_correlation_id("request-456")
|
|
139
|
+
log.info("This log has a different correlation ID")
|
|
140
|
+
|
|
141
|
+
# Use auto-generated correlation ID
|
|
142
|
+
set_correlation_id()
|
|
143
|
+
log.info("This log has an auto-generated correlation ID")
|
|
144
|
+
|
|
145
|
+
# File-based logging with rotation and retention
|
|
146
|
+
file_log = configure_logging(
|
|
147
|
+
format_string="[{time:YYYY-MM-DD HH:mm:ss}] [{level}] {message}",
|
|
148
|
+
level="DEBUG",
|
|
149
|
+
sink="app.log",
|
|
150
|
+
rotation="10 MB",
|
|
151
|
+
retention="1 week",
|
|
152
|
+
)
|
|
153
|
+
file_log.debug("File logging configured successfully")
|
|
154
|
+
|
|
155
|
+
# Stream-based logging
|
|
156
|
+
stream_log = configure_logging(
|
|
157
|
+
format_string="[{time:HH:mm:ss}] {message}", level="INFO", sink=sys.stdout
|
|
158
|
+
)
|
|
159
|
+
stream_log.info("Stream logging configured successfully")
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: airia
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Python SDK for Airia API
|
|
5
|
+
Author-email: Airia LLC <support@airia.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.32.3
|
|
19
|
+
Requires-Dist: aiohttp>=3.11.14
|
|
20
|
+
Requires-Dist: loguru>=0.7.3
|
|
21
|
+
Requires-Dist: pydantic>=2.11.0
|
|
22
|
+
Provides-Extra: anthropic
|
|
23
|
+
Requires-Dist: anthropic>=0.49.0; extra == "anthropic"
|
|
24
|
+
Provides-Extra: openai
|
|
25
|
+
Requires-Dist: openai>=1.74.0; extra == "openai"
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: anthropic>=0.49.0; extra == "all"
|
|
28
|
+
Requires-Dist: openai>=1.74.0; extra == "all"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# Airia Python API Library
|
|
32
|
+
|
|
33
|
+
Airia Python API Library that provides a clean and intuitive interface to interact with the Airia AI platform API. The library offers both synchronous and asynchronous clients for maximum flexibility in your applications.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Dual Client Support**: Choose between synchronous (`AiriaClient`) and asynchronous (`AiriaAsyncClient`) implementations
|
|
38
|
+
- **Pipeline Execution**: Easily run AI pipelines with customizable parameters
|
|
39
|
+
- **Gateway Support**: Seamlessly integrate with OpenAI and Anthropic services through Airia gateways
|
|
40
|
+
- **Error Handling**: Comprehensive error handling with custom exceptions
|
|
41
|
+
- **Logging**: Built-in configurable logging with correlation ID support for request tracing
|
|
42
|
+
- **API Key Management**: Flexible API key configuration via parameters or environment variables
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
Clone the repository:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone https://github.com/AiriaLLC/airia-python.git
|
|
50
|
+
cd airia-python
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can install the package using pip or uv:
|
|
54
|
+
|
|
55
|
+
<table>
|
|
56
|
+
<tr>
|
|
57
|
+
<th>pip</th>
|
|
58
|
+
<th>uv</th>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td>
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install -e .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
</td>
|
|
68
|
+
<td>
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv sync --frozen
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
</td>
|
|
75
|
+
</tr>
|
|
76
|
+
</table>
|
|
77
|
+
|
|
78
|
+
### Install with optional dependencies
|
|
79
|
+
|
|
80
|
+
The package supports optional dependencies for gateway functionality:
|
|
81
|
+
|
|
82
|
+
<table>
|
|
83
|
+
<tr>
|
|
84
|
+
<th>OpenAI Gateway</th>
|
|
85
|
+
<th>Anthropic Gateway</th>
|
|
86
|
+
<th>All Gateways</th>
|
|
87
|
+
</tr>
|
|
88
|
+
<tr>
|
|
89
|
+
<td>
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install -e .[openai]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</td>
|
|
96
|
+
<td>
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pip install -e .[anthropic]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
</td>
|
|
103
|
+
<td>
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e .[all]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
</td>
|
|
110
|
+
</tr>
|
|
111
|
+
</table>
|
|
112
|
+
|
|
113
|
+
### Install with development dependencies
|
|
114
|
+
|
|
115
|
+
<table>
|
|
116
|
+
<tr>
|
|
117
|
+
<th>pip</th>
|
|
118
|
+
<th>uv</th>
|
|
119
|
+
</tr>
|
|
120
|
+
<tr>
|
|
121
|
+
<td>
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pip install dependency-groups
|
|
125
|
+
dev=$(python -m dependency_groups dev)
|
|
126
|
+
pip install -e .
|
|
127
|
+
pip install $dev
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
</td>
|
|
131
|
+
<td>
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
uv sync --frozen --group dev
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</table>
|
|
140
|
+
|
|
141
|
+
## Building from Source
|
|
142
|
+
|
|
143
|
+
To build the package from source:
|
|
144
|
+
|
|
145
|
+
<table>
|
|
146
|
+
<tr>
|
|
147
|
+
<th>pip</th>
|
|
148
|
+
<th>uv</th>
|
|
149
|
+
</tr>
|
|
150
|
+
<tr>
|
|
151
|
+
<td>
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip install build
|
|
155
|
+
python -m build
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
</td>
|
|
159
|
+
<td>
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
uv build
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
</td>
|
|
166
|
+
</tr>
|
|
167
|
+
</table>
|
|
168
|
+
|
|
169
|
+
This will create both wheel and source distribution in the `dist/` directory.
|
|
170
|
+
|
|
171
|
+
## Quick Start
|
|
172
|
+
|
|
173
|
+
### Synchronous Usage
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from airia import AiriaClient
|
|
177
|
+
|
|
178
|
+
# Initialize client (API key can be passed directly or via AIRIA_API_KEY environment variable)
|
|
179
|
+
client = AiriaClient(api_key="your_api_key")
|
|
180
|
+
|
|
181
|
+
# Execute a pipeline
|
|
182
|
+
response = client.execute_pipeline(
|
|
183
|
+
pipeline_id="your_pipeline_id",
|
|
184
|
+
user_input="Tell me about quantum computing"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
print(response.result)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Synchronous Streaming
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from airia import AiriaClient
|
|
194
|
+
|
|
195
|
+
# Initialize client (API key can be passed directly or via AIRIA_API_KEY environment variable)
|
|
196
|
+
client = AiriaClient(api_key="your_api_key")
|
|
197
|
+
|
|
198
|
+
# Execute a pipeline
|
|
199
|
+
response = client.execute_pipeline(
|
|
200
|
+
pipeline_id="your_pipeline_id",
|
|
201
|
+
user_input="Tell me about quantum computing",
|
|
202
|
+
async_output=True
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
for c in resp.stream:
|
|
206
|
+
print(c, end="")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Asynchronous Usage
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
import asyncio
|
|
213
|
+
from airia import AiriaAsyncClient
|
|
214
|
+
|
|
215
|
+
async def main():
|
|
216
|
+
# Use async context manager for proper session handling
|
|
217
|
+
async with AiriaAsyncClient(api_key="your_api_key") as client:
|
|
218
|
+
response = await client.execute_pipeline(
|
|
219
|
+
pipeline_id="your_pipeline_id",
|
|
220
|
+
user_input="Tell me about quantum computing"
|
|
221
|
+
)
|
|
222
|
+
print(response.result)
|
|
223
|
+
|
|
224
|
+
asyncio.run(main())
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Asynchronous Streaming
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
import asyncio
|
|
231
|
+
from airia import AiriaAsyncClient
|
|
232
|
+
|
|
233
|
+
async def main():
|
|
234
|
+
# Use async context manager for proper session handling
|
|
235
|
+
async with AiriaAsyncClient(api_key="your_api_key") as client:
|
|
236
|
+
response = await client.execute_pipeline(
|
|
237
|
+
pipeline_id="your_pipeline_id",
|
|
238
|
+
user_input="Tell me about quantum computing",
|
|
239
|
+
async_output=True
|
|
240
|
+
)
|
|
241
|
+
async for c in resp.stream:
|
|
242
|
+
print(c, end="")
|
|
243
|
+
|
|
244
|
+
asyncio.run(main())
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Gateway Usage
|
|
248
|
+
|
|
249
|
+
Airia provides gateway capabilities for popular AI services like OpenAI and Anthropic, allowing you to use your Airia API key with these services.
|
|
250
|
+
|
|
251
|
+
### OpenAI Gateway
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from airia import AiriaClient
|
|
255
|
+
|
|
256
|
+
# Initialize client with OpenAI gateway support
|
|
257
|
+
client = AiriaClient.with_openai_gateway(api_key="your_airia_api_key")
|
|
258
|
+
|
|
259
|
+
# Use OpenAI's API through Airia's gateway
|
|
260
|
+
response = client.openai.chat.completions.create(
|
|
261
|
+
model="gpt-4.1-nano",
|
|
262
|
+
messages=[
|
|
263
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
264
|
+
{"role": "user", "content": "Hello!"},
|
|
265
|
+
]
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
print(response.choices[0].message.content)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Anthropic Gateway
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
from airia import AiriaClient
|
|
275
|
+
|
|
276
|
+
# Initialize client with Anthropic gateway support
|
|
277
|
+
client = AiriaClient.with_anthropic_gateway(api_key="your_airia_api_key")
|
|
278
|
+
|
|
279
|
+
# Use Anthropic's API through Airia's gateway
|
|
280
|
+
response = client.anthropic.messages.create(
|
|
281
|
+
model="claude-3-5-haiku-20241022",
|
|
282
|
+
max_tokens=1000,
|
|
283
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
print(response.content[0].text)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Asynchronous Gateway Usage
|
|
290
|
+
|
|
291
|
+
Both gateways also support asynchronous usage:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
import asyncio
|
|
295
|
+
from airia import AiriaAsyncClient
|
|
296
|
+
|
|
297
|
+
async def main():
|
|
298
|
+
# Initialize async client with gateway support
|
|
299
|
+
client = AiriaAsyncClient.with_openai_gateway(api_key="your_airia_api_key")
|
|
300
|
+
|
|
301
|
+
# Use OpenAI's API asynchronously through Airia's gateway
|
|
302
|
+
response = await client.openai.chat.completions.create(
|
|
303
|
+
model="gpt-4.1-nano",
|
|
304
|
+
messages=[
|
|
305
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
306
|
+
{"role": "user", "content": "Hello!"},
|
|
307
|
+
]
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
print(response.choices[0].message.content)
|
|
311
|
+
|
|
312
|
+
asyncio.run(main())
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Advanced Usage
|
|
316
|
+
|
|
317
|
+
### Pipeline Execution with All Options
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
response = client.execute_pipeline(
|
|
321
|
+
pipeline_id="pipeline_id",
|
|
322
|
+
user_input="Your input text",
|
|
323
|
+
debug=True, # Enable debug mode
|
|
324
|
+
user_id="user_guid", # User identifier
|
|
325
|
+
conversation_id="conversation_guid", # Conversation identifier
|
|
326
|
+
async_output=False, # Stream response (async mode)
|
|
327
|
+
include_tools_response=True, # Return the initial LLM tool result
|
|
328
|
+
images=["base64_encoded_image"], # Include image data
|
|
329
|
+
files=["base64_encoded_file"], # Include file data
|
|
330
|
+
data_source_folders={}, # Data source folders configuration
|
|
331
|
+
data_source_files={}, # Data source files configuration
|
|
332
|
+
in_memory_messages=[ # Context messages for conversation
|
|
333
|
+
{"role": "user", "message": "Previous message"}
|
|
334
|
+
],
|
|
335
|
+
current_date_time="2025-03-26T21:00:00", # Override current date/time
|
|
336
|
+
save_history=True, # Save to conversation history
|
|
337
|
+
additional_info=["extra data"], # Additional metadata
|
|
338
|
+
prompt_variables={"var1": "value1"}, # Variables for prompt templating
|
|
339
|
+
correlation_id="request-123", # Request tracing ID
|
|
340
|
+
api_version="v2" # API version for the request
|
|
341
|
+
)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Configuring Logging
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
import sys
|
|
348
|
+
from airia import configure_logging
|
|
349
|
+
|
|
350
|
+
# Basic configuration
|
|
351
|
+
logger = configure_logging()
|
|
352
|
+
|
|
353
|
+
# Advanced configuration
|
|
354
|
+
file_logger = configure_logging(
|
|
355
|
+
format_string="[{time:YYYY-MM-DD HH:mm:ss}] [{level}] {message}",
|
|
356
|
+
level="DEBUG",
|
|
357
|
+
sink="app.log",
|
|
358
|
+
rotation="10 MB",
|
|
359
|
+
retention="1 week",
|
|
360
|
+
include_correlation_id=True
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Console output with custom format
|
|
364
|
+
console_logger = configure_logging(
|
|
365
|
+
format_string="[{time:HH:mm:ss}] {message}",
|
|
366
|
+
level="INFO",
|
|
367
|
+
sink=sys.stdout
|
|
368
|
+
)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Error Handling
|
|
372
|
+
|
|
373
|
+
The SDK uses custom exceptions to provide clear error messages:
|
|
374
|
+
|
|
375
|
+
```python
|
|
376
|
+
from airia import AiriaAPIError
|
|
377
|
+
|
|
378
|
+
try:
|
|
379
|
+
response = client.execute_pipeline(
|
|
380
|
+
pipeline_id="invalid_id",
|
|
381
|
+
user_input="test"
|
|
382
|
+
)
|
|
383
|
+
except AiriaAPIError as e:
|
|
384
|
+
print(f"API error: {e.status_code} - {e.message}")
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Requirements
|
|
388
|
+
|
|
389
|
+
- Python 3.9 or higher
|
|
390
|
+
- Core dependencies:
|
|
391
|
+
- requests
|
|
392
|
+
- aiohttp
|
|
393
|
+
- loguru
|
|
394
|
+
- pydantic
|
|
395
|
+
|
|
396
|
+
- Optional dependencies:
|
|
397
|
+
- OpenAI gateway: `openai>=1.74.0`
|
|
398
|
+
- Anthropic gateway: `anthropic>=0.49.0`
|
|
399
|
+
|
|
400
|
+
## Development
|
|
401
|
+
|
|
402
|
+
To run tests (make sure you have development dependencies installed):
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
pytest
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
For testing gateway functionality, install the optional dependencies:
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
# For OpenAI gateway tests
|
|
412
|
+
pip install -e .[openai]
|
|
413
|
+
pytest tests/test_openai_gateway.py
|
|
414
|
+
|
|
415
|
+
# For Anthropic gateway tests
|
|
416
|
+
pip install -e .[anthropic]
|
|
417
|
+
pytest tests/test_anthropic_gateway.py
|
|
418
|
+
|
|
419
|
+
# For all tests
|
|
420
|
+
pip install -e .[all]
|
|
421
|
+
pytest
|
|
422
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
airia/__init__.py,sha256=T39gO8E5T5zxlw-JP78ruxOu7-LeKOJCJzz6t40kdQo,231
|
|
2
|
+
airia/exceptions.py,sha256=4Z55n-cRJrtTa5-pZBIK2oZD4-Z99aUtKx_kfTFYY5o,1146
|
|
3
|
+
airia/logs.py,sha256=17YZ4IuzOF0m5bgofj9-QYlJ2BYR2kRZbBVQfFSLFEk,5441
|
|
4
|
+
airia-0.1.2.dist-info/licenses/LICENSE,sha256=R3ClUMMKPRItIcZ0svzyj2taZZnFYw568YDNzN9KQ1Q,1066
|
|
5
|
+
airia-0.1.2.dist-info/METADATA,sha256=P6kEfX-udLEj3GNG1qvZcq4SEPOS_rFB_DNuuX2X3QQ,9578
|
|
6
|
+
airia-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
airia-0.1.2.dist-info/top_level.txt,sha256=qUQEKfs_hdOYTwjKj1JZbRhS5YeXDNaKQaVTrzabS6w,6
|
|
8
|
+
airia-0.1.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Airia LLC
|
|
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 @@
|
|
|
1
|
+
airia
|