python-base-agent 2026.2.13__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.
- base_agent/__init__.py +49 -0
- base_agent/agent.py +1060 -0
- base_agent/config.py +220 -0
- base_agent/contracts/__init__.py +209 -0
- base_agent/contracts/access_control_summary_part.py +42 -0
- base_agent/contracts/agent_loop_part.py +87 -0
- base_agent/contracts/agent_tool_part.py +15 -0
- base_agent/contracts/append_entity_class_part.py +15 -0
- base_agent/contracts/broadcast_message.py +30 -0
- base_agent/contracts/broadcast_message_type.py +13 -0
- base_agent/contracts/cache_stability_metadata.py +27 -0
- base_agent/contracts/code_generation.py +18 -0
- base_agent/contracts/context_management_notification.py +20 -0
- base_agent/contracts/context_management_pipeline.py +21 -0
- base_agent/contracts/cross_vector_similarity_search_request.py +14 -0
- base_agent/contracts/data_classification_tag.py +12 -0
- base_agent/contracts/data_lineage_part.py +46 -0
- base_agent/contracts/data_part.py +15 -0
- base_agent/contracts/data_pointer_part.py +20 -0
- base_agent/contracts/embedding_request.py +15 -0
- base_agent/contracts/embedding_response.py +21 -0
- base_agent/contracts/entity_matching_form_data.py +79 -0
- base_agent/contracts/entity_vector_text_search_match.py +12 -0
- base_agent/contracts/entity_vector_text_search_request.py +14 -0
- base_agent/contracts/entity_vector_text_search_result.py +24 -0
- base_agent/contracts/entity_vectorization_job_info.py +24 -0
- base_agent/contracts/entity_vectorization_jobs_result.py +30 -0
- base_agent/contracts/entity_vectorization_progress.py +14 -0
- base_agent/contracts/entity_vectorization_request.py +15 -0
- base_agent/contracts/entity_vectorization_result.py +17 -0
- base_agent/contracts/envelope.py +20 -0
- base_agent/contracts/error_part.py +24 -0
- base_agent/contracts/error_part_type.py +14 -0
- base_agent/contracts/file_part.py +17 -0
- base_agent/contracts/file_pointer_part.py +17 -0
- base_agent/contracts/file_revectorization_request_event.py +19 -0
- base_agent/contracts/file_vectorization_request_event.py +22 -0
- base_agent/contracts/for_each_part.py +30 -0
- base_agent/contracts/fuzzy_matching_params.py +21 -0
- base_agent/contracts/group_plan.py +16 -0
- base_agent/contracts/header.py +69 -0
- base_agent/contracts/human_input_request.py +16 -0
- base_agent/contracts/inspector_pipeline_item.py +19 -0
- base_agent/contracts/list_entity_vectorization_jobs_request.py +12 -0
- base_agent/contracts/llm_accounting_part.py +33 -0
- base_agent/contracts/llm_error_notification.py +13 -0
- base_agent/contracts/llm_judge_job.py +84 -0
- base_agent/contracts/llm_judge_params.py +15 -0
- base_agent/contracts/llm_judge_progress.py +20 -0
- base_agent/contracts/llm_model_part.py +72 -0
- base_agent/contracts/llm_reasoning_summary.py +23 -0
- base_agent/contracts/llm_response.py +25 -0
- base_agent/contracts/llm_response_part.py +54 -0
- base_agent/contracts/match_entities_job.py +43 -0
- base_agent/contracts/match_result.py +52 -0
- base_agent/contracts/notification_error_type.py +12 -0
- base_agent/contracts/notification_severity.py +14 -0
- base_agent/contracts/on_trigger_fired.py +17 -0
- base_agent/contracts/parallel_execution_plan.py +25 -0
- base_agent/contracts/part.py +30 -0
- base_agent/contracts/resume_entity_vectorization_request.py +11 -0
- base_agent/contracts/room_dataset_catalog.py +44 -0
- base_agent/contracts/room_dataset_catalog_entry.py +38 -0
- base_agent/contracts/room_dataset_column.py +12 -0
- base_agent/contracts/room_dataset_schema.py +24 -0
- base_agent/contracts/scratch_pad_content.py +14 -0
- base_agent/contracts/search_request.py +27 -0
- base_agent/contracts/search_response.py +39 -0
- base_agent/contracts/search_result.py +21 -0
- base_agent/contracts/search_type_result.py +13 -0
- base_agent/contracts/semantic_search_progress.py +18 -0
- base_agent/contracts/semantic_search_result.py +25 -0
- base_agent/contracts/stream_content_message.py +35 -0
- base_agent/contracts/stream_event_type.py +12 -0
- base_agent/contracts/stream_message.py +14 -0
- base_agent/contracts/stream_metadata.py +28 -0
- base_agent/contracts/task_artifact_update.py +20 -0
- base_agent/contracts/task_error_response.py +22 -0
- base_agent/contracts/task_ref.py +19 -0
- base_agent/contracts/task_request.py +21 -0
- base_agent/contracts/task_response.py +21 -0
- base_agent/contracts/task_status_update.py +31 -0
- base_agent/contracts/text_part.py +15 -0
- base_agent/contracts/tool_authorization_request.py +21 -0
- base_agent/contracts/tool_call_index.py +42 -0
- base_agent/contracts/tool_call_index_entry.py +32 -0
- base_agent/contracts/tool_call_initiation.py +27 -0
- base_agent/contracts/tool_learning_request.py +34 -0
- base_agent/contracts/tool_response_completion.py +19 -0
- base_agent/contracts/tool_response_part.py +31 -0
- base_agent/contracts/usage_metadata.py +11 -0
- base_agent/contracts/user_data_notification.py +13 -0
- base_agent/contracts/user_notification.py +21 -0
- base_agent/contracts/vector_similarity_search_request.py +13 -0
- base_agent/contracts/vector_similarity_search_result.py +25 -0
- base_agent/contracts/workflow_part.py +17 -0
- base_agent/exceptions.py +39 -0
- base_agent/health/__init__.py +5 -0
- base_agent/health/server.py +191 -0
- base_agent/messaging/__init__.py +5 -0
- base_agent/messaging/kafka_client.py +572 -0
- base_agent/ordering/__init__.py +5 -0
- base_agent/ordering/vector_clock.py +176 -0
- base_agent/prompts/__init__.py +10 -0
- base_agent/prompts/prompt_manager.py +213 -0
- base_agent/registration/__init__.py +5 -0
- base_agent/registration/registration_client.py +364 -0
- base_agent/schemas/__init__.py +14 -0
- base_agent/schemas/models.py +30 -0
- base_agent/schemas/schema_registry_client.py +493 -0
- base_agent/schemas/source_type.py +24 -0
- base_agent/schemas/technical_name_validator.py +147 -0
- base_agent/state/__init__.py +13 -0
- base_agent/state/logical_clock_tracker.py +50 -0
- base_agent/state/session_tracker.py +91 -0
- base_agent/state/store.py +333 -0
- base_agent/storage/__init__.py +27 -0
- base_agent/storage/azure_store.py +615 -0
- base_agent/storage/exceptions.py +26 -0
- base_agent/storage/models.py +73 -0
- base_agent/storage/object_store.py +248 -0
- base_agent/storage/object_store_factory.py +136 -0
- base_agent/storage/s3_store.py +411 -0
- base_agent/telemetry/__init__.py +1 -0
- base_agent/tools/__init__.py +12 -0
- base_agent/tools/models.py +66 -0
- base_agent/tools/tool_registry_client.py +607 -0
- base_agent/utils/__init__.py +5 -0
- base_agent/utils/logger.py +146 -0
- base_agent/utils/version_utils.py +92 -0
- python_base_agent-2026.2.13.dist-info/METADATA +536 -0
- python_base_agent-2026.2.13.dist-info/RECORD +134 -0
- python_base_agent-2026.2.13.dist-info/WHEEL +5 -0
- python_base_agent-2026.2.13.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Data models for Object Storage - Based on Java ObjectStore data classes"""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, BinaryIO
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ObjectSummary:
|
|
10
|
+
"""
|
|
11
|
+
Summary information about an object in the object store.
|
|
12
|
+
Maps to Java: ObjectSummary.java
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
key: str
|
|
16
|
+
size: int
|
|
17
|
+
last_modified: datetime
|
|
18
|
+
etag: str | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class ObjectMetadata:
|
|
23
|
+
"""
|
|
24
|
+
Metadata for an object without retrieving its content.
|
|
25
|
+
Maps to Java: ObjectMetadata.java
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
content_type: str | None
|
|
29
|
+
content_length: int
|
|
30
|
+
etag: str | None
|
|
31
|
+
last_modified: datetime | None
|
|
32
|
+
metadata: dict[str, str] | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class ObjectResponse:
|
|
37
|
+
"""
|
|
38
|
+
Response containing an object's content stream and metadata.
|
|
39
|
+
Maps to Java: ObjectResponse.java
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
input_stream: BinaryIO | Any # Can be async stream
|
|
43
|
+
content_length: int
|
|
44
|
+
content_type: str | None
|
|
45
|
+
metadata: dict[str, str] | None = None
|
|
46
|
+
|
|
47
|
+
async def close(self) -> None:
|
|
48
|
+
"""Close the input stream if it's closeable."""
|
|
49
|
+
if hasattr(self.input_stream, "close"):
|
|
50
|
+
if hasattr(self.input_stream, "__aclose__"):
|
|
51
|
+
await self.input_stream.__aclose__()
|
|
52
|
+
else:
|
|
53
|
+
self.input_stream.close()
|
|
54
|
+
|
|
55
|
+
async def __aenter__(self):
|
|
56
|
+
"""Async context manager entry."""
|
|
57
|
+
return self
|
|
58
|
+
|
|
59
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
60
|
+
"""Async context manager exit."""
|
|
61
|
+
await self.close()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class ListObjectsResponse:
|
|
66
|
+
"""
|
|
67
|
+
Response from listing objects with pagination support.
|
|
68
|
+
Maps to Java: ListObjectsResponse.java
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
objects: list[ObjectSummary]
|
|
72
|
+
continuation_token: str | None = None
|
|
73
|
+
is_truncated: bool = False
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Object Storage abstraction - Based on Java ObjectStore.java"""
|
|
2
|
+
|
|
3
|
+
from typing import Protocol
|
|
4
|
+
|
|
5
|
+
from base_agent.storage.models import (
|
|
6
|
+
ListObjectsResponse,
|
|
7
|
+
ObjectMetadata,
|
|
8
|
+
ObjectResponse,
|
|
9
|
+
ObjectSummary,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ObjectStore(Protocol):
|
|
14
|
+
"""
|
|
15
|
+
Generic interface for object storage operations.
|
|
16
|
+
This abstraction allows swapping between different storage providers (S3, Azure Blob, GCS, etc.)
|
|
17
|
+
|
|
18
|
+
Maps to Java: ObjectStore.java
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def put_object(
|
|
22
|
+
self,
|
|
23
|
+
bucket: str,
|
|
24
|
+
key: str,
|
|
25
|
+
content: bytes,
|
|
26
|
+
content_type: str | None = None,
|
|
27
|
+
metadata: dict[str, str] | None = None,
|
|
28
|
+
) -> bool:
|
|
29
|
+
"""
|
|
30
|
+
Store an object in the object store.
|
|
31
|
+
|
|
32
|
+
Java Reference: ObjectStore.java:29
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
bucket: The bucket name
|
|
36
|
+
key: The object key
|
|
37
|
+
content: The content to store as bytes
|
|
38
|
+
content_type: The MIME type of the content
|
|
39
|
+
metadata: Optional metadata to attach to the object
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
True if successful, False otherwise
|
|
43
|
+
"""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
async def get_object(self, bucket: str, key: str) -> bytes | None:
|
|
47
|
+
"""
|
|
48
|
+
Retrieve an object from the object store.
|
|
49
|
+
|
|
50
|
+
Java Reference: ObjectStore.java:66
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
bucket: The bucket name
|
|
54
|
+
key: The object key
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
The object content as bytes, or None if not found
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
async def get_object_stream(self, bucket: str, key: str) -> ObjectResponse | None:
|
|
62
|
+
"""
|
|
63
|
+
Retrieve an object from the object store as a stream.
|
|
64
|
+
|
|
65
|
+
Java Reference: ObjectStore.java:75
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
bucket: The bucket name
|
|
69
|
+
key: The object key
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
An ObjectResponse containing the input stream and metadata, or None if not found
|
|
73
|
+
"""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
async def delete_object(self, bucket: str, key: str) -> bool:
|
|
77
|
+
"""
|
|
78
|
+
Delete an object from the object store.
|
|
79
|
+
|
|
80
|
+
Java Reference: ObjectStore.java:84
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
bucket: The bucket name
|
|
84
|
+
key: The object key
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
True if successful, False otherwise
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
async def list_objects(
|
|
92
|
+
self, bucket: str, prefix: str | None = None, max_keys: int = 1000
|
|
93
|
+
) -> list[ObjectSummary]:
|
|
94
|
+
"""
|
|
95
|
+
List objects in a bucket with optional prefix.
|
|
96
|
+
|
|
97
|
+
Java Reference: ObjectStore.java:94
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
bucket: The bucket name
|
|
101
|
+
prefix: Optional prefix to filter objects
|
|
102
|
+
max_keys: Maximum number of keys to return
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
List of object summaries
|
|
106
|
+
"""
|
|
107
|
+
...
|
|
108
|
+
|
|
109
|
+
async def list_objects_paginated(
|
|
110
|
+
self,
|
|
111
|
+
bucket: str,
|
|
112
|
+
prefix: str | None = None,
|
|
113
|
+
max_keys: int = 1000,
|
|
114
|
+
continuation_token: str | None = None,
|
|
115
|
+
) -> ListObjectsResponse:
|
|
116
|
+
"""
|
|
117
|
+
List objects in a bucket with pagination.
|
|
118
|
+
|
|
119
|
+
Java Reference: ObjectStore.java:105
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
bucket: The bucket name
|
|
123
|
+
prefix: Optional prefix to filter objects
|
|
124
|
+
max_keys: Maximum number of keys to return
|
|
125
|
+
continuation_token: Token for pagination
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
ListObjectsResponse containing objects and next continuation token
|
|
129
|
+
"""
|
|
130
|
+
...
|
|
131
|
+
|
|
132
|
+
async def copy_object(
|
|
133
|
+
self,
|
|
134
|
+
source_bucket: str,
|
|
135
|
+
source_key: str,
|
|
136
|
+
destination_bucket: str,
|
|
137
|
+
destination_key: str,
|
|
138
|
+
) -> bool:
|
|
139
|
+
"""
|
|
140
|
+
Copy an object within the object store.
|
|
141
|
+
|
|
142
|
+
Java Reference: ObjectStore.java:116
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
source_bucket: The source bucket name
|
|
146
|
+
source_key: The source object key
|
|
147
|
+
destination_bucket: The destination bucket name
|
|
148
|
+
destination_key: The destination object key
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
True if successful, False otherwise
|
|
152
|
+
"""
|
|
153
|
+
...
|
|
154
|
+
|
|
155
|
+
async def object_exists(self, bucket: str, key: str) -> bool:
|
|
156
|
+
"""
|
|
157
|
+
Check if an object exists.
|
|
158
|
+
|
|
159
|
+
Java Reference: ObjectStore.java:125
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
bucket: The bucket name
|
|
163
|
+
key: The object key
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
True if the object exists, False otherwise
|
|
167
|
+
"""
|
|
168
|
+
...
|
|
169
|
+
|
|
170
|
+
async def create_bucket_if_not_exists(self, bucket: str) -> bool:
|
|
171
|
+
"""
|
|
172
|
+
Create a bucket if it doesn't exist.
|
|
173
|
+
|
|
174
|
+
Java Reference: ObjectStore.java:133
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
bucket: The bucket name
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
True if bucket was created or already exists, False on error
|
|
181
|
+
"""
|
|
182
|
+
...
|
|
183
|
+
|
|
184
|
+
async def list_buckets(self) -> list[str]:
|
|
185
|
+
"""
|
|
186
|
+
List all buckets.
|
|
187
|
+
|
|
188
|
+
Java Reference: ObjectStore.java:140
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
List of bucket names
|
|
192
|
+
"""
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
async def bucket_exists(self, bucket: str) -> bool:
|
|
196
|
+
"""
|
|
197
|
+
Check if a bucket exists.
|
|
198
|
+
|
|
199
|
+
Java Reference: ObjectStore.java:148
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
bucket: The bucket name
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
True if the bucket exists, False otherwise
|
|
206
|
+
"""
|
|
207
|
+
...
|
|
208
|
+
|
|
209
|
+
async def generate_presigned_url(
|
|
210
|
+
self, bucket: str, key: str, expiration_minutes: int = 60
|
|
211
|
+
) -> str | None:
|
|
212
|
+
"""
|
|
213
|
+
Generate a pre-signed URL for temporary access to an object.
|
|
214
|
+
|
|
215
|
+
Java Reference: ObjectStore.java:158
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
bucket: The bucket name
|
|
219
|
+
key: The object key
|
|
220
|
+
expiration_minutes: Expiration time in minutes
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
The pre-signed URL, or None if not supported
|
|
224
|
+
"""
|
|
225
|
+
...
|
|
226
|
+
|
|
227
|
+
async def get_object_metadata(self, bucket: str, key: str) -> ObjectMetadata | None:
|
|
228
|
+
"""
|
|
229
|
+
Get metadata for an object without retrieving its content.
|
|
230
|
+
|
|
231
|
+
Java Reference: ObjectStore.java:167
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
bucket: The bucket name
|
|
235
|
+
key: The object key
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Object metadata, or None if not found
|
|
239
|
+
"""
|
|
240
|
+
...
|
|
241
|
+
|
|
242
|
+
async def initialize(self) -> None:
|
|
243
|
+
"""Initialize the object store connection."""
|
|
244
|
+
...
|
|
245
|
+
|
|
246
|
+
async def close(self) -> None:
|
|
247
|
+
"""Close the object store connection and cleanup resources."""
|
|
248
|
+
...
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Object Store factory for creating storage instances based on configuration.
|
|
3
|
+
|
|
4
|
+
Maps to Java: ObjectStoreFactory.java
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
from base_agent.storage.azure_store import AzureBlobObjectStore
|
|
11
|
+
from base_agent.storage.object_store import ObjectStore
|
|
12
|
+
from base_agent.storage.s3_store import S3ObjectStore
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ObjectStoreFactory:
|
|
18
|
+
"""
|
|
19
|
+
Factory for creating ObjectStore instances based on environment configuration.
|
|
20
|
+
|
|
21
|
+
Configuration is read from environment variables:
|
|
22
|
+
- OBJECT_STORE_TYPE: Type of storage (s3, minio, azure)
|
|
23
|
+
- Additional provider-specific variables (see specific factory methods)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def create_object_store() -> ObjectStore:
|
|
28
|
+
"""
|
|
29
|
+
Create an ObjectStore instance based on OBJECT_STORE_TYPE environment variable.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
ObjectStore implementation (S3ObjectStore, AzureBlobObjectStore, etc.)
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: If configuration is invalid or missing required variables
|
|
36
|
+
NotImplementedError: If provider type is not yet implemented
|
|
37
|
+
"""
|
|
38
|
+
store_type: str = os.getenv("OBJECT_STORE_TYPE", "s3").lower()
|
|
39
|
+
|
|
40
|
+
logger.info("Creating object store with type: %s", store_type)
|
|
41
|
+
|
|
42
|
+
if store_type in ["s3", "minio"]:
|
|
43
|
+
return ObjectStoreFactory._create_s3_object_store()
|
|
44
|
+
if store_type == "azure":
|
|
45
|
+
return ObjectStoreFactory._create_azure_object_store()
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"Unsupported object store type: {store_type}. Supported types: s3, minio, azure"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def _create_s3_object_store() -> S3ObjectStore:
|
|
52
|
+
"""
|
|
53
|
+
Create an S3-compatible ObjectStore instance.
|
|
54
|
+
|
|
55
|
+
Required environment variables:
|
|
56
|
+
- OBJECT_STORE_ENDPOINT: S3 endpoint URL (e.g., http://localhost:9000)
|
|
57
|
+
- OBJECT_STORE_ACCESS_KEY: Access key ID
|
|
58
|
+
- OBJECT_STORE_SECRET_KEY: Secret access key
|
|
59
|
+
- OBJECT_STORE_REGION: AWS region (e.g., us-east-1)
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
S3ObjectStore instance
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
ValueError: If required configuration is missing
|
|
66
|
+
"""
|
|
67
|
+
logger.info("Creating S3-compatible object store client")
|
|
68
|
+
|
|
69
|
+
# Validate required configuration
|
|
70
|
+
required_vars = [
|
|
71
|
+
"OBJECT_STORE_ENDPOINT",
|
|
72
|
+
"OBJECT_STORE_ACCESS_KEY",
|
|
73
|
+
"OBJECT_STORE_SECRET_KEY",
|
|
74
|
+
"OBJECT_STORE_REGION",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
missing_vars = [var for var in required_vars if not os.getenv(var)]
|
|
78
|
+
if missing_vars:
|
|
79
|
+
raise ValueError(
|
|
80
|
+
f"Missing required configuration for S3 object store: {', '.join(missing_vars)}"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
endpoint_url = os.getenv("OBJECT_STORE_ENDPOINT")
|
|
84
|
+
access_key_id = os.getenv("OBJECT_STORE_ACCESS_KEY")
|
|
85
|
+
secret_access_key = os.getenv("OBJECT_STORE_SECRET_KEY")
|
|
86
|
+
region = os.getenv("OBJECT_STORE_REGION")
|
|
87
|
+
|
|
88
|
+
return S3ObjectStore(
|
|
89
|
+
endpoint=endpoint_url,
|
|
90
|
+
access_key=access_key_id,
|
|
91
|
+
secret_key=secret_access_key,
|
|
92
|
+
region=region,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
@staticmethod
|
|
96
|
+
def _create_azure_object_store() -> AzureBlobObjectStore:
|
|
97
|
+
"""
|
|
98
|
+
Create an Azure Blob Storage ObjectStore instance.
|
|
99
|
+
|
|
100
|
+
Configuration is read from environment variables:
|
|
101
|
+
- AZURE_STORAGE_CONNECTION_STRING: Full connection string (highest priority)
|
|
102
|
+
- AZURE_STORAGE_ACCOUNT: Storage account name
|
|
103
|
+
- AZURE_STORAGE_KEY: Storage account key (optional, uses AAD if not provided)
|
|
104
|
+
- AZURE_STORAGE_ENDPOINT: Custom endpoint URL (optional)
|
|
105
|
+
|
|
106
|
+
Auth priority:
|
|
107
|
+
1. Connection string (if AZURE_STORAGE_CONNECTION_STRING is set)
|
|
108
|
+
2. Account key (if AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_KEY are set)
|
|
109
|
+
3. DefaultAzureCredential (AAD - managed identity, workload identity, etc.)
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
AzureBlobObjectStore instance
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
ValueError: If configuration is invalid or missing required variables
|
|
116
|
+
"""
|
|
117
|
+
logger.info("Creating Azure Blob Storage object store client")
|
|
118
|
+
|
|
119
|
+
connection_string = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
|
|
120
|
+
account = os.getenv("AZURE_STORAGE_ACCOUNT")
|
|
121
|
+
account_key = os.getenv("AZURE_STORAGE_KEY")
|
|
122
|
+
endpoint = os.getenv("AZURE_STORAGE_ENDPOINT")
|
|
123
|
+
|
|
124
|
+
# Validate configuration - need either connection string or account name
|
|
125
|
+
if not connection_string and not account:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
"Azure Blob Storage requires either AZURE_STORAGE_CONNECTION_STRING "
|
|
128
|
+
"or AZURE_STORAGE_ACCOUNT to be set"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return AzureBlobObjectStore(
|
|
132
|
+
account=account,
|
|
133
|
+
endpoint=endpoint,
|
|
134
|
+
connection_string=connection_string,
|
|
135
|
+
account_key=account_key,
|
|
136
|
+
)
|