aisberg 0.1.0__py3-none-any.whl → 0.2.0__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.
aisberg/modules/models.py CHANGED
@@ -25,7 +25,7 @@ class AbstractModelsModule(ABC):
25
25
  ValueError: If no collections are found.
26
26
  Exception: If there is an error fetching the collections.
27
27
  """
28
- pass
28
+ ...
29
29
 
30
30
  @abstractmethod
31
31
  def get(self, model_id: str) -> Model:
@@ -40,7 +40,7 @@ class AbstractModelsModule(ABC):
40
40
  Raises:
41
41
  ValueError: If the specified model is not found.
42
42
  """
43
- pass
43
+ ...
44
44
 
45
45
  @abstractmethod
46
46
  def is_available(self, model_id: str) -> bool:
@@ -52,7 +52,7 @@ class AbstractModelsModule(ABC):
52
52
  Returns:
53
53
  bool: True if the model is available, False otherwise.
54
54
  """
55
- pass
55
+ ...
56
56
 
57
57
  @staticmethod
58
58
  def _get_model_by_id(models: List[Model], model_id: str) -> Model | None:
aisberg/modules/s3.py ADDED
@@ -0,0 +1,316 @@
1
+ import os
2
+ import io
3
+ import sys
4
+ import mimetypes
5
+ import logging
6
+ from datetime import datetime
7
+ from abc import ABC, abstractmethod
8
+ from typing import Optional, Dict, Any, Union
9
+
10
+ logger = logging.getLogger(__name__)
11
+ logger.setLevel(logging.INFO)
12
+
13
+
14
+ # -------- Progress Bar --------
15
+ class ProgressPercentage:
16
+ def __init__(self, file_size, object_name, bar_length=30, verbose=False):
17
+ """
18
+ Initialize the ProgressPercentage class.
19
+ """
20
+ self._file_size = file_size / 1024 / 1024 # MB
21
+ self._seen_so_far = 0
22
+ self._object_name = object_name
23
+ self._bar_length = bar_length
24
+ self._verbose = verbose
25
+
26
+ def __call__(self, bytes_amount):
27
+ if not self._verbose:
28
+ return
29
+
30
+ self._seen_so_far += bytes_amount / 1024 / 1024 # MB
31
+ percentage = (self._seen_so_far / self._file_size) * 100
32
+ bar_filled_length = int(self._bar_length * self._seen_so_far // self._file_size)
33
+ bar = "█" * bar_filled_length + "-" * (self._bar_length - bar_filled_length)
34
+ sys.stdout.write(
35
+ f"\r{self._object_name}: |{bar}| {self._seen_so_far:.2f} MB / "
36
+ f"{self._file_size:.2f} MB ({percentage:.2f}%)"
37
+ )
38
+ sys.stdout.flush()
39
+ if self._seen_so_far >= self._file_size:
40
+ sys.stdout.write("\n")
41
+ sys.stdout.flush()
42
+
43
+
44
+ # -------- Base S3Module --------
45
+ class BaseS3Module(ABC):
46
+ """
47
+ Base abstraite pour modules S3.
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ access_key_id: str,
53
+ secret_access_key: str,
54
+ endpoint_url: Optional[str] = None,
55
+ region_name: str = "fr-par",
56
+ verbose: bool = False,
57
+ ):
58
+ self._args = dict(
59
+ aws_access_key_id=access_key_id,
60
+ aws_secret_access_key=secret_access_key,
61
+ endpoint_url=endpoint_url,
62
+ region_name=region_name,
63
+ )
64
+ self._verbose = verbose
65
+
66
+ @abstractmethod
67
+ def _get_client(self):
68
+ """Returns the S3 client."""
69
+ ...
70
+
71
+ @staticmethod
72
+ def _prepare_metadata(file, metadata=None):
73
+ """Prepare metadata for the file.
74
+
75
+ Args:
76
+ file (str | io.BytesIO): path to the file or a BytesIO object.
77
+ metadata (dict, optional): Additional metadata to enrich the file information.
78
+
79
+ Returns:
80
+ tuple: (file_size (int), metadata (dict)) with enriched file information.
81
+ """
82
+ if metadata is None:
83
+ metadata = {}
84
+
85
+ if isinstance(file, str):
86
+ file_size = os.path.getsize(file)
87
+ file_type, _ = mimetypes.guess_type(file)
88
+ file_creation_time = datetime.fromtimestamp(
89
+ os.path.getctime(file)
90
+ ).isoformat()
91
+ file_name = os.path.basename(file)
92
+ metadata.update(
93
+ {
94
+ "FileName": file_name,
95
+ "FileSize": f"{file_size / (1024 * 1024):.2f} MB",
96
+ "FileType": file_type or "application/octet-stream",
97
+ "CreationTime": file_creation_time,
98
+ }
99
+ )
100
+ else:
101
+ file.seek(0, io.SEEK_END)
102
+ file_size = file.tell()
103
+ file.seek(0)
104
+ metadata.update(
105
+ {
106
+ "FileSize": f"{file_size / (1024 * 1024):.2f} MB",
107
+ "FileType": "application/octet-stream",
108
+ "CreationTime": datetime.now().isoformat(),
109
+ }
110
+ )
111
+ return file_size, metadata
112
+
113
+ @staticmethod
114
+ def _get_object_name(self, file, object_name):
115
+ return object_name or (file if isinstance(file, str) else "default_object_name")
116
+
117
+ @abstractmethod
118
+ def upload_file(
119
+ self,
120
+ file: Union[str, io.BytesIO],
121
+ bucket_name: str,
122
+ object_name: Optional[str] = None,
123
+ metadata: Optional[Dict[str, str]] = None,
124
+ ) -> Any:
125
+ """
126
+ Uploads a file to the S3 bucket.
127
+
128
+ Args:
129
+ file (str or BytesIO): The file to upload. Can be a path to a file or a BytesIO object.
130
+ bucket_name (str): The name of the S3 bucket.
131
+ object_name (str, optional): The object name in S3. Defaults to filename if not provided.
132
+ metadata (dict, optional): Additional metadata for the object.
133
+
134
+ Returns:
135
+ Any: True if the upload succeeded, else False or raises an exception.
136
+ """
137
+ ...
138
+
139
+ @abstractmethod
140
+ def download_file(
141
+ self,
142
+ bucket_name: str,
143
+ object_name: str,
144
+ save_to: Optional[str] = None,
145
+ ) -> Any:
146
+ """
147
+ Downloads a file from the S3 bucket.
148
+
149
+ Args:
150
+ bucket_name (str): The name of the S3 bucket.
151
+ object_name (str): The object name in S3.
152
+ save_to (str, optional): Local path to save the file. If not provided, returns file content as BytesIO.
153
+
154
+ Returns:
155
+ Any: True if the file was saved locally, else a BytesIO object with file content, or False on failure.
156
+ """
157
+ ...
158
+
159
+ @abstractmethod
160
+ def delete_file(self, bucket_name: str, object_name: str) -> Any:
161
+ """
162
+ Deletes a file from the S3 bucket.
163
+
164
+ Args:
165
+ bucket_name (str): The name of the S3 bucket.
166
+ object_name (str): The object name in S3.
167
+
168
+ Returns:
169
+ Any: True if the file was deleted, False otherwise.
170
+ """
171
+ ...
172
+
173
+ @abstractmethod
174
+ def list_files(self, bucket_name: str) -> Any:
175
+ """
176
+ Lists all files in the specified S3 bucket.
177
+
178
+ Args:
179
+ bucket_name (str): The name of the S3 bucket.
180
+
181
+ Returns:
182
+ Any: List of object names (keys) in the bucket, or an empty list on failure.
183
+ """
184
+ ...
185
+
186
+ @abstractmethod
187
+ def list_buckets(self) -> Any:
188
+ """
189
+ Lists all buckets accessible by the credentials.
190
+
191
+ Returns:
192
+ Any: List of bucket names, or an empty list on failure.
193
+ """
194
+ ...
195
+
196
+
197
+ # -------- Sync --------
198
+ class SyncS3Module(BaseS3Module):
199
+ def _get_client(self):
200
+ try:
201
+ import boto3
202
+
203
+ return boto3.client("s3", **self._args)
204
+ except ImportError:
205
+ logger.error(
206
+ "boto3 is not installed. Please install it to use S3 functionalities."
207
+ )
208
+ raise ImportError("boto3 is required for S3 operations.")
209
+ except Exception as e:
210
+ logger.error(f"Failed to create S3 client: {e}")
211
+ raise RuntimeError("Failed to create S3 client.") from e
212
+
213
+ def upload_file(self, file, bucket_name, object_name=None, metadata=None) -> bool:
214
+ s3 = self._get_client()
215
+ object_name = self._get_object_name(file, object_name)
216
+ file_size, metadata = self._prepare_metadata(file, metadata)
217
+ progress_callback = ProgressPercentage(
218
+ file_size, object_name, verbose=self._verbose
219
+ )
220
+ from boto3.s3.transfer import TransferConfig
221
+
222
+ config = TransferConfig(use_threads=False)
223
+ extra_args = {"Metadata": metadata}
224
+
225
+ try:
226
+ if isinstance(file, str):
227
+ s3.upload_file(
228
+ file,
229
+ bucket_name,
230
+ object_name,
231
+ Config=config,
232
+ Callback=progress_callback,
233
+ ExtraArgs=extra_args,
234
+ )
235
+ else:
236
+ s3.upload_fileobj(
237
+ file,
238
+ bucket_name,
239
+ object_name,
240
+ Config=config,
241
+ Callback=progress_callback,
242
+ ExtraArgs=extra_args,
243
+ )
244
+ except Exception as e:
245
+ logger.error(f"Upload failed: {e}")
246
+ return False
247
+ return True
248
+
249
+ def download_file(self, bucket_name, object_name, save_to=None):
250
+ s3 = self._get_client()
251
+ from boto3.s3.transfer import TransferConfig
252
+
253
+ try:
254
+ obj = s3.head_object(Bucket=bucket_name, Key=object_name)
255
+ file_size = obj["ContentLength"]
256
+ progress_callback = ProgressPercentage(
257
+ file_size, object_name, verbose=self._verbose
258
+ )
259
+ config = TransferConfig(use_threads=False)
260
+
261
+ if self._verbose:
262
+ print(
263
+ f"Downloading {object_name} from bucket {bucket_name} "
264
+ f"({file_size / (1024 * 1024):.2f} MB)"
265
+ )
266
+
267
+ if save_to:
268
+ s3.download_file(
269
+ bucket_name,
270
+ object_name,
271
+ save_to,
272
+ Config=config,
273
+ Callback=progress_callback,
274
+ )
275
+ return True
276
+ else:
277
+ file_obj = io.BytesIO()
278
+ s3.download_fileobj(
279
+ bucket_name,
280
+ object_name,
281
+ file_obj,
282
+ Config=config,
283
+ Callback=progress_callback,
284
+ )
285
+ file_obj.seek(0)
286
+ return file_obj
287
+ except Exception as e:
288
+ logger.error(f"Download failed: {e}")
289
+ return False
290
+
291
+ def delete_file(self, bucket_name, object_name):
292
+ s3 = self._get_client()
293
+ try:
294
+ s3.delete_object(Bucket=bucket_name, Key=object_name)
295
+ return True
296
+ except Exception as e:
297
+ logger.error(f"Delete failed: {e}")
298
+ return False
299
+
300
+ def list_files(self, bucket_name):
301
+ s3 = self._get_client()
302
+ try:
303
+ response = s3.list_objects_v2(Bucket=bucket_name)
304
+ return [obj["Key"] for obj in response.get("Contents", [])]
305
+ except Exception as e:
306
+ logger.error(f"List files failed: {e}")
307
+ return []
308
+
309
+ def list_buckets(self):
310
+ s3 = self._get_client()
311
+ try:
312
+ response = s3.list_buckets()
313
+ return [bucket["Name"] for bucket in response.get("Buckets", [])]
314
+ except Exception as e:
315
+ logger.error(f"List buckets failed: {e}")
316
+ return []
@@ -28,7 +28,7 @@ class AbstractWorkflowsModule(ABC):
28
28
  Raises:
29
29
  Exception: If there is an error fetching the workflows.
30
30
  """
31
- pass
31
+ ...
32
32
 
33
33
  @abstractmethod
34
34
  def details(self, workflow_id: str) -> WorkflowDetails:
@@ -44,7 +44,7 @@ class AbstractWorkflowsModule(ABC):
44
44
  ValueError: If the workflow with the specified ID is not found.
45
45
  Exception: If there is an error fetching the workflow details.
46
46
  """
47
- pass
47
+ ...
48
48
 
49
49
  @abstractmethod
50
50
  def run(self, workflow_id: str, data: dict = None, stream: bool = False):
@@ -67,7 +67,7 @@ class AbstractWorkflowsModule(ABC):
67
67
  ValueError: If the workflow with the specified ID is not found.
68
68
  Exception: If there is an error running the workflow.
69
69
  """
70
- pass
70
+ ...
71
71
 
72
72
 
73
73
  class SyncWorkflowsModule(SyncModule, AbstractWorkflowsModule):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisberg
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Aisberg SDK for Python - A simple and powerful SDK to interact with the Aisberg API
5
5
  Author: Free Pro
6
6
  Author-email: Mathis Lambert <mathis.lambert@freepro.com>
@@ -16,6 +16,7 @@ License-File: LICENSE
16
16
  Requires-Dist: httpx>=0.28.1
17
17
  Requires-Dist: pydantic>=2.11.7
18
18
  Requires-Dist: pydantic-settings>=2.10.1
19
+ Requires-Dist: boto3>=1.38.44
19
20
  Provides-Extra: dev
20
21
  Requires-Dist: pytest>=8.4.1; extra == "dev"
21
22
  Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"
@@ -47,6 +48,7 @@ conversational LLM workflows, collections, embeddings, and more.
47
48
  - **Environment-based configuration** (supports `.env` files and system environment variables)
48
49
  - **Context manager support** for easy resource management
49
50
  - **Custom tool registration**: Easily extend LLM capabilities with your own functions
51
+ - **Document Parsing**: Parse documents into structured data (e.g., JSON, CSV, PNG, PDF, etc.)
50
52
 
51
53
  ---
52
54
 
@@ -77,6 +79,15 @@ AISBERG_API_KEY=...
77
79
  AISBERG_BASE_URL=https://url
78
80
  ```
79
81
 
82
+ In order to use the Document Parsing feature, you also need to set the `S3` credentials - ask the FreePro team for
83
+ these:
84
+
85
+ ```env
86
+ S3_ACCESS_KEY_ID=...
87
+ S3_SECRET_ACCESS_KEY=...
88
+ S3_ENDPOINT=https://s3.endpoint
89
+ ```
90
+
80
91
  ### 2. **Synchronous Usage**
81
92
 
82
93
  ```python
@@ -127,6 +138,7 @@ asyncio.run(main())
127
138
  * `client.models` — Model discovery & info
128
139
  * `client.workflows` — Workflow management & execution
129
140
  * `client.tools` — Register and execute tools for LLM tool calls
141
+ * `client.documents` — Document parsing and management
130
142
 
131
143
  Each module is available both in the sync and async clients with similar APIs.
132
144
 
@@ -173,6 +185,9 @@ client = AisbergClient(
173
185
  * `AISBERG_API_KEY`
174
186
  * `AISBERG_BASE_URL`
175
187
  * `AISBERG_TIMEOUT` (optional)
188
+ * `S3_ACCESS_KEY_ID` (for document parsing)(optional)
189
+ * `S3_SECRET_ACCESS_KEY` (for document parsing)(optional)
190
+ * `S3_ENDPOINT` (for document parsing)(optional)
176
191
 
177
192
  ### **Using in a Context Manager**
178
193
 
@@ -208,5 +223,3 @@ For enterprise/commercial use, please contact [Mathis Lambert](mailto:mathis.lam
208
223
  ## Support
209
224
 
210
225
  For support, bug reports, or feature requests, please contact your technical representative.
211
-
212
- ---
@@ -1,43 +1,46 @@
1
1
  aisberg/__init__.py,sha256=jMX3F2Fh5JobAkRMKGAcOpmNdoxSthgR4v_oM-Yw1l0,141
2
- aisberg/async_client.py,sha256=wxwkRUjxFbBlcj3D0aFspCVX5aACCksVhG9ZPVYrtx4,3547
3
- aisberg/client.py,sha256=-UgM9pi-R_qeUmods8sWTxBVGM13pNUfLJv8Zq1vQto,3586
4
- aisberg/config.py,sha256=tYuaE8WQFyyGhXEgF3kKLX7wM4PDIv6vDoezXaryOhk,441
2
+ aisberg/async_client.py,sha256=0hO2lzdP2Vcb4qV619aJLrsxeXmfYj5wo0mog1bda5Q,3816
3
+ aisberg/client.py,sha256=W1i9mh-o7f283kz2s9B2nHBCegJGN0Lgf1q0lAMNx9I,3853
4
+ aisberg/config.py,sha256=6qSucVFxCBD9TiISDh2bTt7QlrjwvptTwEtcbj4Wt8k,610
5
5
  aisberg/exceptions.py,sha256=T1ioitOczdkmW3-8XfPG0ta_O2WqzS1iQtzhDBucb5Y,515
6
6
  aisberg/utils.py,sha256=4wkrpC5gz8PJWw3kZqaRbd3KekrI37zlDC__JiAVitw,3552
7
7
  aisberg/abstract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  aisberg/abstract/modules.py,sha256=aRmB21oiL9NCZsHUx8zB0Q8VvZAZBucsZxYv5l7JygY,1698
9
9
  aisberg/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- aisberg/api/async_endpoints.py,sha256=cYOmUGBnMrvj8zaiek_Cjut6tB3paEIlJRHjRbggQBc,8279
11
- aisberg/api/endpoints.py,sha256=Ni-boFbHpB4ZiCbBwLCzoy8bxRTie-LHmBddqbwVn7Q,8003
10
+ aisberg/api/async_endpoints.py,sha256=UZhz7_JeGnkQ1AWE7gEvvOdbaBUGE1nofG0NddqRctg,10982
11
+ aisberg/api/endpoints.py,sha256=ByVxBVxrdPo-_8G0vzb_PnrwkmOSPI09koBsHjzl3gg,10610
12
12
  aisberg/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  aisberg/models/chat.py,sha256=LcvOgQm9Aan7pS4S90h4lrdzENX-NebA9pAKYdcDLB8,3667
14
- aisberg/models/collections.py,sha256=gtcpyMfUVkfZkWP82AlsfNDT0mM_wREdjnR32i3DP20,806
14
+ aisberg/models/collections.py,sha256=Je9THFx-2qfTgmd_AktRd2oi6YeCw-j3iLLtlUdmaJ0,1103
15
+ aisberg/models/documents.py,sha256=-9jNPRqMQEhkBMtZxDv8Fe0r8X91cpgQCv0FqPL8qH8,916
15
16
  aisberg/models/embeddings.py,sha256=gBGXR3DgyBCWB9Vky-iowWh_2Md7wa57I3fWxIrl77I,2409
16
17
  aisberg/models/models.py,sha256=NcECFpeVjt9nzQEN8lggDy-SesDSDFgSAYhqWz0dupA,1206
17
- aisberg/models/requests.py,sha256=9QXt9COo3GfubLQR5AgajxaDEr-ZOHrdjp-j9nyZrlw,205
18
+ aisberg/models/requests.py,sha256=oCihxhUBMMaFtSKitnachNbXfCak4NVSWviurXU0orA,297
18
19
  aisberg/models/token.py,sha256=p3-uxCZMHbe4yryQdH21iDnPh-etJWgvUDUpCXV2xhk,190
19
20
  aisberg/models/tools.py,sha256=dO8-O-tV9usakviEvWzT7Z-dG5s7EkVV8cg5CyoxZHg,1830
20
21
  aisberg/models/workflows.py,sha256=CiqJdHsSFrOo2DAYNvYFvFOmO0hyg0xUehktkn3maSg,1258
21
- aisberg/modules/__init__.py,sha256=i499QPWq-JB596dRVuBFNleYoldJshYXGmC4oed0f58,725
22
- aisberg/modules/chat.py,sha256=WrMvq0O5gdBggoGm_dJcJywsHJvlKKYBUQ5HgPipQuU,13822
23
- aisberg/modules/collections.py,sha256=kgV7zFHme6d2SXPKITJknxnk1yc6SoWz2LGnGoifon0,3947
24
- aisberg/modules/document.py,sha256=twloRFq1wRS4j6fzth77IdceAaSrdDULzu3hlTiIsrA,3902
25
- aisberg/modules/embeddings.py,sha256=wq7DlOXVQBP9-V5f4ytY4nnD60DAJ49v6JFlBuJwmEs,10470
26
- aisberg/modules/me.py,sha256=yN4-ZYVDLViwz1oXbDpF1_1gULWiBf5GL0wj9-Pp-H4,2145
27
- aisberg/modules/models.py,sha256=EIyWOkO2FaOYV-fNB-42-AEY2bob6yA1_4bqlwKs6JY,3048
22
+ aisberg/modules/__init__.py,sha256=Gfag_zlHi-f7t0UN41ZhJu80gdTkaLXk9IOnV8ug6dQ,894
23
+ aisberg/modules/chat.py,sha256=q_Ob7stzFNZgh1ltktOoHTEDfKhwH3g6KxfDqMNqyP4,14129
24
+ aisberg/modules/collections.py,sha256=Spk9kt88BDwGU3R9wUf7XJzq_wtjnuPdDgvhEhayIU8,16273
25
+ aisberg/modules/documents.py,sha256=YJhGyyy4noj2Dj5XHDOy8RMlseqP8BYkcRnfaft3dJ4,5930
26
+ aisberg/modules/embeddings.py,sha256=UV4lzNTIvooGNisAIS8sUmZ0rAxs3Omq-bnPhlyqQ74,10627
27
+ aisberg/modules/me.py,sha256=VcbXBvcCNPoCKYHjDLvevuZWTJjQx3LLBzPFYkZKlb8,2144
28
+ aisberg/modules/models.py,sha256=IWa2ezrWS4uQQPzx-YBYrBkRgC_ZnMJCnxFB2Az0DkA,3045
29
+ aisberg/modules/s3.py,sha256=2pupGSaHxu4LzxwhMbxgYFt9-ILLcjF74iYmLtpmwY4,10170
28
30
  aisberg/modules/tools.py,sha256=TnTIfjQuPhPImtWTjEy3UCmXeroPrYX3BRzTvT9nIkk,2424
29
- aisberg/modules/workflows.py,sha256=TGDriJYy__dRBwP-MK-8zl6mlzZs22-0_TUqYYTeVfs,5004
31
+ aisberg/modules/workflows.py,sha256=AxyBwCnZkRdgKHUOAoYXMAJH6J7K-qaL1psZ-f-MKhI,5001
30
32
  aisberg/requests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
33
  aisberg/requests/async_requests.py,sha256=4J6Gj6vY5AD9lXhSTdYdAKQIqsqH9m1uaKc7XLDKWx8,2849
32
34
  aisberg/requests/sync_requests.py,sha256=ov7GDgx4C-oQ9xEZ7VQsGVY1fnuqRpPwjS0H_yH1yb8,2839
33
- aisberg-0.1.0.dist-info/licenses/LICENSE,sha256=dCGgiGa4f14s5mzTYnj1wIZNqGRVG2bUYyyk7nzKlEo,406
35
+ aisberg-0.2.0.dist-info/licenses/LICENSE,sha256=dCGgiGa4f14s5mzTYnj1wIZNqGRVG2bUYyyk7nzKlEo,406
34
36
  tests/integration/test_collections_integration.py,sha256=HSs-Mhh5JNx2V6EeKo--G3xZq7pMk3z3gLReX7FJidg,3883
35
37
  tests/unit/test_collections_sync.py,sha256=DyizG4MIYNtBOC9TlsFdLlH5vz7USA12K9Uydlcydoo,3199
36
38
  tmp/test.py,sha256=8H3GxLztspwyt3_wLPtQkwdiLl--qqAn8ZaEUsXbwDE,743
37
39
  tmp/test_async.py,sha256=BaY3MkOIDXsersjYgnfaI43kZ42KDj5Andq5u-yO82s,4168
38
- tmp/test_doc_parse.py,sha256=b41Tsa1VkgNwyKwKoDRLNd05sIFGVaJncJGlFGiwYWY,324
40
+ tmp/test_collection.py,sha256=wV8AnxuaTsHxlzVPigG_qW6kr57lMkKH_bBm9eFfJ-I,1893
41
+ tmp/test_doc_parse.py,sha256=G8-jpZY2cuauzUK9oEvEHjE7Dgjf6LlPFg9F8WyF49g,1188
39
42
  tmp/test_sync.py,sha256=87QSz728gvjTXz2JykjF0U_mNsunDYrWsXYDjkBybI8,4929
40
- aisberg-0.1.0.dist-info/METADATA,sha256=ETmG5wRMX4W_Xr_L8ZyAXyS2BgtQcOLiIIE03vYEatA,5053
41
- aisberg-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- aisberg-0.1.0.dist-info/top_level.txt,sha256=7_CasmLkyF_h1CVRncNuAjam-DMIeMu1Rev_LpVcWoA,18
43
- aisberg-0.1.0.dist-info/RECORD,,
43
+ aisberg-0.2.0.dist-info/METADATA,sha256=BZzpCVk1OsZQEw9oomWeK8Q50BPVi_YeCvY4JXvPX4E,5604
44
+ aisberg-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
+ aisberg-0.2.0.dist-info/top_level.txt,sha256=7_CasmLkyF_h1CVRncNuAjam-DMIeMu1Rev_LpVcWoA,18
46
+ aisberg-0.2.0.dist-info/RECORD,,
tmp/test_collection.py ADDED
@@ -0,0 +1,65 @@
1
+ from aisberg import AisbergClient, AisbergAsyncClient
2
+ import json
3
+
4
+
5
+ def test_coll():
6
+ client = AisbergClient()
7
+ # client.collections.delete('test_aisberg_sdk')
8
+ #
9
+ # colls = client.collections.create('test_aisberg_sdk', {
10
+ # "chunks": [
11
+ # "This is a test chunk 1",
12
+ # "This is a test chunk 2",
13
+ # "This is a test chunk 3"
14
+ # ],
15
+ # "metadata": [
16
+ # {"source": "test1.txt", "author": "Author 1"},
17
+ # {"source": "test2.txt", "author": "Author 2"},
18
+ # {"source": "test3.txt", "author": "Author 3"}
19
+ # ]
20
+ # })
21
+
22
+
23
+ points = client.collections.insert_points('test_aisberg_sdk', {
24
+ "chunks": [
25
+ "LKFJELZFKJZLEsdfsdfKFJZLKEJF chunk 1",
26
+ "LKFJELZFKJZsdfsdfLEKFJZLKEJF chunk 2",
27
+ "LKFJELZFsdfsdfsdfKJZLEKFJZLsdfsdfKEJF chunk 3"
28
+ ],
29
+ "metadata": [
30
+ {"source": "test1.txt", "author": "Author 1"},
31
+ {"source": "test2.txt", "author": "Author 2"},
32
+ {"source": "test3.txt", "author": "Author 3"}
33
+ ]
34
+ }).points
35
+
36
+ print(f"### Collection Created: {points}\n")
37
+
38
+ points_to_delete = []
39
+ for i in range(2):
40
+ points_to_delete.append(points[i].id)
41
+ print(f"### Points to delete: {points_to_delete}\n")
42
+ a = client.collections.delete_points('test_aisberg_sdk', points_to_delete)
43
+ print(f"### Points Deleted: {a}\n")
44
+
45
+ c = client.collections.clear('test_aisberg_sdk')
46
+ print(f"### Collection Cleared: {c}\n")
47
+
48
+
49
+
50
+
51
+ async def async_test_coll():
52
+ client = AisbergAsyncClient()
53
+ await client.collections.delete('test_aisberg_sdk')
54
+
55
+ colls = await client.collections.create('test_aisberg_sdk', './tmp/test.json')
56
+
57
+ print(f"### Collection Created: {colls}\n")
58
+
59
+
60
+ if __name__ == "__main__":
61
+ test_coll()
62
+ #
63
+ # import asyncio
64
+ #
65
+ # asyncio.run(async_test_coll())
tmp/test_doc_parse.py CHANGED
@@ -1,12 +1,36 @@
1
- from aisberg import AisbergClient
2
- from aisberg.api.endpoints import parse_document
1
+ from aisberg import AisbergClient, AisbergAsyncClient
2
+ import json
3
3
 
4
- client = AisbergClient()
5
4
 
6
5
  def test_doc():
7
- file_bytes = b"Hello, this is a test document."
8
- doc = parse_document(client._client, (file_bytes, "test.txt"), source="test_source")
9
- print(doc)
6
+ client = AisbergClient()
7
+ print(client.models.list())
8
+ stt = str(input("STT model to use (default: tts-1.5): ") or "tts-1.5")
9
+ docs = client.documents.parse(
10
+ ["./tmp/test.mp3", "./tmp/test.png"],
11
+ stt_model=stt,
12
+ vlm_model="pixtral-12b-2409",
13
+ input="Que vois tu en haut à droite de l'image ?"
14
+ )
15
+
16
+ print(f"### MP3 Content: {docs[0].content.data}\n")
17
+ # print(f"### PDF Content: {docs[1].content.data}\n")
18
+ # print(f"### JSON Content: {json.dumps(docs[2].content.data, indent=2)}\n")
19
+
20
+
21
+ async def async_test_doc():
22
+ client = AisbergAsyncClient()
23
+ docs = await client.documents.parse(["./tmp/test.mp3", "./tmp/test.pdf", "./tmp/test.json"])
24
+
25
+ img = await client.documents.parse("./tmp/test.png", input="Que vois tu en haut à droite de l'image ?")
26
+
27
+ print(f"### MP3 Content: {docs[0].content.data}\n")
28
+ print(f"### PDF Content: {docs[1].content.data}\n")
29
+ print(f"### JSON Content: {json.dumps(docs[2].content.data, indent=2)}\n")
30
+
10
31
 
11
32
  if __name__ == "__main__":
12
- test_doc()
33
+ test_doc()
34
+
35
+ # import asyncio
36
+ # asyncio.run(async_test_doc())