airia 0.1.10__tar.gz → 0.1.11__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.
Files changed (36) hide show
  1. {airia-0.1.10 → airia-0.1.11}/PKG-INFO +84 -2
  2. {airia-0.1.10 → airia-0.1.11}/README.md +83 -1
  3. {airia-0.1.10 → airia-0.1.11}/airia/client/async_client.py +122 -82
  4. {airia-0.1.10 → airia-0.1.11}/airia/client/base_client.py +42 -7
  5. {airia-0.1.10 → airia-0.1.11}/airia/client/sync_client.py +118 -81
  6. airia-0.1.11/airia/types/api/__init__.py +19 -0
  7. airia-0.1.11/airia/types/api/conversations.py +14 -0
  8. {airia-0.1.10 → airia-0.1.11}/airia/types/api/pipeline_execution.py +6 -10
  9. {airia-0.1.10/airia/types → airia-0.1.11/airia/types/sse}/__init__.py +4 -20
  10. {airia-0.1.10 → airia-0.1.11}/airia/utils/sse_parser.py +1 -1
  11. {airia-0.1.10 → airia-0.1.11}/airia.egg-info/PKG-INFO +84 -2
  12. {airia-0.1.10 → airia-0.1.11}/airia.egg-info/SOURCES.txt +7 -4
  13. {airia-0.1.10 → airia-0.1.11}/pyproject.toml +1 -1
  14. airia-0.1.11/tests/test_create_conversation.py +227 -0
  15. {airia-0.1.10 → airia-0.1.11}/tests/test_execute_pipeline.py +3 -26
  16. {airia-0.1.10 → airia-0.1.11}/tests/test_get_active_pipelines_ids.py +1 -28
  17. {airia-0.1.10 → airia-0.1.11}/tests/test_get_pipeline_config.py +3 -14
  18. {airia-0.1.10 → airia-0.1.11}/tests/test_get_projects.py +1 -27
  19. {airia-0.1.10 → airia-0.1.11}/LICENSE +0 -0
  20. {airia-0.1.10 → airia-0.1.11}/airia/__init__.py +0 -0
  21. {airia-0.1.10 → airia-0.1.11}/airia/client/__init__.py +0 -0
  22. {airia-0.1.10 → airia-0.1.11}/airia/constants.py +0 -0
  23. {airia-0.1.10 → airia-0.1.11}/airia/exceptions.py +0 -0
  24. {airia-0.1.10 → airia-0.1.11}/airia/logs.py +0 -0
  25. /airia-0.1.10/airia/types/api_version.py → /airia-0.1.11/airia/types/_api_version.py +0 -0
  26. /airia-0.1.10/airia/types/request_data.py → /airia-0.1.11/airia/types/_request_data.py +0 -0
  27. {airia-0.1.10 → airia-0.1.11}/airia/types/api/get_pipeline_config.py +0 -0
  28. {airia-0.1.10 → airia-0.1.11}/airia/types/api/get_projects.py +0 -0
  29. {airia-0.1.10/airia/types → airia-0.1.11/airia/types/sse}/sse_messages.py +0 -0
  30. {airia-0.1.10 → airia-0.1.11}/airia.egg-info/dependency_links.txt +0 -0
  31. {airia-0.1.10 → airia-0.1.11}/airia.egg-info/requires.txt +0 -0
  32. {airia-0.1.10 → airia-0.1.11}/airia.egg-info/top_level.txt +0 -0
  33. {airia-0.1.10 → airia-0.1.11}/setup.cfg +0 -0
  34. {airia-0.1.10 → airia-0.1.11}/tests/test_anthropic_gateway.py +0 -0
  35. {airia-0.1.10 → airia-0.1.11}/tests/test_bearer_token_auth.py +0 -0
  36. {airia-0.1.10 → airia-0.1.11}/tests/test_openai_gateway.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airia
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Python SDK for Airia API
5
5
  Author-email: Airia LLC <support@airia.com>
6
6
  License: MIT
@@ -329,7 +329,7 @@ When using streaming mode (`async_output=True`), the API returns Server-Sent Eve
329
329
 
330
330
  ### Available Message Types
331
331
 
