seekrai 0.4.4__py3-none-any.whl → 0.5.1__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.
- seekrai/__init__.py +0 -1
- seekrai/abstract/api_requestor.py +108 -251
- seekrai/abstract/response_parsing.py +99 -0
- seekrai/client.py +6 -2
- seekrai/filemanager.py +92 -3
- seekrai/resources/__init__.py +6 -1
- seekrai/resources/agents/__init__.py +11 -6
- seekrai/resources/agents/agent_inference.py +236 -29
- seekrai/resources/agents/agents.py +272 -0
- seekrai/resources/agents/threads.py +454 -0
- seekrai/resources/alignment.py +3 -9
- seekrai/resources/chat/completions.py +1 -1
- seekrai/resources/completions.py +3 -9
- seekrai/resources/deployments.py +4 -9
- seekrai/resources/embeddings.py +3 -9
- seekrai/resources/files.py +250 -53
- seekrai/resources/finetune.py +3 -9
- seekrai/resources/images.py +3 -5
- seekrai/resources/ingestion.py +3 -9
- seekrai/resources/models.py +35 -124
- seekrai/resources/projects.py +4 -9
- seekrai/resources/resource_base.py +10 -0
- seekrai/resources/vectordb.py +482 -0
- seekrai/types/__init__.py +87 -0
- seekrai/types/agents/__init__.py +89 -0
- seekrai/types/agents/agent.py +42 -0
- seekrai/types/agents/runs.py +117 -0
- seekrai/types/agents/threads.py +265 -0
- seekrai/types/agents/tools/__init__.py +16 -0
- seekrai/types/agents/tools/env_model_config.py +7 -0
- seekrai/types/agents/tools/schemas/__init__.py +8 -0
- seekrai/types/agents/tools/schemas/file_search.py +9 -0
- seekrai/types/agents/tools/schemas/file_search_env.py +11 -0
- seekrai/types/agents/tools/tool.py +14 -0
- seekrai/types/agents/tools/tool_env_types.py +4 -0
- seekrai/types/agents/tools/tool_types.py +10 -0
- seekrai/types/alignment.py +6 -2
- seekrai/types/files.py +2 -0
- seekrai/types/finetune.py +1 -0
- seekrai/types/models.py +3 -0
- seekrai/types/vectordb.py +80 -0
- {seekrai-0.4.4.dist-info → seekrai-0.5.1.dist-info}/METADATA +3 -3
- seekrai-0.5.1.dist-info/RECORD +67 -0
- {seekrai-0.4.4.dist-info → seekrai-0.5.1.dist-info}/WHEEL +1 -1
- seekrai-0.4.4.dist-info/RECORD +0 -49
- {seekrai-0.4.4.dist-info → seekrai-0.5.1.dist-info}/LICENSE +0 -0
- {seekrai-0.4.4.dist-info → seekrai-0.5.1.dist-info}/entry_points.txt +0 -0
seekrai/resources/files.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Any, Dict
|
|
4
|
+
from typing import Any, Dict, Optional, Union
|
|
5
5
|
|
|
6
6
|
from seekrai.abstract import api_requestor
|
|
7
7
|
from seekrai.filemanager import DownloadManager, UploadManager
|
|
8
|
+
from seekrai.resources.resource_base import ResourceBase
|
|
8
9
|
from seekrai.seekrflow_response import SeekrFlowResponse
|
|
9
10
|
from seekrai.types import (
|
|
10
11
|
FileDeleteResponse,
|
|
@@ -12,7 +13,6 @@ from seekrai.types import (
|
|
|
12
13
|
FileObject,
|
|
13
14
|
FilePurpose,
|
|
14
15
|
FileResponse,
|
|
15
|
-
SeekrFlowClient,
|
|
16
16
|
SeekrFlowRequest,
|
|
17
17
|
)
|
|
18
18
|
from seekrai.types.files import (
|
|
@@ -22,19 +22,17 @@ from seekrai.types.files import (
|
|
|
22
22
|
from seekrai.utils import normalize_key
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def _get_local_file_metadata(file_path: Path) -> Dict[str, Any]:
|
|
26
|
+
suffix = file_path.suffix.lstrip(".")
|
|
27
|
+
size_bytes = int(file_path.stat().st_size)
|
|
28
|
+
return {
|
|
29
|
+
"suffix": suffix,
|
|
30
|
+
"size_bytes": size_bytes,
|
|
31
|
+
"filename": file_path.name,
|
|
32
|
+
}
|
|
28
33
|
|
|
29
|
-
def _get_local_file_metadata(self, file_path: Path) -> Dict[str, Any]:
|
|
30
|
-
suffix = file_path.suffix.lstrip(".")
|
|
31
|
-
size_bytes = int(file_path.stat().st_size)
|
|
32
|
-
return {
|
|
33
|
-
"suffix": suffix,
|
|
34
|
-
"size_bytes": size_bytes,
|
|
35
|
-
"filename": file_path.name,
|
|
36
|
-
}
|
|
37
34
|
|
|
35
|
+
class Files(ResourceBase):
|
|
38
36
|
def upload(
|
|
39
37
|
self, file: Path | str, *, purpose: FilePurpose | str = FilePurpose.FineTune
|
|
40
38
|
) -> FileResponse:
|
|
@@ -48,7 +46,7 @@ class Files:
|
|
|
48
46
|
|
|
49
47
|
# Do the metadata validation (fail fast before uploading) for Alignment purpose
|
|
50
48
|
if purpose == FilePurpose.Alignment:
|
|
51
|
-
file_metadata =
|
|
49
|
+
file_metadata = _get_local_file_metadata(file)
|
|
52
50
|
suffix = file_metadata["suffix"]
|
|
53
51
|
size = file_metadata["size_bytes"]
|
|
54
52
|
metadata_validation = self.validate_align_file_metadata(
|
|
@@ -98,7 +96,7 @@ class Files:
|
|
|
98
96
|
# Validate all files before uploading (fail fast)
|
|
99
97
|
if purpose == FilePurpose.Alignment:
|
|
100
98
|
for file_path in file_paths:
|
|
101
|
-
file_metadata =
|
|
99
|
+
file_metadata = _get_local_file_metadata(file_path)
|
|
102
100
|
suffix = file_metadata["suffix"]
|
|
103
101
|
size = file_metadata["size_bytes"]
|
|
104
102
|
metadata_validation = self.validate_align_file_metadata(
|
|
@@ -121,31 +119,6 @@ class Files:
|
|
|
121
119
|
|
|
122
120
|
return file_responses
|
|
123
121
|
|
|
124
|
-
def list(self) -> FileList:
|
|
125
|
-
requestor = api_requestor.APIRequestor(
|
|
126
|
-
client=self._client,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
response, _, _ = requestor.request(
|
|
130
|
-
options=SeekrFlowRequest(
|
|
131
|
-
method="GET",
|
|
132
|
-
url="flow/files",
|
|
133
|
-
),
|
|
134
|
-
stream=False,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
assert isinstance(response, SeekrFlowResponse)
|
|
138
|
-
files = [
|
|
139
|
-
FileResponse(
|
|
140
|
-
id=file["id"],
|
|
141
|
-
filename=file["filename"],
|
|
142
|
-
created_at=file["created_at"],
|
|
143
|
-
object="file",
|
|
144
|
-
)
|
|
145
|
-
for file in response.data["data"]
|
|
146
|
-
]
|
|
147
|
-
return FileList(object="list", data=files)
|
|
148
|
-
|
|
149
122
|
def retrieve(self, id: str) -> FileResponse:
|
|
150
123
|
requestor = api_requestor.APIRequestor(
|
|
151
124
|
client=self._client,
|
|
@@ -217,39 +190,126 @@ class Files:
|
|
|
217
190
|
options=SeekrFlowRequest(
|
|
218
191
|
method="POST",
|
|
219
192
|
url="flow/files/validate_metadata",
|
|
220
|
-
params=request_body.
|
|
193
|
+
params=request_body.model_dump(),
|
|
221
194
|
),
|
|
222
195
|
stream=False,
|
|
223
196
|
)
|
|
224
197
|
|
|
225
198
|
return AlignFileMetadataValidationResp(**response.data)
|
|
226
199
|
|
|
200
|
+
def list(
|
|
201
|
+
self,
|
|
202
|
+
limit: Optional[int] = None,
|
|
203
|
+
offset: Optional[int] = None,
|
|
204
|
+
sort_by: Optional[str] = None,
|
|
205
|
+
sort_order: Optional[str] = None,
|
|
206
|
+
purpose: Optional[Union[FilePurpose, str]] = None,
|
|
207
|
+
) -> FileList:
|
|
208
|
+
"""
|
|
209
|
+
List files with pagination, sorting, and filtering options.
|
|
227
210
|
|
|
228
|
-
|
|
229
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
230
|
-
self._client = client
|
|
211
|
+
All parameter defaults are handled by the API if not specified.
|
|
231
212
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
213
|
+
Args:
|
|
214
|
+
limit: Maximum number of files to return
|
|
215
|
+
offset: Number of files to skip
|
|
216
|
+
sort_by: Field to sort by ('created_at', 'filename', 'type', or 'size')
|
|
217
|
+
sort_order: Sort order ('asc' or 'desc')
|
|
218
|
+
purpose: Filter by file purpose (FilePurpose enum or string)
|
|
236
219
|
|
|
237
|
-
|
|
220
|
+
Returns:
|
|
221
|
+
A FileList object containing the list of files
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
Exception: If the API request fails
|
|
225
|
+
"""
|
|
226
|
+
# Build query parameters, only including non-None values
|
|
227
|
+
params: Dict[str, Any] = {}
|
|
228
|
+
if limit is not None:
|
|
229
|
+
params["limit"] = limit
|
|
230
|
+
if offset is not None:
|
|
231
|
+
params["offset"] = offset
|
|
232
|
+
if sort_by is not None:
|
|
233
|
+
params["sort_by"] = sort_by
|
|
234
|
+
if sort_order is not None:
|
|
235
|
+
params["sort_order"] = sort_order
|
|
236
|
+
|
|
237
|
+
# Add purpose filter if provided, converting from enum if needed
|
|
238
|
+
if purpose is not None:
|
|
239
|
+
params["purpose"] = (
|
|
240
|
+
purpose.value if isinstance(purpose, FilePurpose) else purpose
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Create request and use the API requestor
|
|
244
|
+
requestor = api_requestor.APIRequestor(client=self._client)
|
|
245
|
+
|
|
246
|
+
response, _, _ = requestor.request(
|
|
247
|
+
options=SeekrFlowRequest(
|
|
248
|
+
method="GET",
|
|
249
|
+
url="flow/files",
|
|
250
|
+
params=params,
|
|
251
|
+
),
|
|
252
|
+
stream=False,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
assert isinstance(response, SeekrFlowResponse)
|
|
256
|
+
|
|
257
|
+
return FileList.parse_obj(response.data)
|
|
258
|
+
|
|
259
|
+
def rename(self, id: str, new_filename: str) -> FileResponse:
|
|
260
|
+
"""
|
|
261
|
+
Rename a file.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
id (str): ID of the file to rename.
|
|
265
|
+
new_filename (str): New filename for the file.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
FileResponse: Object containing information about the renamed file.
|
|
269
|
+
"""
|
|
238
270
|
requestor = api_requestor.APIRequestor(
|
|
239
271
|
client=self._client,
|
|
240
272
|
)
|
|
241
273
|
|
|
242
|
-
response, _, _ =
|
|
274
|
+
response, _, _ = requestor.request(
|
|
243
275
|
options=SeekrFlowRequest(
|
|
244
|
-
method="
|
|
245
|
-
url="flow/files",
|
|
276
|
+
method="PUT",
|
|
277
|
+
url=f"flow/files/{id}/rename",
|
|
278
|
+
params={"new_filename": new_filename},
|
|
246
279
|
),
|
|
247
280
|
stream=False,
|
|
248
281
|
)
|
|
249
282
|
|
|
250
283
|
assert isinstance(response, SeekrFlowResponse)
|
|
251
284
|
|
|
252
|
-
return
|
|
285
|
+
return FileResponse(**response.data)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class AsyncFiles(ResourceBase):
|
|
289
|
+
async def validate_align_file_metadata(
|
|
290
|
+
self,
|
|
291
|
+
purpose: FilePurpose,
|
|
292
|
+
suffix: str,
|
|
293
|
+
size: int,
|
|
294
|
+
) -> AlignFileMetadataValidationResp:
|
|
295
|
+
requestor = api_requestor.APIRequestor(client=self._client)
|
|
296
|
+
|
|
297
|
+
request_body = AlignFileMetadataValidationReq(
|
|
298
|
+
purpose=purpose,
|
|
299
|
+
suffix=suffix,
|
|
300
|
+
size=size,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
response, _, _ = await requestor.arequest(
|
|
304
|
+
options=SeekrFlowRequest(
|
|
305
|
+
method="POST",
|
|
306
|
+
url="flow/files/validate_metadata",
|
|
307
|
+
params=request_body.model_dump(),
|
|
308
|
+
),
|
|
309
|
+
stream=False,
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
return AlignFileMetadataValidationResp(**response.data)
|
|
253
313
|
|
|
254
314
|
async def retrieve(self, id: str) -> FileResponse:
|
|
255
315
|
requestor = api_requestor.APIRequestor(
|
|
@@ -289,3 +349,140 @@ class AsyncFiles:
|
|
|
289
349
|
assert isinstance(response, SeekrFlowResponse)
|
|
290
350
|
|
|
291
351
|
return FileDeleteResponse(**response.data)
|
|
352
|
+
|
|
353
|
+
async def bulk_upload(
|
|
354
|
+
self,
|
|
355
|
+
files: list[Path | str],
|
|
356
|
+
*,
|
|
357
|
+
purpose: FilePurpose | str = FilePurpose.FineTune,
|
|
358
|
+
) -> list[FileResponse]:
|
|
359
|
+
"""
|
|
360
|
+
Upload multiple files in bulk asynchronously.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
files: List of file paths to upload
|
|
364
|
+
purpose: The purpose of the files (defaults to FineTune)
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
List of FileResponse objects for each uploaded file
|
|
368
|
+
"""
|
|
369
|
+
if isinstance(purpose, str):
|
|
370
|
+
purpose = FilePurpose(purpose)
|
|
371
|
+
|
|
372
|
+
assert isinstance(purpose, FilePurpose)
|
|
373
|
+
|
|
374
|
+
# Convert string paths to Path objects
|
|
375
|
+
file_paths = [Path(file) if isinstance(file, str) else file for file in files]
|
|
376
|
+
|
|
377
|
+
# Validate all files before uploading (fail fast)
|
|
378
|
+
if purpose == FilePurpose.Alignment:
|
|
379
|
+
for file_path in file_paths:
|
|
380
|
+
file_metadata = _get_local_file_metadata(file_path)
|
|
381
|
+
suffix = file_metadata["suffix"]
|
|
382
|
+
size = file_metadata["size_bytes"]
|
|
383
|
+
metadata_validation = await self.validate_align_file_metadata(
|
|
384
|
+
purpose,
|
|
385
|
+
suffix,
|
|
386
|
+
size,
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
if not metadata_validation.is_valid:
|
|
390
|
+
assert metadata_validation.errors is not None # To appease linter
|
|
391
|
+
raise ValueError(
|
|
392
|
+
f"Alignment file metadata validation failed for {file_path.name}: {metadata_validation.errors}"
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Upload the files to s3
|
|
396
|
+
upload_manager = UploadManager(self._client)
|
|
397
|
+
file_responses = await upload_manager.bulk_upload_async(
|
|
398
|
+
"flow/bulk_files", file_paths, purpose=purpose, redirect=True
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
return file_responses
|
|
402
|
+
|
|
403
|
+
async def list(
|
|
404
|
+
self,
|
|
405
|
+
limit: Optional[int] = None,
|
|
406
|
+
offset: Optional[int] = None,
|
|
407
|
+
sort_by: Optional[str] = None,
|
|
408
|
+
sort_order: Optional[str] = None,
|
|
409
|
+
purpose: Optional[Union[FilePurpose, str]] = None,
|
|
410
|
+
) -> FileList:
|
|
411
|
+
"""
|
|
412
|
+
List files with pagination, sorting, and filtering options.
|
|
413
|
+
|
|
414
|
+
All parameter defaults are handled by the API if not specified.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
limit: Maximum number of files to return
|
|
418
|
+
offset: Number of files to skip
|
|
419
|
+
sort_by: Field to sort by ('created_at', 'filename', 'type', or 'size')
|
|
420
|
+
sort_order: Sort order ('asc' or 'desc')
|
|
421
|
+
purpose: Filter by file purpose (FilePurpose enum or string)
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
A FileList object containing the list of files
|
|
425
|
+
|
|
426
|
+
Raises:
|
|
427
|
+
Exception: If the API request fails
|
|
428
|
+
"""
|
|
429
|
+
# Build query parameters, only including non-None values
|
|
430
|
+
params: Dict[str, Any] = {}
|
|
431
|
+
if limit is not None:
|
|
432
|
+
params["limit"] = limit
|
|
433
|
+
if offset is not None:
|
|
434
|
+
params["offset"] = offset
|
|
435
|
+
if sort_by is not None:
|
|
436
|
+
params["sort_by"] = sort_by
|
|
437
|
+
if sort_order is not None:
|
|
438
|
+
params["sort_order"] = sort_order
|
|
439
|
+
|
|
440
|
+
# Add purpose filter if provided, converting from enum if needed
|
|
441
|
+
if purpose is not None:
|
|
442
|
+
params["purpose"] = (
|
|
443
|
+
purpose.value if isinstance(purpose, FilePurpose) else purpose
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
# Create request and use the API requestor
|
|
447
|
+
requestor = api_requestor.APIRequestor(client=self._client)
|
|
448
|
+
|
|
449
|
+
response, _, _ = await requestor.arequest(
|
|
450
|
+
options=SeekrFlowRequest(
|
|
451
|
+
method="GET",
|
|
452
|
+
url="flow/files",
|
|
453
|
+
params=params,
|
|
454
|
+
),
|
|
455
|
+
stream=False,
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
assert isinstance(response, SeekrFlowResponse)
|
|
459
|
+
|
|
460
|
+
return FileList.parse_obj(response.data)
|
|
461
|
+
|
|
462
|
+
async def rename(self, id: str, new_filename: str) -> FileResponse:
|
|
463
|
+
"""
|
|
464
|
+
Rename a file asynchronously.
|
|
465
|
+
|
|
466
|
+
Args:
|
|
467
|
+
id (str): ID of the file to rename.
|
|
468
|
+
new_filename (str): New filename for the file.
|
|
469
|
+
|
|
470
|
+
Returns:
|
|
471
|
+
FileResponse: Object containing information about the renamed file.
|
|
472
|
+
"""
|
|
473
|
+
requestor = api_requestor.APIRequestor(
|
|
474
|
+
client=self._client,
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
response, _, _ = await requestor.arequest(
|
|
478
|
+
options=SeekrFlowRequest(
|
|
479
|
+
method="PUT",
|
|
480
|
+
url=f"flow/files/{id}/rename",
|
|
481
|
+
params={"new_filename": new_filename},
|
|
482
|
+
),
|
|
483
|
+
stream=False,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
assert isinstance(response, SeekrFlowResponse)
|
|
487
|
+
|
|
488
|
+
return FileResponse(**response.data)
|
seekrai/resources/finetune.py
CHANGED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
from seekrai.abstract import api_requestor
|
|
6
|
+
from seekrai.resources.resource_base import ResourceBase
|
|
6
7
|
from seekrai.seekrflow_response import SeekrFlowResponse
|
|
7
8
|
from seekrai.types import (
|
|
8
9
|
FinetuneDownloadResult,
|
|
@@ -11,16 +12,12 @@ from seekrai.types import (
|
|
|
11
12
|
FinetuneRequest,
|
|
12
13
|
FinetuneResponse,
|
|
13
14
|
InfrastructureConfig,
|
|
14
|
-
SeekrFlowClient,
|
|
15
15
|
SeekrFlowRequest,
|
|
16
16
|
TrainingConfig,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class FineTuning:
|
|
21
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
22
|
-
self._client = client
|
|
23
|
-
|
|
20
|
+
class FineTuning(ResourceBase):
|
|
24
21
|
def create(
|
|
25
22
|
self,
|
|
26
23
|
*,
|
|
@@ -246,10 +243,7 @@ class FineTuning:
|
|
|
246
243
|
return FinetuneListEvents(**response.data)
|
|
247
244
|
|
|
248
245
|
|
|
249
|
-
class AsyncFineTuning:
|
|
250
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
251
|
-
self._client = client
|
|
252
|
-
|
|
246
|
+
class AsyncFineTuning(ResourceBase):
|
|
253
247
|
async def create(
|
|
254
248
|
self,
|
|
255
249
|
*,
|
seekrai/resources/images.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from seekrai.abstract import api_requestor
|
|
4
|
+
from seekrai.resources.resource_base import ResourceBase
|
|
4
5
|
from seekrai.seekrflow_response import SeekrFlowResponse
|
|
5
6
|
from seekrai.types import (
|
|
6
7
|
ImageRequest,
|
|
@@ -10,10 +11,7 @@ from seekrai.types import (
|
|
|
10
11
|
)
|
|
11
12
|
|
|
12
13
|
|
|
13
|
-
class Images:
|
|
14
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
15
|
-
self._client = client
|
|
16
|
-
|
|
14
|
+
class Images(ResourceBase):
|
|
17
15
|
def generate(
|
|
18
16
|
self,
|
|
19
17
|
*,
|
|
@@ -83,7 +81,7 @@ class Images:
|
|
|
83
81
|
return ImageResponse(**response.data)
|
|
84
82
|
|
|
85
83
|
|
|
86
|
-
class AsyncImages:
|
|
84
|
+
class AsyncImages(ResourceBase):
|
|
87
85
|
def __init__(self, client: SeekrFlowClient) -> None:
|
|
88
86
|
self._client = client
|
|
89
87
|
|
seekrai/resources/ingestion.py
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
from typing import List
|
|
2
2
|
|
|
3
3
|
from seekrai.abstract import api_requestor
|
|
4
|
+
from seekrai.resources.resource_base import ResourceBase
|
|
4
5
|
from seekrai.seekrflow_response import SeekrFlowResponse
|
|
5
6
|
from seekrai.types import (
|
|
6
|
-
SeekrFlowClient,
|
|
7
7
|
SeekrFlowRequest,
|
|
8
8
|
)
|
|
9
9
|
from seekrai.types.ingestion import IngestionList, IngestionRequest, IngestionResponse
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class Ingestion:
|
|
13
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
14
|
-
self._client = client
|
|
15
|
-
|
|
12
|
+
class Ingestion(ResourceBase):
|
|
16
13
|
def ingest(
|
|
17
14
|
self,
|
|
18
15
|
files: List[str],
|
|
@@ -94,10 +91,7 @@ class Ingestion:
|
|
|
94
91
|
return IngestionResponse(**response.data)
|
|
95
92
|
|
|
96
93
|
|
|
97
|
-
class AsyncIngestion:
|
|
98
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
99
|
-
self._client = client
|
|
100
|
-
|
|
94
|
+
class AsyncIngestion(ResourceBase):
|
|
101
95
|
async def ingest(
|
|
102
96
|
self,
|
|
103
97
|
files: List[str],
|
seekrai/resources/models.py
CHANGED
|
@@ -1,56 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Any, List
|
|
6
|
-
|
|
7
|
-
from tqdm import tqdm
|
|
8
|
-
from tqdm.utils import CallbackIOWrapper
|
|
9
|
-
|
|
10
3
|
from seekrai.abstract import api_requestor
|
|
11
|
-
from seekrai.
|
|
4
|
+
from seekrai.resources.resource_base import ResourceBase
|
|
12
5
|
from seekrai.seekrflow_response import SeekrFlowResponse
|
|
13
|
-
from seekrai.types import ModelList, ModelResponse,
|
|
14
|
-
from seekrai.types.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Models:
|
|
18
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
19
|
-
self._client = client
|
|
20
|
-
|
|
21
|
-
def upload(
|
|
22
|
-
self,
|
|
23
|
-
file: Path | str,
|
|
24
|
-
*,
|
|
25
|
-
model_type: ModelType | str = ModelType.OBJECT_DETECTION,
|
|
26
|
-
) -> ModelResponse:
|
|
27
|
-
if isinstance(file, str):
|
|
28
|
-
file = Path(file)
|
|
6
|
+
from seekrai.types import ModelList, ModelResponse, SeekrFlowRequest
|
|
7
|
+
from seekrai.types.common import ObjectType
|
|
8
|
+
from seekrai.utils import parse_timestamp
|
|
29
9
|
|
|
30
|
-
requestor = api_requestor.APIRequestor(
|
|
31
|
-
client=self._client,
|
|
32
|
-
)
|
|
33
|
-
file_size = os.stat(file.as_posix()).st_size
|
|
34
|
-
|
|
35
|
-
with tqdm(
|
|
36
|
-
total=file_size,
|
|
37
|
-
unit="B",
|
|
38
|
-
unit_scale=True,
|
|
39
|
-
desc=f"Uploading model file {file.name}",
|
|
40
|
-
disable=bool(DISABLE_TQDM),
|
|
41
|
-
) as t:
|
|
42
|
-
with file.open("rb") as f:
|
|
43
|
-
reader_wrapper = CallbackIOWrapper(t.update, f, "read")
|
|
44
|
-
response, _, _ = requestor.request(
|
|
45
|
-
options=SeekrFlowRequest(
|
|
46
|
-
method="PUT",
|
|
47
|
-
url="flow/pt-models",
|
|
48
|
-
files={"files": reader_wrapper, "filename": file.name},
|
|
49
|
-
params={"purpose": model_type},
|
|
50
|
-
),
|
|
51
|
-
)
|
|
52
|
-
return ModelResponse(**response.data)
|
|
53
10
|
|
|
11
|
+
class Models(ResourceBase):
|
|
54
12
|
def list(
|
|
55
13
|
self,
|
|
56
14
|
) -> ModelList:
|
|
@@ -58,7 +16,7 @@ class Models:
|
|
|
58
16
|
Method to return list of models on the API
|
|
59
17
|
|
|
60
18
|
Returns:
|
|
61
|
-
|
|
19
|
+
ModelList: List of model objects
|
|
62
20
|
"""
|
|
63
21
|
|
|
64
22
|
requestor = api_requestor.APIRequestor(
|
|
@@ -68,95 +26,36 @@ class Models:
|
|
|
68
26
|
response, _, _ = requestor.request(
|
|
69
27
|
options=SeekrFlowRequest(
|
|
70
28
|
method="GET",
|
|
71
|
-
url="flow/
|
|
72
|
-
),
|
|
73
|
-
stream=False,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
assert isinstance(response, SeekrFlowResponse)
|
|
77
|
-
return ModelList(**response.data)
|
|
78
|
-
|
|
79
|
-
def promote(self, id: str) -> ModelResponse:
|
|
80
|
-
requestor = api_requestor.APIRequestor(
|
|
81
|
-
client=self._client,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
response, _, _ = requestor.request(
|
|
85
|
-
options=SeekrFlowRequest(
|
|
86
|
-
method="GET",
|
|
87
|
-
url=f"flow/pt-models/{id}/promote-model",
|
|
88
|
-
params={"model_id": id},
|
|
89
|
-
),
|
|
90
|
-
stream=False,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
assert isinstance(response, SeekrFlowResponse)
|
|
94
|
-
|
|
95
|
-
return ModelResponse(**response.data)
|
|
96
|
-
|
|
97
|
-
def demote(self, id: str) -> ModelResponse:
|
|
98
|
-
requestor = api_requestor.APIRequestor(
|
|
99
|
-
client=self._client,
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
response, _, _ = requestor.request(
|
|
103
|
-
options=SeekrFlowRequest(
|
|
104
|
-
method="GET",
|
|
105
|
-
url=f"flow/pt-models/{id}/demote-model",
|
|
106
|
-
params={"model_id": id},
|
|
29
|
+
url="flow/models",
|
|
107
30
|
),
|
|
108
31
|
stream=False,
|
|
109
32
|
)
|
|
110
|
-
|
|
111
33
|
assert isinstance(response, SeekrFlowResponse)
|
|
112
34
|
|
|
113
|
-
|
|
35
|
+
model_responses = [
|
|
36
|
+
ModelResponse(
|
|
37
|
+
id=str(model["id"]),
|
|
38
|
+
object=ObjectType.Model,
|
|
39
|
+
name=model["name"],
|
|
40
|
+
bytes=model["size"],
|
|
41
|
+
created_at=parse_timestamp(model["created_at"]),
|
|
42
|
+
model_type=model["model_type"],
|
|
43
|
+
)
|
|
44
|
+
for model in response.data["data"]
|
|
45
|
+
]
|
|
114
46
|
|
|
115
|
-
|
|
116
|
-
requestor = api_requestor.APIRequestor(
|
|
117
|
-
client=self._client,
|
|
118
|
-
)
|
|
47
|
+
return ModelList(data=model_responses)
|
|
119
48
|
|
|
120
|
-
if isinstance(file, str):
|
|
121
|
-
file = Path(file)
|
|
122
|
-
|
|
123
|
-
file_size = os.stat(file.as_posix()).st_size
|
|
124
|
-
|
|
125
|
-
with tqdm(
|
|
126
|
-
total=file_size,
|
|
127
|
-
unit="B",
|
|
128
|
-
unit_scale=True,
|
|
129
|
-
desc=f"Uploading file {file.name}",
|
|
130
|
-
disable=bool(DISABLE_TQDM),
|
|
131
|
-
):
|
|
132
|
-
with file.open("rb") as f:
|
|
133
|
-
response, _, _ = requestor.request(
|
|
134
|
-
options=SeekrFlowRequest(
|
|
135
|
-
method="POST",
|
|
136
|
-
url="flow/pt-models/predict",
|
|
137
|
-
files={"files": f, "filename": file.name},
|
|
138
|
-
params={"model_id": id},
|
|
139
|
-
),
|
|
140
|
-
stream=False,
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
assert isinstance(response, SeekrFlowResponse)
|
|
144
|
-
|
|
145
|
-
return response.data
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
class AsyncModels:
|
|
149
|
-
def __init__(self, client: SeekrFlowClient) -> None:
|
|
150
|
-
self._client = client
|
|
151
49
|
|
|
50
|
+
class AsyncModels(ResourceBase):
|
|
152
51
|
async def list(
|
|
153
52
|
self,
|
|
154
|
-
) ->
|
|
53
|
+
) -> ModelList:
|
|
155
54
|
"""
|
|
156
55
|
Async method to return list of models on API
|
|
157
56
|
|
|
158
57
|
Returns:
|
|
159
|
-
|
|
58
|
+
ModelList: List of model objects
|
|
160
59
|
"""
|
|
161
60
|
|
|
162
61
|
requestor = api_requestor.APIRequestor(
|
|
@@ -174,4 +73,16 @@ class AsyncModels:
|
|
|
174
73
|
assert isinstance(response, SeekrFlowResponse)
|
|
175
74
|
assert isinstance(response.data, list)
|
|
176
75
|
|
|
177
|
-
|
|
76
|
+
model_responses = [
|
|
77
|
+
ModelResponse(
|
|
78
|
+
id=str(model["id"]),
|
|
79
|
+
object=ObjectType.Model,
|
|
80
|
+
name=model["name"],
|
|
81
|
+
bytes=model["size"],
|
|
82
|
+
created_at=parse_timestamp(model["created_at"]),
|
|
83
|
+
model_type=model["model_type"],
|
|
84
|
+
)
|
|
85
|
+
for model in response.data["data"]
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
return ModelList(data=model_responses)
|