airia 0.1.12__py3-none-any.whl → 0.1.14__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.
Files changed (58) hide show
  1. airia/client/_request_handler/__init__.py +4 -0
  2. airia/client/_request_handler/async_request_handler.py +272 -0
  3. airia/client/_request_handler/base_request_handler.py +108 -0
  4. airia/client/_request_handler/sync_request_handler.py +255 -0
  5. airia/client/async_client.py +25 -584
  6. airia/client/base_client.py +2 -209
  7. airia/client/conversations/__init__.py +4 -0
  8. airia/client/conversations/async_conversations.py +187 -0
  9. airia/client/conversations/base_conversations.py +135 -0
  10. airia/client/conversations/sync_conversations.py +182 -0
  11. airia/client/pipeline_execution/__init__.py +4 -0
  12. airia/client/pipeline_execution/async_pipeline_execution.py +178 -0
  13. airia/client/pipeline_execution/base_pipeline_execution.py +96 -0
  14. airia/client/pipeline_execution/sync_pipeline_execution.py +178 -0
  15. airia/client/pipelines_config/__init__.py +4 -0
  16. airia/client/pipelines_config/async_pipelines_config.py +127 -0
  17. airia/client/pipelines_config/base_pipelines_config.py +76 -0
  18. airia/client/pipelines_config/sync_pipelines_config.py +127 -0
  19. airia/client/project/__init__.py +4 -0
  20. airia/client/project/async_project.py +122 -0
  21. airia/client/project/base_project.py +74 -0
  22. airia/client/project/sync_project.py +120 -0
  23. airia/client/store/__init__.py +4 -0
  24. airia/client/store/async_store.py +377 -0
  25. airia/client/store/base_store.py +243 -0
  26. airia/client/store/sync_store.py +352 -0
  27. airia/client/sync_client.py +25 -563
  28. airia/constants.py +13 -2
  29. airia/exceptions.py +8 -8
  30. airia/logs.py +10 -32
  31. airia/types/__init__.py +0 -0
  32. airia/types/_request_data.py +29 -2
  33. airia/types/api/__init__.py +0 -19
  34. airia/types/api/conversations/__init__.py +3 -0
  35. airia/types/api/conversations/_conversations.py +115 -0
  36. airia/types/api/pipeline_execution/__init__.py +13 -0
  37. airia/types/api/pipeline_execution/_pipeline_execution.py +76 -0
  38. airia/types/api/pipelines_config/__init__.py +3 -0
  39. airia/types/api/pipelines_config/get_pipeline_config.py +401 -0
  40. airia/types/api/project/__init__.py +3 -0
  41. airia/types/api/project/get_projects.py +91 -0
  42. airia/types/api/store/__init__.py +4 -0
  43. airia/types/api/store/get_file.py +145 -0
  44. airia/types/api/store/get_files.py +21 -0
  45. airia/types/sse/__init__.py +8 -0
  46. airia/types/sse/sse_messages.py +209 -0
  47. airia/utils/sse_parser.py +40 -7
  48. airia-0.1.14.dist-info/METADATA +221 -0
  49. airia-0.1.14.dist-info/RECORD +55 -0
  50. airia/types/api/conversations.py +0 -14
  51. airia/types/api/get_pipeline_config.py +0 -183
  52. airia/types/api/get_projects.py +0 -35
  53. airia/types/api/pipeline_execution.py +0 -29
  54. airia-0.1.12.dist-info/METADATA +0 -705
  55. airia-0.1.12.dist-info/RECORD +0 -23
  56. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/WHEEL +0 -0
  57. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/licenses/LICENSE +0 -0
  58. {airia-0.1.12.dist-info → airia-0.1.14.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,11 @@
1
+ """
2
+ Server-Sent Event (SSE) message types and models for the Airia API.
3
+
4
+ This module defines all possible SSE message types that can be received during
5
+ pipeline execution, including agent lifecycle events, processing steps, model
6
+ streaming, and tool execution messages.
7
+ """
8
+
1
9
  from datetime import datetime, time
2
10
  from enum import Enum
3
11
  from typing import Optional, Union
@@ -6,6 +14,13 @@ from pydantic import BaseModel, ConfigDict
6
14
 
7
15
 
8
16
  class MessageType(str, Enum):
17
+ """
18
+ Enumeration of all possible SSE message types from the Airia API.
19
+
20
+ These message types correspond to different events that occur during
21
+ pipeline execution, agent processing, and streaming responses.
22
+ """
23
+
9
24
  AGENT_PING = "AgentPingMessage"
10
25
  AGENT_START = "AgentStartMessage"
11
26
  AGENT_INPUT = "AgentInputMessage"
@@ -35,11 +50,25 @@ class MessageType(str, Enum):
35
50
 
36
51
 
37
52
  class BaseSSEMessage(BaseModel):
53
+ """
54
+ Base class for all Server-Sent Event (SSE) messages from the Airia API.
55
+
56
+ All SSE messages include a message_type field that identifies the specific
57
+ type of event being reported.
58
+ """
59
+
38
60
  model_config = ConfigDict(use_enum_values=True)
39
61
  message_type: MessageType
40
62
 
41
63
 
42
64
  class AgentPingMessage(BaseSSEMessage):
65
+ """
66
+ Ping message sent periodically to maintain connection health.
67
+
68
+ These messages help verify that the connection is still active during
69
+ long-running pipeline executions.
70
+ """
71
+
43
72
  message_type: MessageType = MessageType.AGENT_PING
44
73
  timestamp: datetime
45
74
 
@@ -48,19 +77,38 @@ class AgentPingMessage(BaseSSEMessage):
48
77
 
49
78
 
50
79
  class BaseAgentMessage(BaseSSEMessage):
80
+ """
81
+ Base class for messages related to agent execution.
82
+
83
+ All agent messages include identifiers for the specific agent
84
+ and execution session.
85
+ """
86
+
51
87
  agent_id: str
52
88
  execution_id: str
53
89
 
54
90
 
55
91
  class AgentStartMessage(BaseAgentMessage):
92
+ """
93
+ Message indicating that an agent has started processing.
94
+ """
95
+
56
96
  message_type: MessageType = MessageType.AGENT_START
57
97
 
58
98
 
59
99
  class AgentInputMessage(BaseAgentMessage):
100
+ """
101
+ Message indicating that an agent has received input to process.
102
+ """
103
+
60
104
  message_type: MessageType = MessageType.AGENT_INPUT
61
105
 
62
106
 
63
107
  class AgentEndMessage(BaseAgentMessage):
108
+ """
109
+ Message indicating that an agent has finished processing.
110
+ """
111
+
64
112
  message_type: MessageType = MessageType.AGENT_END
65
113
 
66
114
 
@@ -68,22 +116,46 @@ class AgentEndMessage(BaseAgentMessage):
68
116
 
69
117
 
70
118
  class BaseStepMessage(BaseAgentMessage):
119
+ """
120
+ Base class for messages related to individual processing steps within an agent.
121
+
122
+ Steps represent discrete operations or tasks that an agent performs
123
+ as part of its overall processing workflow.
124
+ """
125
+
71
126
  step_id: str
72
127
  step_type: str
73
128
  step_title: Optional[str] = None
74
129
 
75
130
 
76
131
  class AgentStepStartMessage(BaseStepMessage):
132
+ """
133
+ Message indicating that a processing step has started.
134
+ """
135
+
77
136
  message_type: MessageType = MessageType.AGENT_STEP_START
78
137
  start_time: datetime
79
138
 
80
139
 
81
140
  class AgentStepHaltMessage(BaseStepMessage):
141
+ """
142
+ Message indicating that a step has been halted pending approval.
143
+
144
+ This occurs when human approval is required before proceeding
145
+ with potentially sensitive or high-impact operations.
146
+ """
147
+
82
148
  message_type: MessageType = MessageType.AGENT_STEP_HALT
83
149
  approval_id: str
84
150
 
85
151
 
86
152
  class AgentStepEndMessage(BaseStepMessage):
153
+ """
154
+ Message indicating that a processing step has completed.
155
+
156
+ Includes timing information and the final status of the step.
157
+ """
158
+
87
159
  message_type: MessageType = MessageType.AGENT_STEP_END
88
160
  end_time: datetime
89
161
  duration: time
@@ -91,6 +163,10 @@ class AgentStepEndMessage(BaseStepMessage):
91
163
 
92
164
 
93
165
  class AgentOutputMessage(BaseStepMessage):
166
+ """
167
+ Message containing the output result from a completed step.
168
+ """
169
+
94
170
  message_type: MessageType = MessageType.AGENT_OUTPUT
95
171
  step_result: str
96
172
 
@@ -99,15 +175,36 @@ class AgentOutputMessage(BaseStepMessage):
99
175
 
100
176
 
101
177
  class BaseStatusMessage(BaseStepMessage):
178
+ """
179
+ Base class for status update messages within processing steps.
180
+
181
+ Status messages provide real-time updates about what operations
182
+ are being performed during step execution.
183
+ """
184
+
102
185
  pass
103
186
 
104
187
 
105
188
  class AgentAgentCardMessage(BaseStatusMessage):
189
+ """
190
+ Message indicating that an agent card step is being processed.
191
+
192
+ Agent cards represent interactive UI components or displays
193
+ that provide rich information to users during pipeline execution.
194
+ """
195
+
106
196
  message_type: MessageType = MessageType.AGENT_AGENT_CARD
107
197
  step_name: str
108
198
 
109
199
 
110
200
  class AgentDatasearchMessage(BaseStatusMessage):
201
+ """
202
+ Message indicating that data source search is being performed.
203
+
204
+ This message is sent when an agent is querying or searching
205
+ through configured data sources to retrieve relevant information.
206
+ """
207
+
111
208
  message_type: MessageType = MessageType.AGENT_DATASEARCH
112
209
  datastore_id: str
113
210
  datastore_type: str
@@ -115,21 +212,49 @@ class AgentDatasearchMessage(BaseStatusMessage):
115
212
 
116
213
 
117
214
  class AgentInvocationMessage(BaseStatusMessage):
215
+ """
216
+ Message indicating that another agent is being invoked.
217
+
218
+ This occurs when the current agent calls or delegates work
219
+ to another specialized agent in the pipeline.
220
+ """
221
+
118
222
  message_type: MessageType = MessageType.AGENT_INVOCATION
119
223
  agent_name: str
120
224
 
121
225
 
122
226
  class AgentModelMessage(BaseStatusMessage):
227
+ """
228
+ Message indicating that a language model is being called.
229
+
230
+ This message is sent when an agent begins interacting with
231
+ a language model for text generation or processing.
232
+ """
233
+
123
234
  message_type: MessageType = MessageType.AGENT_MODEL
124
235
  model_name: str
125
236
 
126
237
 
127
238
  class AgentPythonCodeMessage(BaseStatusMessage):
239
+ """
240
+ Message indicating that Python code execution is taking place.
241
+
242
+ This message is sent when an agent executes custom Python code
243
+ blocks as part of its processing workflow.
244
+ """
245
+
128
246
  message_type: MessageType = MessageType.AGENT_PYTHON_CODE
129
247
  step_name: str
130
248
 
131
249
 
132
250
  class AgentToolActionMessage(BaseStatusMessage):
251
+ """
252
+ Message indicating that a tool or external service is being called.
253
+
254
+ This message is sent when an agent invokes an external tool,
255
+ API, or service to perform a specific action or retrieve data.
256
+ """
257
+
133
258
  message_type: MessageType = MessageType.AGENT_TOOL_ACTION
134
259
  step_name: str
135
260
  tool_name: str
@@ -139,33 +264,63 @@ class AgentToolActionMessage(BaseStatusMessage):
139
264
 
140
265
 
141
266
  class BaseModelStreamMessage(BaseAgentMessage):
267
+ """
268
+ Base class for language model streaming messages.
269
+
270
+ Model streaming allows real-time display of text generation
271
+ as it occurs, providing better user experience for long responses.
272
+ """
273
+
142
274
  step_id: str
143
275
  stream_id: str
144
276
 
145
277
 
146
278
  class AgentModelStreamStartMessage(BaseModelStreamMessage):
279
+ """
280
+ Message indicating that model text streaming has begun.
281
+ """
282
+
147
283
  message_type: MessageType = MessageType.AGENT_MODEL_STREAM_START
148
284
  model_name: str
149
285
 
150
286
 
151
287
  class AgentModelStreamErrorMessage(BaseModelStreamMessage):
288
+ """
289
+ Message indicating that an error occurred during model streaming.
290
+ """
291
+
152
292
  message_type: MessageType = MessageType.AGENT_MODEL_STREAM_ERROR
153
293
  error_message: str
154
294
 
155
295
 
156
296
  class AgentModelStreamFragmentMessage(BaseModelStreamMessage):
297
+ """
298
+ Fragment of streaming text content from a language model.
299
+
300
+ These messages contain individual chunks of text as they are generated
301
+ by the model, allowing for real-time display of results.
302
+ """
303
+
157
304
  message_type: MessageType = MessageType.AGENT_MODEL_STREAM_FRAGMENT
158
305
  index: int
159
306
  content: Optional[str] = None
160
307
 
161
308
 
162
309
  class AgentModelStreamEndMessage(BaseModelStreamMessage):
310
+ """
311
+ Message indicating that model text streaming has completed.
312
+ """
313
+
163
314
  message_type: MessageType = MessageType.AGENT_MODEL_STREAM_END
164
315
  content_id: str
165
316
  duration: Optional[float] = None
166
317
 
167
318
 
168
319
  class AgentModelStreamUsageMessage(BaseModelStreamMessage):
320
+ """
321
+ Message containing token usage and cost information for model calls.
322
+ """
323
+
169
324
  message_type: MessageType = MessageType.AGENT_MODEL_STREAM_USAGE
170
325
  token: Optional[int] = None
171
326
  tokens_cost: Optional[float] = None
@@ -175,27 +330,53 @@ class AgentModelStreamUsageMessage(BaseModelStreamMessage):
175
330
 
176
331
 
177
332
  class BaseAgentAgentCardStreamMessage(BaseAgentMessage):
333
+ """
334
+ Base class for agent card streaming messages.
335
+
336
+ Agent card streaming allows real-time updates to interactive
337
+ UI components during their generation or processing.
338
+ """
339
+
178
340
  step_id: str
179
341
  stream_id: str
180
342
 
181
343
 
182
344
  class AgentAgentCardStreamStartMessage(BaseAgentAgentCardStreamMessage):
345
+ """
346
+ Message indicating that agent card streaming has begun.
347
+ """
348
+
183
349
  message_type: MessageType = MessageType.AGENT_AGENT_CARD_STREAM_START
184
350
  content: Optional[str] = None
185
351
 
186
352
 
187
353
  class AgentAgentCardStreamErrorMessage(BaseAgentAgentCardStreamMessage):
354
+ """
355
+ Message indicating that an error occurred during agent card streaming.
356
+ """
357
+
188
358
  message_type: MessageType = MessageType.AGENT_AGENT_CARD_STREAM_ERROR
189
359
  error_message: str
190
360
 
191
361
 
192
362
  class AgentAgentCardStreamFragmentMessage(BaseAgentAgentCardStreamMessage):
363
+ """
364
+ Fragment of streaming agent card content.
365
+
366
+ These messages contain individual chunks of agent card data
367
+ as they are generated, allowing for real-time UI updates.
368
+ """
369
+
193
370
  message_type: MessageType = MessageType.AGENT_AGENT_CARD_STREAM_FRAGMENT
194
371
  index: int
195
372
  content: Optional[str]
196
373
 
197
374
 
198
375
  class AgentAgentCardStreamEndMessage(BaseAgentAgentCardStreamMessage):
376
+ """
377
+ Message indicating that agent card streaming has completed.
378
+ """
379
+
199
380
  message_type: MessageType = MessageType.AGENT_AGENT_CARD_STREAM_END
200
381
  content: Optional[str] = None
201
382
 
@@ -204,15 +385,36 @@ class AgentAgentCardStreamEndMessage(BaseAgentAgentCardStreamMessage):
204
385
 
205
386
 
206
387
  class BaseAgentToolMessage(BaseStepMessage):
388
+ """
389
+ Base class for tool execution messages.
390
+
391
+ Tool messages track the lifecycle of external tool or service
392
+ calls made by agents during pipeline execution.
393
+ """
394
+
207
395
  id: str
208
396
  name: str
209
397
 
210
398
 
211
399
  class AgentToolRequestMessage(BaseAgentToolMessage):
400
+ """
401
+ Message indicating that a tool request has been initiated.
402
+
403
+ This message is sent when an agent begins calling an external
404
+ tool or service to perform a specific operation.
405
+ """
406
+
212
407
  message_type: MessageType = MessageType.AGENT_TOOL_REQUEST
213
408
 
214
409
 
215
410
  class AgentToolResponseMessage(BaseAgentToolMessage):
411
+ """
412
+ Message indicating that a tool request has completed.
413
+
414
+ This message contains the results and timing information
415
+ from a completed tool or service call.
416
+ """
417
+
216
418
  message_type: MessageType = MessageType.AGENT_TOOL_RESPONSE
217
419
  duration: time
218
420
  success: bool
@@ -246,6 +448,7 @@ SSEMessage = Union[
246
448
  AgentToolRequestMessage,
247
449
  AgentToolResponseMessage,
248
450
  ]
451
+ """Union type representing all possible SSE message types from the Airia API."""
249
452
 
250
453
  SSEDict = {
251
454
  MessageType.AGENT_PING.value: AgentPingMessage,
@@ -274,3 +477,9 @@ SSEDict = {
274
477
  MessageType.AGENT_TOOL_REQUEST.value: AgentToolRequestMessage,
275
478
  MessageType.AGENT_TOOL_RESPONSE.value: AgentToolResponseMessage,
276
479
  }
480
+ """
481
+ Mapping from message type strings to their corresponding Pydantic model classes.
482
+
483
+ This dictionary is used by the SSE parser to instantiate the correct message
484
+ type based on the 'event' field in incoming SSE data.
485
+ """
airia/utils/sse_parser.py CHANGED
@@ -1,3 +1,11 @@
1
+ """
2
+ Server-Sent Events (SSE) stream parsing utilities.
3
+
4
+ This module provides functions for parsing SSE streams from both synchronous and
5
+ asynchronous HTTP responses. It handles the SSE protocol format and converts
6
+ raw stream data into typed message objects.
7
+ """
8
+
1
9
  import json
2
10
  import re
3
11
  from typing import AsyncIterable, AsyncIterator, Iterable, Iterator
@@ -5,19 +13,36 @@ from typing import AsyncIterable, AsyncIterator, Iterable, Iterator
5
13
  from ..types.sse import SSEDict, SSEMessage
6
14
 
7
15
 
8
- def _to_snake_case(name: str):
16
+ def _to_snake_case(name: str) -> str:
17
+ """
18
+ Convert camelCase or PascalCase string to snake_case.
19
+
20
+ Args:
21
+ name: The string to convert to snake_case
22
+
23
+ Returns:
24
+ The string converted to snake_case format
25
+ """
9
26
  return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
10
27
 
11
28
 
12
29
  def parse_sse_stream_chunked(stream_chunks: Iterable[bytes]) -> Iterator[SSEMessage]:
13
30
  """
14
- Parse SSE stream from an iterable of chunks (e.g., from a streaming response).
31
+ Parse Server-Sent Events (SSE) stream from an iterable of byte chunks.
32
+
33
+ This function processes streaming data from HTTP responses that follow the SSE protocol,
34
+ parsing event blocks and converting them into typed SSE message objects. It handles
35
+ incomplete chunks by buffering data until complete events are received.
15
36
 
16
37
  Args:
17
- stream_chunks: Iterable of string chunks
38
+ stream_chunks: An iterable of byte chunks from an HTTP streaming response
18
39
 
19
40
  Yields:
20
- dict: Dictionary containing 'event' and 'data' keys
41
+ SSEMessage: Typed SSE message objects corresponding to the parsed events
42
+
43
+ Note:
44
+ Events are expected to follow the SSE format with 'event:' and 'data:' lines,
45
+ terminated by double newlines (\n\n). The data portion should contain valid JSON.
21
46
  """
22
47
  buffer = ""
23
48
 
@@ -53,13 +78,21 @@ async def async_parse_sse_stream_chunked(
53
78
  stream_chunks: AsyncIterable[bytes],
54
79
  ) -> AsyncIterator[SSEMessage]:
55
80
  """
56
- Parse SSE stream from an iterable of chunks (e.g., from a streaming response).
81
+ Asynchronously parse Server-Sent Events (SSE) stream from an async iterable of byte chunks.
82
+
83
+ This is the async version of parse_sse_stream_chunked, designed for use with
84
+ asynchronous HTTP clients. It processes streaming data that follows the SSE protocol,
85
+ parsing event blocks and converting them into typed SSE message objects.
57
86
 
58
87
  Args:
59
- stream_chunks: Iterable of string chunks
88
+ stream_chunks: An async iterable of byte chunks from an HTTP streaming response
60
89
 
61
90
  Yields:
62
- dict: Dictionary containing 'event' and 'data' keys
91
+ SSEMessage: Typed SSE message objects corresponding to the parsed events
92
+
93
+ Note:
94
+ Events are expected to follow the SSE format with 'event:' and 'data:' lines,
95
+ terminated by double newlines (\n\n). The data portion should contain valid JSON.
63
96
  """
64
97
  buffer = ""
65
98
 
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: airia
3
+ Version: 0.1.14
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
+ [![PyPI version](https://badge.fury.io/py/airia.svg)](https://badge.fury.io/py/airia)
34
+ [![Python versions](https://img.shields.io/pypi/pyversions/airia.svg)](https://pypi.org/project/airia/)
35
+ [![License](https://img.shields.io/pypi/l/airia.svg)](https://pypi.org/project/airia/)
36
+
37
+ The Airia Python library provides a clean and intuitive interface to interact with Airia API. The library offers both synchronous and asynchronous clients for maximum flexibility in your applications.
38
+
39
+ ## Features
40
+
41
+ - **Dual Client Support**: Choose between synchronous (`AiriaClient`) and asynchronous (`AiriaAsyncClient`) implementations
42
+ - **Pipeline Execution**: Easily run AI pipelines with customizable parameters
43
+ - **Gateway Support**: Seamlessly integrate with OpenAI and Anthropic services through Airia gateways
44
+ - **Error Handling**: Comprehensive error handling with custom exceptions
45
+ - **Logging**: Built-in configurable logging with correlation ID support for request tracing
46
+ - **Flexible Authentication**: Support for both API keys and bearer tokens with flexible configuration
47
+
48
+ ## Documentation and Quick Start Guides
49
+
50
+ Full documentation and quick start guides are available [here](https://airiallc.github.io/airia-python).
51
+
52
+ You can also run the documentation page locally with `mkdocs`:
53
+
54
+ 1. [Install development dependencies](#install-with-development-dependencies)
55
+ 2. Run `mkdocs serve` to start the local server
56
+
57
+ ## Installation
58
+
59
+ You can install the package using pip or uv:
60
+
61
+ <table>
62
+ <tr>
63
+ <th>pip</th>
64
+ <th>uv</th>
65
+ </tr>
66
+ <tr>
67
+ <td>
68
+
69
+ ```bash
70
+ pip install airia
71
+ ```
72
+
73
+ </td>
74
+ <td>
75
+
76
+ ```bash
77
+ uv add airia
78
+ ```
79
+
80
+ </td>
81
+ </tr>
82
+ </table>
83
+
84
+ ### Install with optional dependencies
85
+
86
+ The package supports optional dependencies for gateway functionality:
87
+
88
+ <table>
89
+ <tr>
90
+ <th>OpenAI Gateway</th>
91
+ <th>Anthropic Gateway</th>
92
+ <th>All Gateways</th>
93
+ </tr>
94
+ <tr>
95
+ <td>
96
+
97
+ ```bash
98
+ pip install "airia[openai]"
99
+ ```
100
+
101
+ </td>
102
+ <td>
103
+
104
+ ```bash
105
+ pip install "airia[anthropic]"
106
+ ```
107
+
108
+ </td>
109
+ <td>
110
+
111
+ ```bash
112
+ pip install "airia[all]"
113
+ ```
114
+
115
+ </td>
116
+ </tr>
117
+ </table>
118
+
119
+ ### Install with development dependencies
120
+
121
+ Clone the repository:
122
+
123
+ ```bash
124
+ git clone https://github.com/AiriaLLC/airia-python.git
125
+ cd airia-python
126
+ ```
127
+
128
+ Then, run one of the following commands:
129
+
130
+ <table>
131
+ <tr>
132
+ <th>pip</th>
133
+ <th>uv</th>
134
+ </tr>
135
+ <tr>
136
+ <td>
137
+
138
+ ```bash
139
+ pip install dependency-groups
140
+ dev=$(python -m dependency_groups dev)
141
+ pip install -e .
142
+ pip install $dev
143
+ ```
144
+
145
+ </td>
146
+ <td>
147
+
148
+ ```bash
149
+ uv sync --frozen --group dev
150
+ ```
151
+
152
+ </td>
153
+ </tr>
154
+ </table>
155
+
156
+ ## Building from Source
157
+
158
+ First make sure you have already cloned the repository, then run one of the following commands:
159
+
160
+ <table>
161
+ <tr>
162
+ <th>pip</th>
163
+ <th>uv</th>
164
+ </tr>
165
+ <tr>
166
+ <td>
167
+
168
+ ```bash
169
+ pip install build
170
+ python -m build
171
+ ```
172
+
173
+ </td>
174
+ <td>
175
+
176
+ ```bash
177
+ uv build
178
+ ```
179
+
180
+ </td>
181
+ </tr>
182
+ </table>
183
+
184
+ This will create both wheel and source distribution in the `dist/` directory.
185
+
186
+ ## Requirements
187
+
188
+ - Python 3.9 or higher
189
+ - Core dependencies:
190
+ - requests
191
+ - aiohttp
192
+ - loguru
193
+ - pydantic
194
+
195
+ - Optional dependencies:
196
+ - OpenAI gateway: `openai>=1.74.0`
197
+ - Anthropic gateway: `anthropic>=0.49.0`
198
+
199
+ ## Development
200
+
201
+ To run tests (make sure you have development dependencies installed):
202
+
203
+ ```bash
204
+ pytest
205
+ ```
206
+
207
+ For testing gateway functionality, install the optional dependencies:
208
+
209
+ ```bash
210
+ # For OpenAI gateway tests
211
+ pip install -e .[openai]
212
+ pytest tests/test_openai_gateway.py
213
+
214
+ # For Anthropic gateway tests
215
+ pip install -e .[anthropic]
216
+ pytest tests/test_anthropic_gateway.py
217
+
218
+ # For all tests
219
+ pip install -e .[all]
220
+ pytest
221
+ ```