332
- The streaming response includes various message types defined in `airia.types`. Here are the key ones:
332
+ The streaming response includes various message types defined in `airia.types.sse`. Here are the key ones:
333
333
 
334
334
  - `AgentModelStreamFragmentMessage` - Contains actual LLM output chunks
335
335
  - `AgentModelStreamStartMessage` - Indicates LLM streaming has started
@@ -414,6 +414,88 @@ config = client.get_pipeline_config(pipeline_id="your_pipeline_id")
414
414
  print(f"Pipeline Name: {config.agent.name}")
415
415
  ```
416
416
 
417
+ ## Conversation Management
418
+
419
+ You can create and manage conversations using the `create_conversation` method. Conversations allow you to organize and persist interactions within the Airia platform.
420
+
421
+ ### Creating Conversations
422
+
423
+ #### Synchronous Usage
424
+
425
+ ```python
426
+ from airia import AiriaClient
427
+
428
+ client = AiriaClient(api_key="your_api_key")
429
+ # Or with bearer token: client = AiriaClient.with_bearer_token(bearer_token="your_bearer_token")
430
+
431
+ # Create a basic conversation
432
+ conversation = client.create_conversation(
433
+ user_id="user_123"
434
+ )
435
+ print(f"Created conversation: {conversation.conversation_id}")
436
+ print(f"WebSocket URL: {conversation.websocket_url}")
437
+
438
+ # Create a conversation with all options
439
+ conversation = client.create_conversation(
440
+ user_id="user_123",
441
+ title="My Research Session",
442
+ deployment_id="deployment_456",
443
+ data_source_files={"documents": ["doc1.pdf", "doc2.txt"]},
444
+ is_bookmarked=True
445
+ )
446
+ print(f"Created bookmarked conversation: {conversation.conversation_id}")
447
+ ```
448
+
449
+ #### Asynchronous Usage
450
+
451
+ ```python
452
+ import asyncio
453
+ from airia import AiriaAsyncClient
454
+
455
+ async def main():
456
+ client = AiriaAsyncClient(api_key="your_api_key")
457
+ # Or with bearer token: client = AiriaAsyncClient.with_bearer_token(bearer_token="your_bearer_token")
458
+
459
+ # Create a basic conversation
460
+ conversation = await client.create_conversation(
461
+ user_id="user_123"
462
+ )
463
+ print(f"Created conversation: {conversation.conversation_id}")
464
+
465
+ # Create a conversation with all options
466
+ conversation = await client.create_conversation(
467
+ user_id="user_123",
468
+ title="My Research Session",
469
+ deployment_id="deployment_456",
470
+ data_source_files={"documents": ["doc1.pdf", "doc2.txt"]},
471
+ is_bookmarked=True
472
+ )
473
+ print(f"Created bookmarked conversation: {conversation.conversation_id}")
474
+
475
+ asyncio.run(main())
476
+ ```
477
+
478
+ ### Conversation Parameters
479
+
480
+ - **user_id** (required): The unique identifier of the user creating the conversation
481
+ - **title** (optional): A descriptive title for the conversation
482
+ - **deployment_id** (optional): The unique identifier of the deployment to associate with the conversation
483
+ - **data_source_files** (optional): Configuration for data source files to be associated with the conversation
484
+ - **is_bookmarked** (optional): Whether the conversation should be bookmarked (defaults to False)
485
+ - **correlation_id** (optional): A unique identifier for request tracing and logging
486
+
487
+ ### Response Fields
488
+
489
+ The `create_conversation` method returns a `CreateConversationResponse` object containing:
490
+
491
+ - **conversation_id**: The unique identifier of the created conversation
492
+ - **user_id**: The user ID associated with the conversation
493
+ - **websocket_url**: The WebSocket URL for real-time communication
494
+ - **deployment_id**: The deployment ID associated with the conversation
495
+ - **icon_id** and **icon_url**: Optional conversation icon information
496
+ - **description**: Optional conversation description
497
+ - **space_name**: Optional workspace or space name
498
+
417
499
  ## Authentication Methods
418
500
 
419
501
  Airia supports two authentication methods:
@@ -299,7 +299,7 @@ When using streaming mode (`async_output=True`), the API returns Server-Sent Eve
299
299
 
300
300
  ### Available Message Types
301
301
 
302
- The streaming response includes various message types defined in `airia.types`. Here are the key ones:
302
+ The streaming response includes various message types defined in `airia.types.sse`. Here are the key ones:
303
303
 
304
304
  - `AgentModelStreamFragmentMessage` - Contains actual LLM output chunks
305
305
  - `AgentModelStreamStartMessage` - Indicates LLM streaming has started
@@ -384,6 +384,88 @@ config = client.get_pipeline_config(pipeline_id="your_pipeline_id")
384
384
  print(f"Pipeline Name: {config.agent.name}")
385
385
  ```
