airia 0.1.7__tar.gz → 0.1.9__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.7 → airia-0.1.9}/PKG-INFO +1 -1
- {airia-0.1.7 → airia-0.1.9}/airia/client/async_client.py +121 -35
- {airia-0.1.7 → airia-0.1.9}/airia/client/base_client.py +50 -35
- {airia-0.1.7 → airia-0.1.9}/airia/client/sync_client.py +107 -21
- {airia-0.1.7 → airia-0.1.9}/airia/types/__init__.py +2 -0
- {airia-0.1.7 → airia-0.1.9}/airia/types/api/get_pipeline_config.py +40 -5
- airia-0.1.9/airia/types/api/get_projects.py +35 -0
- {airia-0.1.7 → airia-0.1.9}/airia/types/request_data.py +1 -0
- {airia-0.1.7 → airia-0.1.9}/airia.egg-info/PKG-INFO +1 -1
- {airia-0.1.7 → airia-0.1.9}/airia.egg-info/SOURCES.txt +2 -0
- {airia-0.1.7 → airia-0.1.9}/pyproject.toml +1 -1
- {airia-0.1.7 → airia-0.1.9}/tests/test_anthropic_gateway.py +1 -1
- {airia-0.1.7 → airia-0.1.9}/tests/test_execute_pipeline.py +1 -1
- {airia-0.1.7 → airia-0.1.9}/tests/test_get_active_pipelines_ids.py +29 -12
- {airia-0.1.7 → airia-0.1.9}/tests/test_get_pipeline_config.py +1 -1
- airia-0.1.9/tests/test_get_projects.py +203 -0
- {airia-0.1.7 → airia-0.1.9}/tests/test_openai_gateway.py +1 -1
- {airia-0.1.7 → airia-0.1.9}/LICENSE +0 -0
- {airia-0.1.7 → airia-0.1.9}/README.md +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/__init__.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/client/__init__.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/exceptions.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/logs.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/types/api/pipeline_execution.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/types/api_version.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/types/sse_messages.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia/utils/sse_parser.py +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia.egg-info/dependency_links.txt +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia.egg-info/requires.txt +0 -0
- {airia-0.1.7 → airia-0.1.9}/airia.egg-info/top_level.txt +0 -0
- {airia-0.1.7 → airia-0.1.9}/setup.cfg +0 -0
|
@@ -14,6 +14,7 @@ from ..types import (
|
|
|
14
14
|
PipelineExecutionResponse,
|
|
15
15
|
PipelineExecutionV1StreamedResponse,
|
|
16
16
|
PipelineExecutionV2AsyncStreamedResponse,
|
|
17
|
+
ProjectItem,
|
|
17
18
|
RequestData,
|
|
18
19
|
)
|
|
19
20
|
from ..utils.sse_parser import async_parse_sse_stream_chunked
|
|
@@ -199,6 +200,7 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
199
200
|
method=method,
|
|
200
201
|
url=request_data.url,
|
|
201
202
|
json=request_data.payload,
|
|
203
|
+
params=request_data.params,
|
|
202
204
|
headers=request_data.headers,
|
|
203
205
|
timeout=self.timeout,
|
|
204
206
|
) as response:
|
|
@@ -250,6 +252,7 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
250
252
|
method=method,
|
|
251
253
|
url=request_data.url,
|
|
252
254
|
json=request_data.payload,
|
|
255
|
+
params=request_data.params,
|
|
253
256
|
headers=request_data.headers,
|
|
254
257
|
timeout=self.timeout,
|
|
255
258
|
chunked=True,
|
|
@@ -419,11 +422,11 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
419
422
|
aiohttp.ClientError: For other request-related errors.
|
|
420
423
|
|
|
421
424
|
Example:
|
|
422
|
-
>>>
|
|
423
|
-
...
|
|
424
|
-
...
|
|
425
|
-
...
|
|
426
|
-
...
|
|
425
|
+
>>> client = AiriaAsyncClient(api_key="your_api_key")
|
|
426
|
+
... response = await client.execute_pipeline(
|
|
427
|
+
... pipeline_id="pipeline_123",
|
|
428
|
+
... user_input="Tell me about quantum computing"
|
|
429
|
+
... )
|
|
427
430
|
>>> print(response.result)
|
|
428
431
|
"""
|
|
429
432
|
request_data = self._pre_execute_pipeline(
|
|
@@ -462,9 +465,9 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
462
465
|
self.base_url, f"{api_version}/StreamSocketConfig/GenerateUrl"
|
|
463
466
|
)
|
|
464
467
|
request_data = self._prepare_request(
|
|
465
|
-
url,
|
|
466
|
-
{"socketIdentifier": resp},
|
|
467
|
-
request_data.headers["X-Correlation-ID"],
|
|
468
|
+
url=url,
|
|
469
|
+
payload={"socketIdentifier": resp},
|
|
470
|
+
correlation_id=request_data.headers["X-Correlation-ID"],
|
|
468
471
|
)
|
|
469
472
|
resp = await self._make_request("POST", request_data)
|
|
470
473
|
|
|
@@ -472,43 +475,126 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
472
475
|
|
|
473
476
|
return PipelineExecutionV2AsyncStreamedResponse(stream=resp)
|
|
474
477
|
|
|
478
|
+
async def get_projects(
|
|
479
|
+
self,
|
|
480
|
+
correlation_id: Optional[str] = None,
|
|
481
|
+
api_version: str = ApiVersion.V1.value,
|
|
482
|
+
) -> List[ProjectItem]:
|
|
483
|
+
"""
|
|
484
|
+
Retrieve a list of all projects accessible to the authenticated user.
|
|
485
|
+
|
|
486
|
+
This method fetches comprehensive information about all projects that the
|
|
487
|
+
current user has access to, including project metadata, creation details,
|
|
488
|
+
and status information.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
correlation_id (str, optional): A unique identifier for request tracing
|
|
492
|
+
and logging. If not provided, one will be automatically generated.
|
|
493
|
+
api_version (str, optional): The API version to use for the request.
|
|
494
|
+
Defaults to "v1". Valid versions are defined in ApiVersion enum.
|
|
495
|
+
|
|
496
|
+
Returns:
|
|
497
|
+
List[ProjectItem]: A list of ProjectItem objects containing project
|
|
498
|
+
information. Returns an empty list if no projects are accessible
|
|
499
|
+
or found.
|
|
500
|
+
|
|
501
|
+
Raises:
|
|
502
|
+
ValueError: If the provided api_version is not valid.
|
|
503
|
+
AiriaAPIError: If the API request fails, including cases where:
|
|
504
|
+
- Authentication fails (401)
|
|
505
|
+
- Access is forbidden (403)
|
|
506
|
+
- Server errors (5xx)
|
|
507
|
+
|
|
508
|
+
Example:
|
|
509
|
+
```python
|
|
510
|
+
from airia import AiriaAsyncClient
|
|
511
|
+
|
|
512
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
513
|
+
|
|
514
|
+
# Get all accessible projects
|
|
515
|
+
projects = await client.get_projects()
|
|
516
|
+
|
|
517
|
+
for project in projects:
|
|
518
|
+
print(f"Project: {project.name}")
|
|
519
|
+
print(f"ID: {project.id}")
|
|
520
|
+
print(f"Description: {project.description}")
|
|
521
|
+
print(f"Created: {project.created_at}")
|
|
522
|
+
print("---")
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Note:
|
|
526
|
+
The returned projects are filtered based on the authenticated user's
|
|
527
|
+
permissions. Users will only see projects they have been granted
|
|
528
|
+
access to.
|
|
529
|
+
"""
|
|
530
|
+
request_data = self._pre_get_projects(
|
|
531
|
+
correlation_id=correlation_id, api_version=api_version
|
|
532
|
+
)
|
|
533
|
+
resp = await self._make_request("GET", request_data)
|
|
534
|
+
|
|
535
|
+
if "items" not in resp or len(resp["items"]) == 0:
|
|
536
|
+
return []
|
|
537
|
+
|
|
538
|
+
return [ProjectItem(**item) for item in resp["items"]]
|
|
539
|
+
|
|
475
540
|
async def get_active_pipelines_ids(
|
|
476
541
|
self,
|
|
542
|
+
project_id: Optional[str] = None,
|
|
477
543
|
correlation_id: Optional[str] = None,
|
|
478
544
|
api_version: str = ApiVersion.V1.value,
|
|
479
545
|
) -> List[str]:
|
|
480
546
|
"""
|
|
481
547
|
Retrieve a list of active pipeline IDs.
|
|
482
|
-
|
|
483
|
-
This method fetches all
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
548
|
+
|
|
549
|
+
This method fetches the IDs of all active pipelines, optionally filtered by project.
|
|
550
|
+
Active pipelines are those that are currently deployed and available for execution.
|
|
551
|
+
|
|
487
552
|
Args:
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
generated.
|
|
493
|
-
|
|
553
|
+
project_id (str, optional): The unique identifier of the project to filter
|
|
554
|
+
pipelines by. If not provided, returns active pipelines from all projects
|
|
555
|
+
accessible to the authenticated user.
|
|
556
|
+
correlation_id (str, optional): A unique identifier for request tracing
|
|
557
|
+
and logging. If not provided, one will be automatically generated.
|
|
558
|
+
api_version (str, optional): The API version to use for the request.
|
|
559
|
+
Defaults to "v1". Valid versions are defined in ApiVersion enum.
|
|
560
|
+
|
|
494
561
|
Returns:
|
|
495
|
-
List[str]: A list of
|
|
496
|
-
if no active pipelines are found.
|
|
497
|
-
|
|
562
|
+
List[str]: A list of pipeline IDs that are currently active. Returns an
|
|
563
|
+
empty list if no active pipelines are found.
|
|
564
|
+
|
|
498
565
|
Raises:
|
|
499
|
-
ValueError: If the provided
|
|
500
|
-
AiriaAPIError: If the API request fails, including
|
|
501
|
-
|
|
502
|
-
|
|
566
|
+
ValueError: If the provided api_version is not valid.
|
|
567
|
+
AiriaAPIError: If the API request fails, including cases where:
|
|
568
|
+
- The project_id doesn't exist (404)
|
|
569
|
+
- Authentication fails (401)
|
|
570
|
+
- Access is forbidden (403)
|
|
571
|
+
- Server errors (5xx)
|
|
572
|
+
|
|
503
573
|
Example:
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
574
|
+
```python
|
|
575
|
+
from airia import AiriaAsyncClient
|
|
576
|
+
|
|
577
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
578
|
+
|
|
579
|
+
# Get all active pipeline IDs
|
|
580
|
+
pipeline_ids = await client.get_active_pipelines_ids()
|
|
581
|
+
print(f"Found {len(pipeline_ids)} active pipelines")
|
|
582
|
+
|
|
583
|
+
# Get active pipeline IDs for a specific project
|
|
584
|
+
project_pipelines = await client.get_active_pipelines_ids(
|
|
585
|
+
project_id="your_project_id"
|
|
586
|
+
)
|
|
587
|
+
print(f"Project has {len(project_pipelines)} active pipelines")
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Note:
|
|
591
|
+
Only pipelines with active versions are returned. Inactive or archived
|
|
592
|
+
pipelines are not included in the results.
|
|
509
593
|
"""
|
|
510
594
|
request_data = self._pre_get_active_pipelines_ids(
|
|
511
|
-
|
|
595
|
+
project_id=project_id,
|
|
596
|
+
correlation_id=correlation_id,
|
|
597
|
+
api_version=api_version,
|
|
512
598
|
)
|
|
513
599
|
resp = await self._make_request("GET", request_data)
|
|
514
600
|
|
|
@@ -553,12 +639,12 @@ class AiriaAsyncClient(AiriaBaseClient):
|
|
|
553
639
|
|
|
554
640
|
Example:
|
|
555
641
|
```python
|
|
556
|
-
from airia import
|
|
642
|
+
from airia import AiriaAsyncClient
|
|
557
643
|
|
|
558
|
-
client =
|
|
644
|
+
client = AiriaAsyncClient(api_key="your_api_key")
|
|
559
645
|
|
|
560
646
|
# Get pipeline configuration
|
|
561
|
-
config = client.get_pipeline_config(
|
|
647
|
+
config = await client.get_pipeline_config(
|
|
562
648
|
pipeline_id="your_pipeline_id"
|
|
563
649
|
)
|
|
564
650
|
|
|
@@ -70,29 +70,9 @@ class AiriaBaseClient:
|
|
|
70
70
|
self,
|
|
71
71
|
url: str,
|
|
72
72
|
payload: Optional[Dict[str, Any]] = None,
|
|
73
|
+
params: Optional[Dict[str, Any]] = None,
|
|
73
74
|
correlation_id: Optional[str] = None,
|
|
74
75
|
):
|
|
75
|
-
"""
|
|
76
|
-
Prepare the request parameters for an API call.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
url (str): The endpoint URL for the API request.
|
|
80
|
-
payload (Optional[Dict[str, Any]]): The request payload/body to be sent.
|
|
81
|
-
correlation_id (Optional[str]): A unique identifier for tracing the request. If None, one will be generated.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
dict: A dictionary containing the prepared request parameters with the following keys:
|
|
85
|
-
- url: The request URL
|
|
86
|
-
- payload: The request payload
|
|
87
|
-
- headers: Request headers including API key and correlation ID
|
|
88
|
-
- correlation_id: The correlation ID used for the request
|
|
89
|
-
|
|
90
|
-
Note:
|
|
91
|
-
This method handles:
|
|
92
|
-
- Setting/generating correlation IDs
|
|
93
|
-
- Adding authentication headers
|
|
94
|
-
- Logging requests (if enabled) with sensitive information redacted
|
|
95
|
-
"""
|
|
96
76
|
# Set correlation ID if provided or generate a new one
|
|
97
77
|
correlation_id = set_correlation_id(correlation_id)
|
|
98
78
|
|
|
@@ -105,29 +85,27 @@ class AiriaBaseClient:
|
|
|
105
85
|
|
|
106
86
|
# Log the request if enabled
|
|
107
87
|
if self.log_requests:
|
|
108
|
-
# Create a sanitized copy of headers for logging
|
|
88
|
+
# Create a sanitized copy of headers and params for logging
|
|
109
89
|
log_headers = headers.copy()
|
|
90
|
+
log_params = params.copy() if params is not None else {}
|
|
110
91
|
|
|
111
92
|
# Filter out sensitive headers
|
|
112
93
|
if "X-API-KEY" in log_headers:
|
|
113
94
|
log_headers["X-API-KEY"] = "[REDACTED]"
|
|
114
95
|
|
|
115
96
|
# Process payload for logging
|
|
116
|
-
log_payload = None
|
|
117
|
-
if
|
|
118
|
-
log_payload =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if "files" in log_payload and log_payload["files"] is not None:
|
|
123
|
-
log_payload["files"] = f"{len(log_payload['files'])} files"
|
|
124
|
-
|
|
125
|
-
log_payload = json.dumps(log_payload)
|
|
97
|
+
log_payload = payload.copy() if payload is not None else {}
|
|
98
|
+
if "images" in log_payload and log_payload["images"] is not None:
|
|
99
|
+
log_payload["images"] = f"{len(log_payload['images'])} images"
|
|
100
|
+
if "files" in log_payload and log_payload["files"] is not None:
|
|
101
|
+
log_payload["files"] = f"{len(log_payload['files'])} files"
|
|
102
|
+
log_payload = json.dumps(log_payload)
|
|
126
103
|
|
|
127
104
|
self.logger.info(
|
|
128
105
|
f"API Request: POST {url}\n"
|
|
129
106
|
f"Headers: {json.dumps(log_headers)}\n"
|
|
130
107
|
f"Payload: {log_payload}"
|
|
108
|
+
f"Params: {json.dumps(log_params)}\n"
|
|
131
109
|
)
|
|
132
110
|
|
|
133
111
|
return RequestData(
|
|
@@ -135,6 +113,7 @@ class AiriaBaseClient:
|
|
|
135
113
|
"url": url,
|
|
136
114
|
"payload": payload,
|
|
137
115
|
"headers": headers,
|
|
116
|
+
"params": params,
|
|
138
117
|
"correlation_id": correlation_id,
|
|
139
118
|
}
|
|
140
119
|
)
|
|
@@ -184,12 +163,29 @@ class AiriaBaseClient:
|
|
|
184
163
|
"promptVariables": prompt_variables,
|
|
185
164
|
}
|
|
186
165
|
|
|
187
|
-
request_data = self._prepare_request(
|
|
166
|
+
request_data = self._prepare_request(
|
|
167
|
+
url=url, payload=payload, correlation_id=correlation_id
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return request_data
|
|
171
|
+
|
|
172
|
+
def _pre_get_projects(
|
|
173
|
+
self,
|
|
174
|
+
correlation_id: Optional[str] = None,
|
|
175
|
+
api_version: str = ApiVersion.V1.value,
|
|
176
|
+
):
|
|
177
|
+
if api_version not in ApiVersion.as_list():
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
|
|
180
|
+
)
|
|
181
|
+
url = urljoin(self.base_url, f"{api_version}/Project/paginated")
|
|
182
|
+
request_data = self._prepare_request(url, correlation_id=correlation_id)
|
|
188
183
|
|
|
189
184
|
return request_data
|
|
190
185
|
|
|
191
186
|
def _pre_get_active_pipelines_ids(
|
|
192
187
|
self,
|
|
188
|
+
project_id: Optional[str] = None,
|
|
193
189
|
correlation_id: Optional[str] = None,
|
|
194
190
|
api_version: str = ApiVersion.V1.value,
|
|
195
191
|
):
|
|
@@ -198,7 +194,10 @@ class AiriaBaseClient:
|
|
|
198
194
|
f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
|
|
199
195
|
)
|
|
200
196
|
url = urljoin(self.base_url, f"{api_version}/PipelinesConfig")
|
|
201
|
-
|
|
197
|
+
params = {"projectId": project_id} if project_id is not None else None
|
|
198
|
+
request_data = self._prepare_request(
|
|
199
|
+
url, params=params, correlation_id=correlation_id
|
|
200
|
+
)
|
|
202
201
|
|
|
203
202
|
return request_data
|
|
204
203
|
|
|
@@ -212,7 +211,23 @@ class AiriaBaseClient:
|
|
|
212
211
|
raise ValueError(
|
|
213
212
|
f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
|
|
214
213
|
)
|
|
215
|
-
url = urljoin(
|
|
214
|
+
url = urljoin(
|
|
215
|
+
self.base_url, f"{api_version}/PipelinesConfig/export/{pipeline_id}"
|
|
216
|
+
)
|
|
217
|
+
request_data = self._prepare_request(url, correlation_id=correlation_id)
|
|
218
|
+
|
|
219
|
+
return request_data
|
|
220
|
+
|
|
221
|
+
def _pre_get_projects(
|
|
222
|
+
self,
|
|
223
|
+
correlation_id: Optional[str] = None,
|
|
224
|
+
api_version: str = ApiVersion.V1.value,
|
|
225
|
+
):
|
|
226
|
+
if api_version not in ApiVersion.as_list():
|
|
227
|
+
raise ValueError(
|
|
228
|
+
f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
|
|
229
|
+
)
|
|
230
|
+
url = urljoin(self.base_url, f"{api_version}/Project/paginated")
|
|
216
231
|
request_data = self._prepare_request(url, correlation_id=correlation_id)
|
|
217
232
|
|
|
218
233
|
return request_data
|
|
@@ -12,6 +12,7 @@ from ..types import (
|
|
|
12
12
|
PipelineExecutionResponse,
|
|
13
13
|
PipelineExecutionV1StreamedResponse,
|
|
14
14
|
PipelineExecutionV2StreamedResponse,
|
|
15
|
+
ProjectItem,
|
|
15
16
|
RequestData,
|
|
16
17
|
)
|
|
17
18
|
from ..utils.sse_parser import parse_sse_stream_chunked
|
|
@@ -181,6 +182,7 @@ class AiriaClient(AiriaBaseClient):
|
|
|
181
182
|
method=method,
|
|
182
183
|
url=request_data.url,
|
|
183
184
|
json=request_data.payload,
|
|
185
|
+
params=request_data.params,
|
|
184
186
|
headers=request_data.headers,
|
|
185
187
|
timeout=self.timeout,
|
|
186
188
|
)
|
|
@@ -231,6 +233,7 @@ class AiriaClient(AiriaBaseClient):
|
|
|
231
233
|
response = self.session.request(
|
|
232
234
|
method=method,
|
|
233
235
|
url=request_data.url,
|
|
236
|
+
params=request_data.params,
|
|
234
237
|
json=request_data.payload,
|
|
235
238
|
headers=request_data.headers,
|
|
236
239
|
timeout=self.timeout,
|
|
@@ -445,8 +448,8 @@ class AiriaClient(AiriaBaseClient):
|
|
|
445
448
|
)
|
|
446
449
|
request_data = self._prepare_request(
|
|
447
450
|
url,
|
|
448
|
-
{"socketIdentifier": resp},
|
|
449
|
-
request_data.headers["X-Correlation-ID"],
|
|
451
|
+
payload={"socketIdentifier": resp},
|
|
452
|
+
correlation_id=request_data.headers["X-Correlation-ID"],
|
|
450
453
|
)
|
|
451
454
|
resp = self._make_request("POST", request_data)
|
|
452
455
|
|
|
@@ -454,43 +457,126 @@ class AiriaClient(AiriaBaseClient):
|
|
|
454
457
|
|
|
455
458
|
return PipelineExecutionV2StreamedResponse(stream=resp)
|
|
456
459
|
|
|
460
|
+
def get_projects(
|
|
461
|
+
self,
|
|
462
|
+
correlation_id: Optional[str] = None,
|
|
463
|
+
api_version: str = ApiVersion.V1.value,
|
|
464
|
+
) -> List[ProjectItem]:
|
|
465
|
+
"""
|
|
466
|
+
Retrieve a list of all projects accessible to the authenticated user.
|
|
467
|
+
|
|
468
|
+
This method fetches comprehensive information about all projects that the
|
|
469
|
+
current user has access to, including project metadata, creation details,
|
|
470
|
+
and status information.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
correlation_id (str, optional): A unique identifier for request tracing
|
|
474
|
+
and logging. If not provided, one will be automatically generated.
|
|
475
|
+
api_version (str, optional): The API version to use for the request.
|
|
476
|
+
Defaults to "v1". Valid versions are defined in ApiVersion enum.
|
|
477
|
+
|
|
478
|
+
Returns:
|
|
479
|
+
List[ProjectItem]: A list of ProjectItem objects containing project
|
|
480
|
+
information. Returns an empty list if no projects are accessible
|
|
481
|
+
or found.
|
|
482
|
+
|
|
483
|
+
Raises:
|
|
484
|
+
ValueError: If the provided api_version is not valid.
|
|
485
|
+
AiriaAPIError: If the API request fails, including cases where:
|
|
486
|
+
- Authentication fails (401)
|
|
487
|
+
- Access is forbidden (403)
|
|
488
|
+
- Server errors (5xx)
|
|
489
|
+
|
|
490
|
+
Example:
|
|
491
|
+
```python
|
|
492
|
+
from airia import AiriaClient
|
|
493
|
+
|
|
494
|
+
client = AiriaClient(api_key="your_api_key")
|
|
495
|
+
|
|
496
|
+
# Get all accessible projects
|
|
497
|
+
projects = client.get_projects()
|
|
498
|
+
|
|
499
|
+
for project in projects:
|
|
500
|
+
print(f"Project: {project.name}")
|
|
501
|
+
print(f"ID: {project.id}")
|
|
502
|
+
print(f"Description: {project.description}")
|
|
503
|
+
print(f"Created: {project.created_at}")
|
|
504
|
+
print("---")
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Note:
|
|
508
|
+
The returned projects are filtered based on the authenticated user's
|
|
509
|
+
permissions. Users will only see projects they have been granted
|
|
510
|
+
access to.
|
|
511
|
+
"""
|
|
512
|
+
request_data = self._pre_get_projects(
|
|
513
|
+
correlation_id=correlation_id, api_version=api_version
|
|
514
|
+
)
|
|
515
|
+
resp = self._make_request("GET", request_data)
|
|
516
|
+
|
|
517
|
+
if "items" not in resp or len(resp["items"]) == 0:
|
|
518
|
+
return []
|
|
519
|
+
|
|
520
|
+
return [ProjectItem(**item) for item in resp["items"]]
|
|
521
|
+
|
|
457
522
|
def get_active_pipelines_ids(
|
|
458
523
|
self,
|
|
524
|
+
project_id: Optional[str] = None,
|
|
459
525
|
correlation_id: Optional[str] = None,
|
|
460
526
|
api_version: str = ApiVersion.V1.value,
|
|
461
527
|
) -> List[str]:
|
|
462
528
|
"""
|
|
463
529
|
Retrieve a list of active pipeline IDs.
|
|
464
530
|
|
|
465
|
-
This method fetches all
|
|
466
|
-
|
|
467
|
-
get_pipeline_config().
|
|
531
|
+
This method fetches the IDs of all active pipelines, optionally filtered by project.
|
|
532
|
+
Active pipelines are those that are currently deployed and available for execution.
|
|
468
533
|
|
|
469
534
|
Args:
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
generated.
|
|
535
|
+
project_id (str, optional): The unique identifier of the project to filter
|
|
536
|
+
pipelines by. If not provided, returns active pipelines from all projects
|
|
537
|
+
accessible to the authenticated user.
|
|
538
|
+
correlation_id (str, optional): A unique identifier for request tracing
|
|
539
|
+
and logging. If not provided, one will be automatically generated.
|
|
540
|
+
api_version (str, optional): The API version to use for the request.
|
|
541
|
+
Defaults to "v1". Valid versions are defined in ApiVersion enum.
|
|
475
542
|
|
|
476
543
|
Returns:
|
|
477
|
-
List[str]: A list of
|
|
478
|
-
if no active pipelines are found.
|
|
544
|
+
List[str]: A list of pipeline IDs that are currently active. Returns an
|
|
545
|
+
empty list if no active pipelines are found.
|
|
479
546
|
|
|
480
547
|
Raises:
|
|
481
|
-
ValueError: If the provided
|
|
482
|
-
AiriaAPIError: If the API request fails, including
|
|
483
|
-
|
|
548
|
+
ValueError: If the provided api_version is not valid.
|
|
549
|
+
AiriaAPIError: If the API request fails, including cases where:
|
|
550
|
+
- The project_id doesn't exist (404)
|
|
551
|
+
- Authentication fails (401)
|
|
552
|
+
- Access is forbidden (403)
|
|
553
|
+
- Server errors (5xx)
|
|
484
554
|
|
|
485
555
|
Example:
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
556
|
+
```python
|
|
557
|
+
from airia import AiriaClient
|
|
558
|
+
|
|
559
|
+
client = AiriaClient(api_key="your_api_key")
|
|
560
|
+
|
|
561
|
+
# Get all active pipeline IDs
|
|
562
|
+
pipeline_ids = client.get_active_pipelines_ids()
|
|
563
|
+
print(f"Found {len(pipeline_ids)} active pipelines")
|
|
564
|
+
|
|
565
|
+
# Get active pipeline IDs for a specific project
|
|
566
|
+
project_pipelines = client.get_active_pipelines_ids(
|
|
567
|
+
project_id="your_project_id"
|
|
568
|
+
)
|
|
569
|
+
print(f"Project has {len(project_pipelines)} active pipelines")
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
Note:
|
|
573
|
+
Only pipelines with active versions are returned. Inactive or archived
|
|
574
|
+
pipelines are not included in the results.
|
|
491
575
|
"""
|
|
492
576
|
request_data = self._pre_get_active_pipelines_ids(
|
|
493
|
-
|
|
577
|
+
project_id=project_id,
|
|
578
|
+
correlation_id=correlation_id,
|
|
579
|
+
api_version=api_version,
|
|
494
580
|
)
|
|
495
581
|
resp = self._make_request("GET", request_data)
|
|
496
582
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from .api.get_projects import ProjectItem
|
|
1
2
|
from .api.get_pipeline_config import GetPipelineConfigResponse
|
|
2
3
|
from .api.pipeline_execution import (
|
|
3
4
|
PipelineExecutionDebugResponse,
|
|
@@ -43,6 +44,7 @@ __all__ = [
|
|
|
43
44
|
"PipelineExecutionV2AsyncStreamedResponse",
|
|
44
45
|
"PipelineExecutionV2StreamedResponse",
|
|
45
46
|
"GetPipelineConfigResponse",
|
|
47
|
+
"ProjectItem",
|
|
46
48
|
"RequestData",
|
|
47
49
|
"AgentPingMessage",
|
|
48
50
|
"AgentStartMessage",
|
|
@@ -75,7 +75,9 @@ class Tool(BaseModel):
|
|
|
75
75
|
tool_description: str = Field(alias="toolDescription")
|
|
76
76
|
purpose: str
|
|
77
77
|
api_endpoint: str = Field(alias="apiEndpoint")
|
|
78
|
-
credentials_definition: CredentialsDefinition = Field(
|
|
78
|
+
credentials_definition: Optional[CredentialsDefinition] = Field(
|
|
79
|
+
alias="credentialsDefinition"
|
|
80
|
+
)
|
|
79
81
|
headers_definition: List[HeaderDefinition] = Field(alias="headersDefinition")
|
|
80
82
|
body: str
|
|
81
83
|
parameters_definition: List[ParameterDefinition] = Field(
|
|
@@ -99,7 +101,9 @@ class Model(BaseModel):
|
|
|
99
101
|
url: str
|
|
100
102
|
input_type: str = Field(alias="inputType")
|
|
101
103
|
provider: str
|
|
102
|
-
credentials_definition: CredentialsDefinition = Field(
|
|
104
|
+
credentials_definition: Optional[CredentialsDefinition] = Field(
|
|
105
|
+
alias="credentialsDefinition"
|
|
106
|
+
)
|
|
103
107
|
deployment_type: str = Field(alias="deploymentType")
|
|
104
108
|
source_type: str = Field(alias="sourceType")
|
|
105
109
|
connection_string: Optional[str] = Field(alias="connectionString", default=None)
|
|
@@ -110,14 +114,14 @@ class Model(BaseModel):
|
|
|
110
114
|
uploaded_container_id: Optional[str] = Field(
|
|
111
115
|
alias="uploadedContainerId", default=None
|
|
112
116
|
)
|
|
113
|
-
library_model_id: str = Field(alias="libraryModelId")
|
|
117
|
+
library_model_id: Optional[str] = Field(alias="libraryModelId")
|
|
114
118
|
input_token_price: str = Field(alias="inputTokenPrice")
|
|
115
119
|
output_token_price: str = Field(alias="outputTokenPrice")
|
|
116
120
|
token_units: int = Field(alias="tokenUnits")
|
|
117
121
|
has_tool_support: bool = Field(alias="hasToolSupport")
|
|
118
122
|
allow_airia_credentials: bool = Field(alias="allowAiriaCredentials")
|
|
119
123
|
allow_byok_credentials: bool = Field(alias="allowBYOKCredentials")
|
|
120
|
-
author: str
|
|
124
|
+
author: Optional[str]
|
|
121
125
|
price_type: str = Field(alias="priceType")
|
|
122
126
|
|
|
123
127
|
|
|
@@ -133,10 +137,41 @@ class Router(BaseModel):
|
|
|
133
137
|
router_config: Dict[str, Dict[str, Any]] = Field(alias="routerConfig")
|
|
134
138
|
|
|
135
139
|
|
|
140
|
+
class ChunkingConfig(BaseModel):
|
|
141
|
+
id: str
|
|
142
|
+
chunk_size: int = Field(alias="chunkSize")
|
|
143
|
+
chunk_overlap: int = Field(alias="chunkOverlap")
|
|
144
|
+
strategy_type: str = Field(alias="strategyType")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class DataSourceFile(BaseModel):
|
|
148
|
+
data_source_id: str = Field(alias="dataSourceId")
|
|
149
|
+
file_path: Optional[str] = Field(None, alias="filePath")
|
|
150
|
+
input_token: Optional[str] = Field(None, alias="inputToken")
|
|
151
|
+
file_count: Optional[int] = Field(None, alias="fileCount")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class DataSource(BaseModel):
|
|
155
|
+
id: str = Field(alias="id")
|
|
156
|
+
name: Optional[str] = None
|
|
157
|
+
execution_name: Optional[str] = Field(None, alias="executionName")
|
|
158
|
+
chunking_config: ChunkingConfig = Field(alias="chunkingConfig")
|
|
159
|
+
data_source_type: str = Field(alias="dataSourceType")
|
|
160
|
+
database_type: str = Field(alias="databaseType")
|
|
161
|
+
embedding_provider: str = Field(alias="embeddingProvider")
|
|
162
|
+
is_user_specific: bool = Field(alias="isUserSpecific")
|
|
163
|
+
files: Optional[List[DataSourceFile]] = None
|
|
164
|
+
configuration_json: Optional[str] = Field(None, alias="configurationJson")
|
|
165
|
+
credentials: Optional[CredentialsDefinition]
|
|
166
|
+
is_image_processing_enabled: bool = Field(alias="isImageProcessingEnabled")
|
|
167
|
+
|
|
168
|
+
|
|
136
169
|
class GetPipelineConfigResponse(BaseModel):
|
|
137
170
|
metadata: Metadata
|
|
138
171
|
agent: Agent
|
|
139
|
-
data_sources: Optional[List[
|
|
172
|
+
data_sources: Optional[List[DataSource]] = Field(
|
|
173
|
+
alias="dataSources", default_factory=list
|
|
174
|
+
)
|
|
140
175
|
prompts: Optional[List[Prompt]] = Field(default_factory=list)
|
|
141
176
|
tools: Optional[List[Tool]] = Field(default_factory=list)
|
|
142
177
|
models: Optional[List[Model]] = Field(default_factory=list)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Pipeline(BaseModel):
|
|
8
|
+
id: str
|
|
9
|
+
name: str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProjectItem(BaseModel):
|
|
13
|
+
tenant_id: str = Field(alias="tenantId")
|
|
14
|
+
created_at: datetime = Field(alias="createdAt")
|
|
15
|
+
require_classification: bool = Field(alias="requireClassification")
|
|
16
|
+
budget_amount: Optional[Any] = Field(None, alias="budgetAmount")
|
|
17
|
+
budget_period: Optional[Any] = Field(None, alias="budgetPeriod")
|
|
18
|
+
budget_alert: Optional[Any] = Field(None, alias="budgetAlert")
|
|
19
|
+
budget_stop: bool = Field(alias="budgetStop")
|
|
20
|
+
used_budget_amount: Optional[Any] = Field(None, alias="usedBudgetAmount")
|
|
21
|
+
resume_ends_at: Optional[datetime] = Field(None, alias="resumeEndsAt")
|
|
22
|
+
updated_at: datetime = Field(alias="updatedAt")
|
|
23
|
+
pipelines: List[Pipeline]
|
|
24
|
+
models: Optional[Any] = None
|
|
25
|
+
data_sources: List[Any] = Field(alias="dataSources")
|
|
26
|
+
prompts: Optional[Any] = None
|
|
27
|
+
api_keys: Optional[Any] = Field(alias="apiKeys")
|
|
28
|
+
memories: Optional[Any] = None
|
|
29
|
+
project_icon: Optional[str] = Field(None, alias="projectIcon")
|
|
30
|
+
project_icon_id: Optional[str] = Field(None, alias="projectIconId")
|
|
31
|
+
description: Optional[str] = None
|
|
32
|
+
project_type: str = Field(alias="projectType")
|
|
33
|
+
classifications: Optional[Any] = None
|
|
34
|
+
id: str
|
|
35
|
+
name: str
|
|
@@ -18,10 +18,12 @@ airia/types/api_version.py
|
|
|
18
18
|
airia/types/request_data.py
|
|
19
19
|
airia/types/sse_messages.py
|
|
20
20
|
airia/types/api/get_pipeline_config.py
|
|
21
|
+
airia/types/api/get_projects.py
|
|
21
22
|
airia/types/api/pipeline_execution.py
|
|
22
23
|
airia/utils/sse_parser.py
|
|
23
24
|
tests/test_anthropic_gateway.py
|
|
24
25
|
tests/test_execute_pipeline.py
|
|
25
26
|
tests/test_get_active_pipelines_ids.py
|
|
26
27
|
tests/test_get_pipeline_config.py
|
|
28
|
+
tests/test_get_projects.py
|
|
27
29
|
tests/test_openai_gateway.py
|
|
@@ -6,7 +6,7 @@ from dotenv import load_dotenv
|
|
|
6
6
|
|
|
7
7
|
from airia import AiriaAsyncClient, AiriaClient
|
|
8
8
|
|
|
9
|
-
load_dotenv()
|
|
9
|
+
load_dotenv(override=True)
|
|
10
10
|
PYTHON_PIPELINE = "0134da17-c5a5-4730-a576-92f8eaf0926f"
|
|
11
11
|
GPT_4O_MINI_PIPELINE = "367969f1-7a11-40f0-bab6-c8f901fdb537"
|
|
12
12
|
USER_INPUT = "test"
|
|
@@ -56,6 +56,20 @@ class TestSyncGetActivePipelineIds:
|
|
|
56
56
|
assert isinstance(result, list)
|
|
57
57
|
assert len(result) == 0
|
|
58
58
|
|
|
59
|
+
def test_get_active_pipelines_ids_with_custom_project_id(
|
|
60
|
+
self, sync_client: AiriaClient
|
|
61
|
+
):
|
|
62
|
+
"""Test using custom Project ID."""
|
|
63
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
64
|
+
mock_request.return_value = SAMPLE_PIPELINE_IDS
|
|
65
|
+
|
|
66
|
+
result = sync_client.get_active_pipelines_ids(
|
|
67
|
+
project_id="custom-project-id"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
assert result == ["pipeline-id-1", "pipeline-id-2", "pipeline-id-3"]
|
|
71
|
+
mock_request.assert_called_once()
|
|
72
|
+
|
|
59
73
|
def test_get_active_pipelines_ids_with_custom_api_version(
|
|
60
74
|
self, sync_client: AiriaClient
|
|
61
75
|
):
|
|
@@ -104,18 +118,6 @@ class TestSyncGetActivePipelineIds:
|
|
|
104
118
|
assert "Pipelines not found" in str(exc_info.value)
|
|
105
119
|
assert exc_info.value.status_code == 404
|
|
106
120
|
|
|
107
|
-
def test_get_active_pipelines_ids_network_error(self, sync_client: AiriaClient):
|
|
108
|
-
"""Test error handling for network errors."""
|
|
109
|
-
with patch.object(sync_client, "_make_request") as mock_request:
|
|
110
|
-
mock_request.side_effect = AiriaAPIError(
|
|
111
|
-
status_code=500, message="Internal server error"
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
with pytest.raises(AiriaAPIError) as exc_info:
|
|
115
|
-
sync_client.get_active_pipelines_ids()
|
|
116
|
-
|
|
117
|
-
assert exc_info.value.status_code == 500
|
|
118
|
-
|
|
119
121
|
|
|
120
122
|
class TestAsyncGetActivePipelineIds:
|
|
121
123
|
"""Test cases for asynchronous get_active_pipelines_ids method."""
|
|
@@ -166,6 +168,21 @@ class TestAsyncGetActivePipelineIds:
|
|
|
166
168
|
assert result == ["pipeline-id-1", "pipeline-id-2", "pipeline-id-3"]
|
|
167
169
|
mock_request.assert_called_once()
|
|
168
170
|
|
|
171
|
+
@pytest.mark.asyncio
|
|
172
|
+
async def test_get_active_pipelines_ids_with_custom_project_id(
|
|
173
|
+
self, async_client: AiriaClient
|
|
174
|
+
):
|
|
175
|
+
"""Test using custom Project ID."""
|
|
176
|
+
with patch.object(async_client, "_make_request") as mock_request:
|
|
177
|
+
mock_request.return_value = SAMPLE_PIPELINE_IDS
|
|
178
|
+
|
|
179
|
+
result = await async_client.get_active_pipelines_ids(
|
|
180
|
+
project_id="custom-project-id"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
assert result == ["pipeline-id-1", "pipeline-id-2", "pipeline-id-3"]
|
|
184
|
+
mock_request.assert_called_once()
|
|
185
|
+
|
|
169
186
|
@pytest.mark.asyncio
|
|
170
187
|
async def test_get_active_pipelines_ids_invalid_api_version(
|
|
171
188
|
self, async_client: AiriaAsyncClient
|
|
@@ -8,7 +8,7 @@ from airia import AiriaAPIError, AiriaAsyncClient, AiriaClient
|
|
|
8
8
|
from airia.types import GetPipelineConfigResponse
|
|
9
9
|
|
|
10
10
|
# Load environment variables for testing
|
|
11
|
-
load_dotenv()
|
|
11
|
+
load_dotenv(override=True)
|
|
12
12
|
PYTHON_PIPELINE = "0134da17-c5a5-4730-a576-92f8eaf0926f"
|
|
13
13
|
|
|
14
14
|
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from unittest.mock import patch
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import pytest_asyncio
|
|
5
|
+
from dotenv import load_dotenv
|
|
6
|
+
|
|
7
|
+
from airia import AiriaAsyncClient, AiriaClient
|
|
8
|
+
from airia.exceptions import AiriaAPIError
|
|
9
|
+
|
|
10
|
+
# Load environment variables from .env file
|
|
11
|
+
load_dotenv(override=True)
|
|
12
|
+
|
|
13
|
+
# Test constants
|
|
14
|
+
SAMPLE_PROJECTS = {
|
|
15
|
+
"items": [
|
|
16
|
+
{
|
|
17
|
+
"tenantId": "2ce49ae0-c3ff-421a-91b7-830d0c73b348",
|
|
18
|
+
"createdAt": "2025-01-22T20:00:19.8504590Z",
|
|
19
|
+
"requireClassification": False,
|
|
20
|
+
"budgetAmount": None,
|
|
21
|
+
"budgetPeriod": None,
|
|
22
|
+
"budgetAlert": None,
|
|
23
|
+
"budgetStop": False,
|
|
24
|
+
"usedBudgetAmount": None,
|
|
25
|
+
"resumeEndsAt": None,
|
|
26
|
+
"updatedAt": "2025-01-22T20:00:19.8509410Z",
|
|
27
|
+
"pipelines": [
|
|
28
|
+
{
|
|
29
|
+
"id": "940275e2-7eae-4bc9-9830-4ef595727b87",
|
|
30
|
+
"name": "Cloudkit Records",
|
|
31
|
+
},
|
|
32
|
+
{"id": "b8c24cc9-39de-4e76-b7dd-debac381d1a8", "name": "RAG_test"},
|
|
33
|
+
{
|
|
34
|
+
"id": "17554b31-2370-4d2d-91de-4fe4805b9ef9",
|
|
35
|
+
"name": "Omni Agent - Test Agent to be Described",
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
"models": None,
|
|
39
|
+
"dataSources": [],
|
|
40
|
+
"prompts": None,
|
|
41
|
+
"apiKeys": None,
|
|
42
|
+
"memories": None,
|
|
43
|
+
"projectIcon": "https://airiaimagesprod.blob.core.windows.net/airia-default/8a8f75f5-bd6c-470b-bf23-e82c58d81912?sv=2025-05-05&spr=https&st=2025-06-17T20%3A23%3A39Z&se=2025-06-18T20%3A23%3A39Z&sr=b&sp=r&sig=TE7B5sgtCp%2BMpeQizbuhZShOXRcGPol%2BGitQdKGDBKg%3D",
|
|
44
|
+
"projectIconId": "8a8f75f5-bd6c-470b-bf23-e82c58d81912",
|
|
45
|
+
"description": "Agents Developed by AI Core Team",
|
|
46
|
+
"projectType": "Standard",
|
|
47
|
+
"classifications": None,
|
|
48
|
+
"id": "01948f99-f78a-7415-a187-b250c6e04458",
|
|
49
|
+
"name": "AI Core",
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"totalCount": 1,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.fixture
|
|
57
|
+
def sync_client():
|
|
58
|
+
return AiriaClient(log_requests=True)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@pytest_asyncio.fixture
|
|
62
|
+
async def async_client():
|
|
63
|
+
return AiriaAsyncClient(log_requests=True)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class TestSyncGetProjectsIds:
|
|
67
|
+
"""Test cases for synchronous get_projects method."""
|
|
68
|
+
|
|
69
|
+
def test_get_projects_success(self, sync_client: AiriaClient):
|
|
70
|
+
"""Test successful retrieval of projectss."""
|
|
71
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
72
|
+
mock_request.return_value = SAMPLE_PROJECTS
|
|
73
|
+
|
|
74
|
+
result = sync_client.get_projects()
|
|
75
|
+
|
|
76
|
+
assert isinstance(result, list)
|
|
77
|
+
assert len(result) == 1
|
|
78
|
+
mock_request.assert_called_once()
|
|
79
|
+
|
|
80
|
+
def test_get_projects_empty_dict(self, sync_client: AiriaClient):
|
|
81
|
+
"""Test handling of empty project response."""
|
|
82
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
83
|
+
mock_request.return_value = {}
|
|
84
|
+
|
|
85
|
+
result = sync_client.get_projects()
|
|
86
|
+
|
|
87
|
+
assert result == []
|
|
88
|
+
assert isinstance(result, list)
|
|
89
|
+
assert len(result) == 0
|
|
90
|
+
|
|
91
|
+
def test_get_projects_with_custom_api_version(self, sync_client: AiriaClient):
|
|
92
|
+
"""Test using custom API version."""
|
|
93
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
94
|
+
mock_request.return_value = SAMPLE_PROJECTS
|
|
95
|
+
|
|
96
|
+
result = sync_client.get_projects(api_version="v1")
|
|
97
|
+
|
|
98
|
+
assert isinstance(result, list)
|
|
99
|
+
assert len(result) == 1
|
|
100
|
+
mock_request.assert_called_once()
|
|
101
|
+
|
|
102
|
+
def test_get_projects_with_correlation_id(self, sync_client: AiriaClient):
|
|
103
|
+
"""Test using custom correlation ID."""
|
|
104
|
+
custom_correlation_id = "test-correlation-123"
|
|
105
|
+
|
|
106
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
107
|
+
mock_request.return_value = SAMPLE_PROJECTS
|
|
108
|
+
|
|
109
|
+
result = sync_client.get_projects(correlation_id=custom_correlation_id)
|
|
110
|
+
|
|
111
|
+
assert isinstance(result, list)
|
|
112
|
+
assert len(result) == 1
|
|
113
|
+
mock_request.assert_called_once()
|
|
114
|
+
|
|
115
|
+
def test_get_projects_invalid_api_version(
|
|
116
|
+
self, sync_client: AiriaClient
|
|
117
|
+
):
|
|
118
|
+
"""Test error handling for invalid API version."""
|
|
119
|
+
with pytest.raises(ValueError, match="Invalid API version"):
|
|
120
|
+
sync_client.get_projects(api_version="invalid")
|
|
121
|
+
|
|
122
|
+
def test_get_projects_api_error(self, sync_client: AiriaClient):
|
|
123
|
+
"""Test error handling for API errors."""
|
|
124
|
+
with patch.object(sync_client, "_make_request") as mock_request:
|
|
125
|
+
mock_request.side_effect = AiriaAPIError(
|
|
126
|
+
status_code=404, message="Projects not found"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
with pytest.raises(AiriaAPIError) as exc_info:
|
|
130
|
+
sync_client.get_projects()
|
|
131
|
+
|
|
132
|
+
assert "Projects not found" in str(exc_info.value)
|
|
133
|
+
assert exc_info.value.status_code == 404
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TestAsyncGetActivePipelineIds:
|
|
137
|
+
"""Test cases for asynchronous get_active_pipelines_ids method."""
|
|
138
|
+
|
|
139
|
+
@pytest.mark.asyncio
|
|
140
|
+
async def test_get_projects_success(self, async_client: AiriaAsyncClient):
|
|
141
|
+
"""Test successful retrieval of projects."""
|
|
142
|
+
with patch.object(async_client, "_make_request") as mock_request:
|
|
143
|
+
mock_request.return_value = SAMPLE_PROJECTS
|
|
144
|
+
|
|
145
|
+
result = await async_client.get_projects()
|
|
146
|
+
|
|
147
|
+
assert isinstance(result, list)
|
|
148
|
+
assert len(result) == 1
|
|
149
|
+
mock_request.assert_called_once()
|
|
150
|
+
|
|
151
|
+
@pytest.mark.asyncio
|
|
152
|
+
async def test_get_projects_empty_list(self, async_client: AiriaAsyncClient):
|
|
153
|
+
"""Test handling of empty project list response."""
|
|
154
|
+
with patch.object(async_client, "_make_request") as mock_request:
|
|
155
|
+
mock_request.return_value = []
|
|
156
|
+
|
|
157
|
+
result = await async_client.get_projects()
|
|
158
|
+
|
|
159
|
+
assert result == []
|
|
160
|
+
assert isinstance(result, list)
|
|
161
|
+
assert len(result) == 0
|
|
162
|
+
|
|
163
|
+
@pytest.mark.asyncio
|
|
164
|
+
async def test_get_projects_with_custom_params(
|
|
165
|
+
self, async_client: AiriaAsyncClient
|
|
166
|
+
):
|
|
167
|
+
"""Test using custom API version and correlation ID."""
|
|
168
|
+
custom_correlation_id = "async-test-correlation-456"
|
|
169
|
+
|
|
170
|
+
with patch.object(async_client, "_make_request") as mock_request:
|
|
171
|
+
mock_request.return_value = SAMPLE_PROJECTS
|
|
172
|
+
|
|
173
|
+
result = await async_client.get_projects(
|
|
174
|
+
api_version="v1", correlation_id=custom_correlation_id
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
assert isinstance(result, list)
|
|
178
|
+
assert len(result) == 1
|
|
179
|
+
mock_request.assert_called_once()
|
|
180
|
+
|
|
181
|
+
@pytest.mark.asyncio
|
|
182
|
+
async def test_get_projects_invalid_api_version(
|
|
183
|
+
self, async_client: AiriaAsyncClient
|
|
184
|
+
):
|
|
185
|
+
"""Test error handling for invalid API version."""
|
|
186
|
+
with pytest.raises(ValueError, match="Invalid API version"):
|
|
187
|
+
await async_client.get_projects(api_version="invalid")
|
|
188
|
+
|
|
189
|
+
@pytest.mark.asyncio
|
|
190
|
+
async def test_get_projects_api_error(
|
|
191
|
+
self, async_client: AiriaAsyncClient
|
|
192
|
+
):
|
|
193
|
+
"""Test error handling for API errors."""
|
|
194
|
+
with patch.object(async_client, "_make_request") as mock_request:
|
|
195
|
+
mock_request.side_effect = AiriaAPIError(
|
|
196
|
+
status_code=403, message="Access forbidden"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
with pytest.raises(AiriaAPIError) as exc_info:
|
|
200
|
+
await async_client.get_projects()
|
|
201
|
+
|
|
202
|
+
assert "Access forbidden" in str(exc_info.value)
|
|
203
|
+
assert exc_info.value.status_code == 403
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|