386
386
 
387
+ ## Conversation Management
388
+
389
+ You can create and manage conversations using the `create_conversation` method. Conversations allow you to organize and persist interactions within the Airia platform.
390
+
391
+ ### Creating Conversations
392
+
393
+ #### Synchronous Usage
394
+
395
+ ```python
396
+ from airia import AiriaClient
397
+
398
+ client = AiriaClient(api_key="your_api_key")
399
+ # Or with bearer token: client = AiriaClient.with_bearer_token(bearer_token="your_bearer_token")
400
+
401
+ # Create a basic conversation
402
+ conversation = client.create_conversation(
403
+ user_id="user_123"
404
+ )
405
+ print(f"Created conversation: {conversation.conversation_id}")
406
+ print(f"WebSocket URL: {conversation.websocket_url}")
407
+
408
+ # Create a conversation with all options
409
+ conversation = client.create_conversation(
410
+ user_id="user_123",
411
+ title="My Research Session",
412
+ deployment_id="deployment_456",
413
+ data_source_files={"documents": ["doc1.pdf", "doc2.txt"]},
414
+ is_bookmarked=True
415
+ )
416
+ print(f"Created bookmarked conversation: {conversation.conversation_id}")
417
+ ```
418
+
419
+ #### Asynchronous Usage
420
+
421
+ ```python
422
+ import asyncio
423
+ from airia import AiriaAsyncClient
424
+
425
+ async def main():
426
+ client = AiriaAsyncClient(api_key="your_api_key")
427
+ # Or with bearer token: client = AiriaAsyncClient.with_bearer_token(bearer_token="your_bearer_token")
428
+
429
+ # Create a basic conversation
430
+ conversation = await client.create_conversation(
431
+ user_id="user_123"
432
+ )
433
+ print(f"Created conversation: {conversation.conversation_id}")
434
+
435
+ # Create a conversation with all options
436
+ conversation = await client.create_conversation(
437
+ user_id="user_123",
438
+ title="My Research Session",
439
+ deployment_id="deployment_456",
440
+ data_source_files={"documents": ["doc1.pdf", "doc2.txt"]},
441
+ is_bookmarked=True
442
+ )
443
+ print(f"Created bookmarked conversation: {conversation.conversation_id}")
444
+
445
+ asyncio.run(main())
446
+ ```
447
+
448
+ ### Conversation Parameters
449
+
450
+ - **user_id** (required): The unique identifier of the user creating the conversation
451
+ - **title** (optional): A descriptive title for the conversation
452
+ - **deployment_id** (optional): The unique identifier of the deployment to associate with the conversation
453
+ - **data_source_files** (optional): Configuration for data source files to be associated with the conversation
454
+ - **is_bookmarked** (optional): Whether the conversation should be bookmarked (defaults to False)
455
+ - **correlation_id** (optional): A unique identifier for request tracing and logging
456
+
457
+ ### Response Fields
458
+
459
+ The `create_conversation` method returns a `CreateConversationResponse` object containing:
460
+
461
+ - **conversation_id**: The unique identifier of the created conversation
462
+ - **user_id**: The user ID associated with the conversation
463
+ - **websocket_url**: The WebSocket URL for real-time communication
464
+ - **deployment_id**: The deployment ID associated with the conversation
465
+ - **icon_id** and **icon_url**: Optional conversation icon information
466
+ - **description**: Optional conversation description
467
+ - **space_name**: Optional workspace or space name
468
+
387
469
  ## Authentication Methods
388
470
 
389
471
  Airia supports two authentication methods:
@@ -1,22 +1,26 @@
1
1
  import asyncio
2
2
  import weakref
3
3
  from typing import Any, AsyncIterator, Dict, List, Literal, Optional, overload
4
- from urllib.parse import urljoin
5
4
 
6
5
  import aiohttp
7
6
  import loguru
8
7
 
9
- from ..constants import DEFAULT_ANTHROPIC_GATEWAY_URL, DEFAULT_BASE_URL, DEFAULT_OPENAI_GATEWAY_URL, DEFAULT_TIMEOUT
8
+ from ..constants import (
9
+ DEFAULT_ANTHROPIC_GATEWAY_URL,
10
+ DEFAULT_BASE_URL,
11
+ DEFAULT_OPENAI_GATEWAY_URL,
12
+ DEFAULT_TIMEOUT,
13
+ )
10
14
  from ..exceptions import AiriaAPIError
11
- from ..types import (
12
- ApiVersion,
15
+ from ..types._api_version import ApiVersion
16
+ from ..types._request_data import RequestData
17
+ from ..types.api import (
18
+ CreateConversationResponse,
13
19
  GetPipelineConfigResponse,
20
+ PipelineExecutionAsyncStreamedResponse,
14
21
  PipelineExecutionDebugResponse,
15
22
  PipelineExecutionResponse,
16
- PipelineExecutionV1StreamedResponse,
17
- PipelineExecutionV2AsyncStreamedResponse,
18
23
  ProjectItem,
19
- RequestData,
20
24
  )
21
25
  from ..utils.sse_parser import async_parse_sse_stream_chunked
22
26
  from .base_client import AiriaBaseClient
@@ -106,7 +110,13 @@ class AiriaAsyncClient(AiriaBaseClient):
106
110
  """
107
111
  from openai import AsyncOpenAI
108
112
 
109
- client = cls(base_url=base_url, api_key=api_key, timeout=timeout, log_requests=log_requests, custom_logger=custom_logger)
113
+ client = cls(
114
+ base_url=base_url,
115
+ api_key=api_key,
116
+ timeout=timeout,
117
+ log_requests=log_requests,
118
+ custom_logger=custom_logger,
119
+ )
110
120
  cls.openai = AsyncOpenAI(
111
121
  api_key=client.api_key,
112
122
  base_url=gateway_url,
@@ -140,7 +150,13 @@ class AiriaAsyncClient(AiriaBaseClient):
140
150
  """
141
151
  from anthropic import AsyncAnthropic
142
152
 
143
- client = cls(base_url=base_url, api_key=api_key, timeout=timeout, log_requests=log_requests, custom_logger=custom_logger)
153
+ client = cls(
154
+ base_url=base_url,
155
+ api_key=api_key,
156
+ timeout=timeout,
157
+ log_requests=log_requests,
158
+ custom_logger=custom_logger,
159
+ )
144
160
  cls.anthropic = AsyncAnthropic(
145
161
  api_key=client.api_key,
146
162
  base_url=gateway_url,
@@ -195,7 +211,9 @@ class AiriaAsyncClient(AiriaBaseClient):
195
211
  if self.api_key and self.api_key in sanitized_message:
196
212
  sanitized_message = sanitized_message.replace(self.api_key, "[REDACTED]")
197
213
  if self.bearer_token and self.bearer_token in sanitized_message:
198
- sanitized_message = sanitized_message.replace(self.bearer_token, "[REDACTED]")
214
+ sanitized_message = sanitized_message.replace(
215
+ self.bearer_token, "[REDACTED]"
216
+ )
199
217
 
200
218
  # Raise custom exception with status code and sanitized message
201
219
  raise AiriaAPIError(status_code=e.status, message=sanitized_message) from e
@@ -328,7 +346,6 @@ class AiriaAsyncClient(AiriaBaseClient):
328
346
  additional_info: Optional[List[Any]] = None,
329
347
  prompt_variables: Optional[Dict[str, Any]] = None,
330
348
  correlation_id: Optional[str] = None,
331
- api_version: str = ApiVersion.V2.value,
332
349
  ) -> PipelineExecutionResponse: ...
333
350
 
334
351
  @overload
@@ -351,7 +368,6 @@ class AiriaAsyncClient(AiriaBaseClient):
351
368
  additional_info: Optional[List[Any]] = None,
352
369
  prompt_variables: Optional[Dict[str, Any]] = None,
353
370
  correlation_id: Optional[str] = None,
354
- api_version: str = ApiVersion.V2.value,
355
371
  ) -> PipelineExecutionDebugResponse: ...
356
372
 
357
373
  @overload
@@ -374,31 +390,7 @@ class AiriaAsyncClient(AiriaBaseClient):
374
390
  additional_info: Optional[List[Any]] = None,
375
391
  prompt_variables: Optional[Dict[str, Any]] = None,
376
392
  correlation_id: Optional[str] = None,
377
- api_version: Literal["v2"] = ApiVersion.V2.value,
378
- ) -> PipelineExecutionV2AsyncStreamedResponse: ...
379
-
380
- @overload
381
- async def execute_pipeline(
382
- self,
383
- pipeline_id: str,
384
- user_input: str,
385
- debug: bool = False,
386
- user_id: Optional[str] = None,
387
- conversation_id: Optional[str] = None,
388
- async_output: Literal[True] = True,
389
- include_tools_response: bool = False,
390
- images: Optional[List[str]] = None,
391
- files: Optional[List[str]] = None,
392
- data_source_folders: Optional[Dict[str, Any]] = None,
393
- data_source_files: Optional[Dict[str, Any]] = None,
394
- in_memory_messages: Optional[List[Dict[str, str]]] = None,
395
- current_date_time: Optional[str] = None,
396
- save_history: bool = True,
397
- additional_info: Optional[List[Any]] = None,
398
- prompt_variables: Optional[Dict[str, Any]] = None,
399
- correlation_id: Optional[str] = None,
400
- api_version: Literal["v1"] = ApiVersion.V1.value,
401
- ) -> PipelineExecutionV1StreamedResponse: ...
393
+ ) -> PipelineExecutionAsyncStreamedResponse: ...
402
394
 
403
395
  async def execute_pipeline(
404
396
  self,
@@ -419,7 +411,6 @@ class AiriaAsyncClient(AiriaBaseClient):
419
411
  additional_info: Optional[List[Any]] = None,
420
412
  prompt_variables: Optional[Dict[str, Any]] = None,
421
413
  correlation_id: Optional[str] = None,
422
- api_version: str = ApiVersion.V2.value,
423
414
  ) -> Dict[str, Any]:
424
415
  """
425
416
  Execute a pipeline with the provided input asynchronously.
@@ -443,7 +434,6 @@ class AiriaAsyncClient(AiriaBaseClient):
443
434
  prompt_variables: Optional variables to be used in the prompt.
444
435
  correlation_id: Optional correlation ID for request tracing. If not provided,
445
436
  one will be generated automatically.
446
- api_version: API version to use. Default is `v2`
447
437
 
448
438
  Returns:
449
439
  The API response as a dictionary.
@@ -478,38 +468,23 @@ class AiriaAsyncClient(AiriaBaseClient):
478
468
  additional_info=additional_info,
479
469
  prompt_variables=prompt_variables,
480
470
  correlation_id=correlation_id,
481
- api_version=api_version,
471
+ api_version=ApiVersion.V2.value,
472
+ )
473
+ resp = (
474
+ self._make_request_stream(method="POST", request_data=request_data)
475
+ if async_output
476
+ else await self._make_request("POST", request_data=request_data)
482
477
  )
483
- stream = async_output and api_version == ApiVersion.V2.value
484
- if stream:
485
- resp = self._make_request_stream(method="POST", request_data=request_data)
486
- else:
487
- resp = await self._make_request("POST", request_data)
488
478
 
489
479
  if not async_output:
490
480
  if not debug:
491
481
  return PipelineExecutionResponse(**resp)
492
482
  return PipelineExecutionDebugResponse(**resp)
493
483
 
494
- if api_version == ApiVersion.V1.value:
495
- url = urljoin(
496
- self.base_url, f"{api_version}/StreamSocketConfig/GenerateUrl"
497
- )
498
- request_data = self._prepare_request(
499
- url=url,
500
- payload={"socketIdentifier": resp},
501
- correlation_id=request_data.headers["X-Correlation-ID"],
502
- )
503
- resp = await self._make_request("POST", request_data)
504
-
505
- return PipelineExecutionV1StreamedResponse(**resp)
506
-
507
- return PipelineExecutionV2AsyncStreamedResponse(stream=resp)
484
+ return PipelineExecutionAsyncStreamedResponse(stream=resp)
508
485
 
509
486
  async def get_projects(
510
- self,
511
- correlation_id: Optional[str] = None,
512
- api_version: str = ApiVersion.V1.value,
487
+ self, correlation_id: Optional[str] = None
513
488
  ) -> List[ProjectItem]:
514
489
  """
515
490
  Retrieve a list of all projects accessible to the authenticated user.
@@ -521,8 +496,6 @@ class AiriaAsyncClient(AiriaBaseClient):
521
496
  Args:
522
497
  correlation_id (str, optional): A unique identifier for request tracing
523
498
  and logging. If not provided, one will be automatically generated.
524
- api_version (str, optional): The API version to use for the request.
525
- Defaults to "v1". Valid versions are defined in ApiVersion enum.
526
499
 
527
500
  Returns:
528
501
  List[ProjectItem]: A list of ProjectItem objects containing project
@@ -530,7 +503,6 @@ class AiriaAsyncClient(AiriaBaseClient):
530
503
  or found.
531
504
 
532
505
  Raises:
533
- ValueError: If the provided api_version is not valid.
534
506
  AiriaAPIError: If the API request fails, including cases where:
535
507
  - Authentication fails (401)
536
508
  - Access is forbidden (403)
@@ -559,7 +531,7 @@ class AiriaAsyncClient(AiriaBaseClient):
559
531
  access to.
560
532
  """
561
533
  request_data = self._pre_get_projects(
562
- correlation_id=correlation_id, api_version=api_version
534
+ correlation_id=correlation_id, api_version=ApiVersion.V1.value
563
535
  )
564
536
  resp = await self._make_request("GET", request_data)
565
537
 
@@ -569,10 +541,7 @@ class AiriaAsyncClient(AiriaBaseClient):
569
541
  return [ProjectItem(**item) for item in resp["items"]]
570
542
 
571
543
  async def get_active_pipelines_ids(
572
- self,
573
- project_id: Optional[str] = None,
574
- correlation_id: Optional[str] = None,
575
- api_version: str = ApiVersion.V1.value,
544
+ self, project_id: Optional[str] = None, correlation_id: Optional[str] = None
576
545
  ) -> List[str]:
577
546
  """
578
547
  Retrieve a list of active pipeline IDs.
@@ -586,15 +555,12 @@ class AiriaAsyncClient(AiriaBaseClient):
586
555
  accessible to the authenticated user.
587
556
  correlation_id (str, optional): A unique identifier for request tracing
588
557
  and logging. If not provided, one will be automatically generated.
589
- api_version (str, optional): The API version to use for the request.
590
- Defaults to "v1". Valid versions are defined in ApiVersion enum.
591
558
 
592
559
  Returns:
593
560
  List[str]: A list of pipeline IDs that are currently active. Returns an
594
561
  empty list if no active pipelines are found.
595
562
 
596
563
  Raises:
597
- ValueError: If the provided api_version is not valid.
598
564
  AiriaAPIError: If the API request fails, including cases where:
599
565
  - The project_id doesn't exist (404)
600
566
  - Authentication fails (401)
@@ -625,7 +591,7 @@ class AiriaAsyncClient(AiriaBaseClient):
625
591
  request_data = self._pre_get_active_pipelines_ids(
626
592
  project_id=project_id,
627
593
  correlation_id=correlation_id,
628
- api_version=api_version,
594
+ api_version=ApiVersion.V1.value,
629
595
  )
630
596
  resp = await self._make_request("GET", request_data)
631
597
 
@@ -637,10 +603,7 @@ class AiriaAsyncClient(AiriaBaseClient):
637
603
  return pipeline_ids
638
604
 
639
605
  async def get_pipeline_config(
640
- self,
641
- pipeline_id: str,
642
- correlation_id: Optional[str] = None,
643
- api_version: str = ApiVersion.V1.value,
606
+ self, pipeline_id: str, correlation_id: Optional[str] = None
644
607
  ) -> GetPipelineConfigResponse:
645
608
  """
646
609
  Retrieve configuration details for a specific pipeline.
@@ -651,8 +614,6 @@ class AiriaAsyncClient(AiriaBaseClient):
651
614
  Args:
652
615
  pipeline_id (str): The unique identifier of the pipeline to retrieve
653
616
  configuration for.
654
- api_version (str, optional): The API version to use for the request.
655
- Defaults to "v1". Valid versions are defined in ApiVersion enum.
656
617
  correlation_id (str, optional): A unique identifier for request tracing
657
618
  and logging. If not provided, one will be automatically generated.
658
619
 
@@ -661,7 +622,6 @@ class AiriaAsyncClient(AiriaBaseClient):
661
622
  configuration.
662
623
 
663
624
  Raises:
664
- ValueError: If the provided api_version is not valid.
665
625
  AiriaAPIError: If the API request fails, including cases where:
666
626
  - The pipeline_id doesn't exist (404)
667
627
  - Authentication fails (401)
@@ -692,8 +652,88 @@ class AiriaAsyncClient(AiriaBaseClient):
692
652
  request_data = self._pre_get_pipeline_config(
693
653
  pipeline_id=pipeline_id,
694
654
  correlation_id=correlation_id,
695
- api_version=api_version,
655
+ api_version=ApiVersion.V1.value,
696
656
  )
697
657
  resp = await self._make_request("GET", request_data)
698
658
 
699
659
  return GetPipelineConfigResponse(**resp)
660
+
661
+ async def create_conversation(
662
+ self,
663
+ user_id: str,
664
+ title: Optional[str] = None,
665
+ deployment_id: Optional[str] = None,
666
+ data_source_files: Dict[str, Any] = {},
667
+ is_bookmarked: bool = False,
668
+ correlation_id: Optional[str] = None,
669
+ ) -> CreateConversationResponse:
670
+ """
671
+ Create a new conversation.
672
+
673
+ Args:
674
+ user_id (str): The unique identifier of the user creating the conversation.
675
+ title (str, optional): The title for the conversation. If not provided,
676
+ the conversation will be created without a title.
677
+ deployment_id (str, optional): The unique identifier of the deployment
678
+ to associate with the conversation. If not provided, the conversation
679
+ will not be associated with any specific deployment.
680
+ data_source_files (dict): Configuration for data source files
681
+ to be associated with the conversation. If not provided, no data
682
+ source files will be associated.
683
+ is_bookmarked (bool): Whether the conversation should be bookmarked.
684
+ Defaults to False.
685
+ correlation_id (str, optional): A unique identifier for request tracing
686
+ and logging. If not provided, one will be automatically generated.
687
+
688
+ Returns:
689
+ CreateConversationResponse: A response object containing the created
690
+ conversation details including its ID, creation timestamp, and
691
+ all provided parameters.
692
+
693
+ Raises:
694
+ AiriaAPIError: If the API request fails, including cases where:
695
+ - The user_id doesn't exist (404)
696
+ - The deployment_id is invalid (404)
697
+ - Authentication fails (401)
698
+ - Access is forbidden (403)
699
+ - Server errors (5xx)
700
+
701
+ Example:
702
+ ```python
703
+ from airia import AiriaAsyncClient
704
+
705
+ client = AiriaAsyncClient(api_key="your_api_key")
706
+
707
+ # Create a basic conversation
708
+ conversation = await client.create_conversation(
709
+ user_id="user_123"
710
+ )
711
+ print(f"Created conversation: {conversation.conversation_id}")
712
+
713
+ # Create a conversation with all options
714
+ conversation = await client.create_conversation(
715
+ user_id="user_123",
716
+ title="My Research Session",
717
+ deployment_id="deployment_456",
718
+ data_source_files={"documents": ["doc1.pdf", "doc2.txt"]},
719
+ is_bookmarked=True
720
+ )
721
+ print(f"Created bookmarked conversation: {conversation.conversation_id}")
722
+ ```
723
+
724
+ Note:
725
+ The user_id is required and must correspond to a valid user in the system.
726
+ All other parameters are optional and can be set to None or their default values.
727
+ """
728
+ request_data = self._pre_create_conversation(
729
+ user_id=user_id,
730
+ title=title,
731
+ deployment_id=deployment_id,
732
+ data_source_files=data_source_files,
733
+ is_bookmarked=is_bookmarked,
734
+ correlation_id=correlation_id,
735
+ api_version=ApiVersion.V1.value,
736
+ )
737
+ resp = await self._make_request("POST", request_data)
738
+
739
+ return CreateConversationResponse(**resp)
@@ -7,7 +7,8 @@ import loguru
7
7
 
8
8
  from ..constants import DEFAULT_BASE_URL, DEFAULT_TIMEOUT
9
9
  from ..logs import configure_logging, set_correlation_id
10
- from ..types import ApiVersion, RequestData
10
+ from ..types._api_version import ApiVersion
11
+ from ..types._request_data import RequestData
11
12
 
12
13
 
13
14
  class AiriaBaseClient:
@@ -36,7 +37,9 @@ class AiriaBaseClient:
36
37
  custom_logger: Optional custom logger object to use for logging. If not provided, will use a default logger when `log_requests` is True.
37
38
  """
38
39
  # Resolve authentication credentials
39
- self.api_key, self.bearer_token = self.__class__._resolve_auth_credentials(api_key, bearer_token)
40
+ self.api_key, self.bearer_token = self.__class__._resolve_auth_credentials(
41
+ api_key, bearer_token
42
+ )
40
43
 
41
44
  # Store configuration
42
45
  self.base_url = base_url
@@ -47,7 +50,9 @@ class AiriaBaseClient:
47
50
  self.logger = configure_logging() if custom_logger is None else custom_logger
48
51
 
49
52
  @staticmethod
50
- def _resolve_auth_credentials(api_key: Optional[str] = None, bearer_token: Optional[str] = None):
53
+ def _resolve_auth_credentials(
54
+ api_key: Optional[str] = None, bearer_token: Optional[str] = None
55
+ ):
51
56
  """
52
57
  Resolve authentication credentials from parameters and environment variables.
53
58
 
@@ -66,20 +71,20 @@ class AiriaBaseClient:
66
71
  raise ValueError(
67
72
  "Cannot provide both api_key and bearer_token. Please use only one authentication method."
68
73
  )
69
-
74
+
70
75
  # If bearer token is explicitly provided, use it exclusively
71
76
  if bearer_token:
72
77
  return None, bearer_token
73
-
78
+
74
79
  # If API key is explicitly provided, use it exclusively
75
80
  if api_key:
76
81
  return api_key, None
77
-
82
+
78
83
  # If neither is provided explicitly, fall back to environment variable
79
84
  resolved_api_key = os.environ.get("AIRIA_API_KEY")
80
85
  if resolved_api_key:
81
86
  return resolved_api_key, None
82
-
87
+
83
88
  # No authentication method found
84
89
  raise ValueError(
85
90
  "Authentication required. Provide either api_key (or set AIRIA_API_KEY environment variable) or bearer_token."
@@ -244,6 +249,36 @@ class AiriaBaseClient:
244
249
 
245
250
  return request_data
246
251
 
252
+ def _pre_create_conversation(
253
+ self,
254
+ user_id: str,
255
+ title: Optional[str] = None,
256
+ deployment_id: Optional[str] = None,
257
+ data_source_files: Dict[str, Any] = {},
258
+ is_bookmarked: bool = False,
259
+ correlation_id: Optional[str] = None,
260
+ api_version: str = ApiVersion.V1.value,
261
+ ):
262
+ if api_version not in ApiVersion.as_list():
263
+ raise ValueError(
264
+ f"Invalid API version: {api_version}. Valid versions are: {', '.join(ApiVersion.as_list())}"
265
+ )
266
+ url = urljoin(self.base_url, f"{api_version}/Conversations")
267
+
268
+ payload = {
269
+ "userId": user_id,
270
+ "title": title,
271
+ "deploymentId": deployment_id,
272
+ "dataSourceFiles": data_source_files,
273
+ "isBookmarked": is_bookmarked,
274
+ }
275
+
276
+ request_data = self._prepare_request(
277
+ url=url, payload=payload, correlation_id=correlation_id
278
+ )
279
+
280
+ return request_data
281
+
247
282
  def _pre_get_projects(
248
283
  self,
249
284
  correlation_id: Optional[str] = None,