pygeai 0.6.0b6__py3-none-any.whl → 0.6.0b7__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.
- pygeai/_docs/source/content/api_reference/admin.rst +161 -0
- pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
- pygeai/_docs/source/content/api_reference/auth.rst +379 -0
- pygeai/_docs/source/content/api_reference/health.rst +58 -0
- pygeai/_docs/source/content/api_reference/project.rst +20 -18
- pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
- pygeai/_docs/source/content/api_reference.rst +6 -1
- pygeai/_docs/source/index.rst +59 -7
- pygeai/_docs/source/pygeai.auth.rst +29 -0
- pygeai/_docs/source/pygeai.cli.commands.rst +16 -0
- pygeai/_docs/source/pygeai.core.utils.rst +16 -0
- pygeai/_docs/source/pygeai.rst +1 -0
- pygeai/_docs/source/pygeai.tests.auth.rst +21 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.rst +16 -0
- pygeai/_docs/source/pygeai.tests.core.base.rst +8 -0
- pygeai/_docs/source/pygeai.tests.core.files.rst +8 -0
- pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.rst +1 -0
- pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +8 -0
- pygeai/_docs/source/pygeai.tests.organization.rst +8 -0
- pygeai/_docs/source/pygeai.tests.rst +2 -0
- pygeai/_docs/source/pygeai.tests.snippets.auth.rst +10 -0
- pygeai/_docs/source/pygeai.tests.snippets.organization.rst +40 -0
- pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
- pygeai/admin/clients.py +7 -32
- pygeai/assistant/clients.py +9 -44
- pygeai/assistant/data/clients.py +1 -0
- pygeai/assistant/data_analyst/clients.py +4 -13
- pygeai/assistant/rag/clients.py +13 -67
- pygeai/auth/clients.py +88 -14
- pygeai/auth/endpoints.py +4 -0
- pygeai/chat/clients.py +1 -0
- pygeai/cli/commands/auth.py +178 -2
- pygeai/cli/commands/lab/ai_lab.py +0 -2
- pygeai/cli/commands/organization.py +241 -0
- pygeai/core/base/clients.py +1 -0
- pygeai/core/embeddings/clients.py +3 -7
- pygeai/core/feedback/clients.py +3 -8
- pygeai/core/files/clients.py +5 -18
- pygeai/core/llm/clients.py +7 -26
- pygeai/core/models.py +107 -0
- pygeai/core/plugins/clients.py +3 -7
- pygeai/core/rerank/clients.py +3 -8
- pygeai/core/secrets/clients.py +8 -37
- pygeai/core/utils/parsers.py +32 -0
- pygeai/core/utils/validators.py +10 -0
- pygeai/evaluation/clients.py +1 -0
- pygeai/evaluation/dataset/clients.py +1 -0
- pygeai/evaluation/plan/clients.py +1 -0
- pygeai/evaluation/result/clients.py +1 -0
- pygeai/gam/clients.py +6 -25
- pygeai/health/clients.py +3 -7
- pygeai/lab/agents/clients.py +13 -53
- pygeai/lab/agents/endpoints.py +2 -0
- pygeai/lab/clients.py +1 -0
- pygeai/lab/processes/clients.py +24 -127
- pygeai/lab/strategies/clients.py +7 -25
- pygeai/lab/tools/clients.py +22 -67
- pygeai/lab/tools/endpoints.py +3 -0
- pygeai/organization/clients.py +122 -51
- pygeai/organization/endpoints.py +6 -1
- pygeai/organization/limits/clients.py +17 -91
- pygeai/organization/managers.py +157 -1
- pygeai/organization/mappers.py +76 -2
- pygeai/organization/responses.py +25 -1
- pygeai/proxy/clients.py +1 -0
- pygeai/tests/auth/test_clients.py +183 -7
- pygeai/tests/organization/test_clients.py +184 -1
- pygeai/tests/organization/test_managers.py +122 -1
- pygeai/tests/snippets/auth/__init__.py +0 -0
- pygeai/tests/snippets/organization/get_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_organization_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_project_roles.py +6 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/METADATA +1 -1
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/RECORD +85 -64
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/WHEEL +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/entry_points.txt +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/top_level.txt +0 -0
|
@@ -288,6 +288,202 @@ export_request_data_options = [
|
|
|
288
288
|
)
|
|
289
289
|
]
|
|
290
290
|
|
|
291
|
+
|
|
292
|
+
def get_memberships(option_list: list):
|
|
293
|
+
email = None
|
|
294
|
+
start_page = 1
|
|
295
|
+
page_size = 20
|
|
296
|
+
order_key = None
|
|
297
|
+
order_direction = "desc"
|
|
298
|
+
role_types = None
|
|
299
|
+
|
|
300
|
+
for option_flag, option_arg in option_list:
|
|
301
|
+
if option_flag.name == "email":
|
|
302
|
+
email = option_arg
|
|
303
|
+
if option_flag.name == "start_page":
|
|
304
|
+
start_page = int(option_arg)
|
|
305
|
+
if option_flag.name == "page_size":
|
|
306
|
+
page_size = int(option_arg)
|
|
307
|
+
if option_flag.name == "order_key":
|
|
308
|
+
order_key = option_arg
|
|
309
|
+
if option_flag.name == "order_direction":
|
|
310
|
+
order_direction = option_arg
|
|
311
|
+
if option_flag.name == "role_types":
|
|
312
|
+
role_types = option_arg
|
|
313
|
+
|
|
314
|
+
client = OrganizationClient()
|
|
315
|
+
result = client.get_memberships(email, start_page, page_size, order_key, order_direction, role_types)
|
|
316
|
+
Console.write_stdout(f"Memberships: \n{result}")
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
get_memberships_options = [
|
|
320
|
+
Option(
|
|
321
|
+
"email",
|
|
322
|
+
["--email", "-e"],
|
|
323
|
+
"Email address of the user (optional, case-insensitive)",
|
|
324
|
+
True
|
|
325
|
+
),
|
|
326
|
+
Option(
|
|
327
|
+
"start_page",
|
|
328
|
+
["--start-page"],
|
|
329
|
+
"Page number for pagination (default: 1)",
|
|
330
|
+
True
|
|
331
|
+
),
|
|
332
|
+
Option(
|
|
333
|
+
"page_size",
|
|
334
|
+
["--page-size"],
|
|
335
|
+
"Number of items per page (default: 20)",
|
|
336
|
+
True
|
|
337
|
+
),
|
|
338
|
+
Option(
|
|
339
|
+
"order_key",
|
|
340
|
+
["--order-key"],
|
|
341
|
+
"Field for sorting (only 'organizationName' supported)",
|
|
342
|
+
True
|
|
343
|
+
),
|
|
344
|
+
Option(
|
|
345
|
+
"order_direction",
|
|
346
|
+
["--order-direction"],
|
|
347
|
+
"Sort direction: asc or desc (default: desc)",
|
|
348
|
+
True
|
|
349
|
+
),
|
|
350
|
+
Option(
|
|
351
|
+
"role_types",
|
|
352
|
+
["--role-types"],
|
|
353
|
+
"Comma-separated list: backend, frontend (optional, case-insensitive)",
|
|
354
|
+
True
|
|
355
|
+
),
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def get_project_memberships(option_list: list):
|
|
360
|
+
email = None
|
|
361
|
+
start_page = 1
|
|
362
|
+
page_size = 20
|
|
363
|
+
order_key = None
|
|
364
|
+
order_direction = "desc"
|
|
365
|
+
role_types = None
|
|
366
|
+
|
|
367
|
+
for option_flag, option_arg in option_list:
|
|
368
|
+
if option_flag.name == "email":
|
|
369
|
+
email = option_arg
|
|
370
|
+
if option_flag.name == "start_page":
|
|
371
|
+
start_page = int(option_arg)
|
|
372
|
+
if option_flag.name == "page_size":
|
|
373
|
+
page_size = int(option_arg)
|
|
374
|
+
if option_flag.name == "order_key":
|
|
375
|
+
order_key = option_arg
|
|
376
|
+
if option_flag.name == "order_direction":
|
|
377
|
+
order_direction = option_arg
|
|
378
|
+
if option_flag.name == "role_types":
|
|
379
|
+
role_types = option_arg
|
|
380
|
+
|
|
381
|
+
client = OrganizationClient()
|
|
382
|
+
result = client.get_project_memberships(email, start_page, page_size, order_key, order_direction, role_types)
|
|
383
|
+
Console.write_stdout(f"Project memberships: \n{result}")
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
get_project_memberships_options = [
|
|
387
|
+
Option(
|
|
388
|
+
"email",
|
|
389
|
+
["--email", "-e"],
|
|
390
|
+
"Email address of the user (optional, case-insensitive)",
|
|
391
|
+
True
|
|
392
|
+
),
|
|
393
|
+
Option(
|
|
394
|
+
"start_page",
|
|
395
|
+
["--start-page"],
|
|
396
|
+
"Page number for pagination (default: 1)",
|
|
397
|
+
True
|
|
398
|
+
),
|
|
399
|
+
Option(
|
|
400
|
+
"page_size",
|
|
401
|
+
["--page-size"],
|
|
402
|
+
"Number of items per page (default: 20)",
|
|
403
|
+
True
|
|
404
|
+
),
|
|
405
|
+
Option(
|
|
406
|
+
"order_key",
|
|
407
|
+
["--order-key"],
|
|
408
|
+
"Field for sorting (only 'projectName' supported)",
|
|
409
|
+
True
|
|
410
|
+
),
|
|
411
|
+
Option(
|
|
412
|
+
"order_direction",
|
|
413
|
+
["--order-direction"],
|
|
414
|
+
"Sort direction: asc or desc (default: desc)",
|
|
415
|
+
True
|
|
416
|
+
),
|
|
417
|
+
Option(
|
|
418
|
+
"role_types",
|
|
419
|
+
["--role-types"],
|
|
420
|
+
"Comma-separated list: backend, frontend (optional, case-insensitive)",
|
|
421
|
+
True
|
|
422
|
+
),
|
|
423
|
+
]
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def get_project_roles(option_list: list):
|
|
427
|
+
project_id = None
|
|
428
|
+
for option_flag, option_arg in option_list:
|
|
429
|
+
if option_flag.name == "project_id":
|
|
430
|
+
project_id = option_arg
|
|
431
|
+
|
|
432
|
+
if not project_id:
|
|
433
|
+
raise MissingRequirementException("Cannot retrieve project roles without project-id")
|
|
434
|
+
|
|
435
|
+
client = OrganizationClient()
|
|
436
|
+
result = client.get_project_roles(project_id)
|
|
437
|
+
Console.write_stdout(f"Project roles: \n{result}")
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
get_project_roles_options = [
|
|
441
|
+
PROJECT_ID_OPTION,
|
|
442
|
+
]
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def get_project_members(option_list: list):
|
|
446
|
+
project_id = None
|
|
447
|
+
for option_flag, option_arg in option_list:
|
|
448
|
+
if option_flag.name == "project_id":
|
|
449
|
+
project_id = option_arg
|
|
450
|
+
|
|
451
|
+
if not project_id:
|
|
452
|
+
raise MissingRequirementException("Cannot retrieve project members without project-id")
|
|
453
|
+
|
|
454
|
+
client = OrganizationClient()
|
|
455
|
+
result = client.get_project_members(project_id)
|
|
456
|
+
Console.write_stdout(f"Project members: \n{result}")
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
get_project_members_options = [
|
|
460
|
+
PROJECT_ID_OPTION,
|
|
461
|
+
]
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def get_organization_members(option_list: list):
|
|
465
|
+
organization_id = None
|
|
466
|
+
for option_flag, option_arg in option_list:
|
|
467
|
+
if option_flag.name == "organization_id":
|
|
468
|
+
organization_id = option_arg
|
|
469
|
+
|
|
470
|
+
if not organization_id:
|
|
471
|
+
raise MissingRequirementException("Cannot retrieve organization members without organization-id")
|
|
472
|
+
|
|
473
|
+
client = OrganizationClient()
|
|
474
|
+
result = client.get_organization_members(organization_id)
|
|
475
|
+
Console.write_stdout(f"Organization members: \n{result}")
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
get_organization_members_options = [
|
|
479
|
+
Option(
|
|
480
|
+
"organization_id",
|
|
481
|
+
["--organization-id", "--oid"],
|
|
482
|
+
"GUID of the organization (required)",
|
|
483
|
+
True
|
|
484
|
+
),
|
|
485
|
+
]
|
|
486
|
+
|
|
291
487
|
organization_commands = [
|
|
292
488
|
Command(
|
|
293
489
|
"help",
|
|
@@ -370,4 +566,49 @@ organization_commands = [
|
|
|
370
566
|
[],
|
|
371
567
|
export_request_data_options
|
|
372
568
|
),
|
|
569
|
+
Command(
|
|
570
|
+
"get_memberships",
|
|
571
|
+
["get-memberships"],
|
|
572
|
+
"Get user memberships across organizations and projects",
|
|
573
|
+
get_memberships,
|
|
574
|
+
ArgumentsEnum.OPTIONAL,
|
|
575
|
+
[],
|
|
576
|
+
get_memberships_options
|
|
577
|
+
),
|
|
578
|
+
Command(
|
|
579
|
+
"get_project_memberships",
|
|
580
|
+
["get-project-memberships"],
|
|
581
|
+
"Get user project memberships within an organization",
|
|
582
|
+
get_project_memberships,
|
|
583
|
+
ArgumentsEnum.OPTIONAL,
|
|
584
|
+
[],
|
|
585
|
+
get_project_memberships_options
|
|
586
|
+
),
|
|
587
|
+
Command(
|
|
588
|
+
"get_project_roles",
|
|
589
|
+
["get-project-roles"],
|
|
590
|
+
"Get all roles supported by a project",
|
|
591
|
+
get_project_roles,
|
|
592
|
+
ArgumentsEnum.REQUIRED,
|
|
593
|
+
[],
|
|
594
|
+
get_project_roles_options
|
|
595
|
+
),
|
|
596
|
+
Command(
|
|
597
|
+
"get_project_members",
|
|
598
|
+
["get-project-members"],
|
|
599
|
+
"Get all members and their roles for a project",
|
|
600
|
+
get_project_members,
|
|
601
|
+
ArgumentsEnum.REQUIRED,
|
|
602
|
+
[],
|
|
603
|
+
get_project_members_options
|
|
604
|
+
),
|
|
605
|
+
Command(
|
|
606
|
+
"get_organization_members",
|
|
607
|
+
["get-organization-members"],
|
|
608
|
+
"Get all members and their roles for an organization",
|
|
609
|
+
get_organization_members,
|
|
610
|
+
ArgumentsEnum.REQUIRED,
|
|
611
|
+
[],
|
|
612
|
+
get_organization_members_options
|
|
613
|
+
),
|
|
373
614
|
]
|
pygeai/core/base/clients.py
CHANGED
|
@@ -3,6 +3,7 @@ from abc import ABC
|
|
|
3
3
|
from pygeai.core.base.session import get_session, Session
|
|
4
4
|
from pygeai.core.common.exceptions import MissingRequirementException
|
|
5
5
|
from pygeai.core.services.rest import ApiService
|
|
6
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class BaseClient(ABC):
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from json import JSONDecodeError
|
|
2
1
|
|
|
3
2
|
from pygeai import logger
|
|
4
3
|
from pygeai.core.base.clients import BaseClient
|
|
5
4
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
6
5
|
from pygeai.core.embeddings.endpoints import GENERATE_EMBEDDINGS
|
|
6
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
7
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class EmbeddingsClient(BaseClient):
|
|
@@ -73,10 +74,5 @@ class EmbeddingsClient(BaseClient):
|
|
|
73
74
|
data=data,
|
|
74
75
|
headers=headers
|
|
75
76
|
)
|
|
76
|
-
|
|
77
|
-
result = response.json()
|
|
78
|
-
return result
|
|
79
|
-
except JSONDecodeError as e:
|
|
80
|
-
logger.error(f"Unable to generate embeddings: JSON parsin error: {e}; Response: {response.text}")
|
|
81
|
-
raise InvalidAPIResponseException(f"Unable to generate embeddings: {response.text}")
|
|
77
|
+
return parse_json_response(response, "generate embeddings")
|
|
82
78
|
|
pygeai/core/feedback/clients.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from json import JSONDecodeError
|
|
3
1
|
from typing import Any, Union
|
|
4
2
|
|
|
5
3
|
from pygeai import logger
|
|
6
4
|
from pygeai.core.base.clients import BaseClient
|
|
7
5
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
8
6
|
from pygeai.core.feedback.endpoints import SEND_FEEDBACK_V1
|
|
7
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
8
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class FeedbackClient(BaseClient):
|
|
@@ -45,10 +45,5 @@ class FeedbackClient(BaseClient):
|
|
|
45
45
|
endpoint=endpoint,
|
|
46
46
|
data=data
|
|
47
47
|
)
|
|
48
|
-
|
|
49
|
-
result = response.json()
|
|
50
|
-
return result
|
|
51
|
-
except JSONDecodeError as e:
|
|
52
|
-
logger.error(f"Unable to send feedback. JSON parsing error: {e}. Response: {e}")
|
|
53
|
-
raise InvalidAPIResponseException(f"Unable to send feedback for request {request_id}: {response.text}")
|
|
48
|
+
return parse_json_response(response, "send feedback. JSON parsing error")
|
|
54
49
|
|
pygeai/core/files/clients.py
CHANGED
|
@@ -7,6 +7,8 @@ from pygeai.core.base.clients import BaseClient
|
|
|
7
7
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
8
8
|
from pygeai.core.files.endpoints import UPLOAD_FILE_V1, GET_FILE_V1, DELETE_FILE_V1, GET_FILE_CONTENT_V1, \
|
|
9
9
|
GET_ALL_FILES_V1
|
|
10
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
11
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class FileClient(BaseClient):
|
|
@@ -82,12 +84,7 @@ class FileClient(BaseClient):
|
|
|
82
84
|
}
|
|
83
85
|
)
|
|
84
86
|
logger.debug(f"Retrieving file details for id {file_id}")
|
|
85
|
-
|
|
86
|
-
result = response.json()
|
|
87
|
-
return result
|
|
88
|
-
except JSONDecodeError as e:
|
|
89
|
-
logger.error(f"Unable to retrieve file details for id {file_id} in project {project}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
90
|
-
raise InvalidAPIResponseException(f"Unable to retrieve file details for id {file_id}: {response.text}")
|
|
87
|
+
return parse_json_response(response, "retrieve file details for id in project", file_id=file_id, project=project)
|
|
91
88
|
|
|
92
89
|
def delete_file(self, organization: str, project: str, file_id: str) -> dict:
|
|
93
90
|
"""
|
|
@@ -113,12 +110,7 @@ class FileClient(BaseClient):
|
|
|
113
110
|
"project": project
|
|
114
111
|
}
|
|
115
112
|
)
|
|
116
|
-
|
|
117
|
-
result = response.json()
|
|
118
|
-
return result
|
|
119
|
-
except JSONDecodeError as e:
|
|
120
|
-
logger.error(f"Unable to delete file with id {file_id} in project {project}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
121
|
-
raise InvalidAPIResponseException(f"Unable to delete file with id {file_id}: {response.text}")
|
|
113
|
+
return parse_json_response(response, "delete file with id in project", file_id=file_id, project=project)
|
|
122
114
|
|
|
123
115
|
def get_file_content(self, organization: str, project: str, file_id: str) -> bytes:
|
|
124
116
|
"""
|
|
@@ -163,9 +155,4 @@ class FileClient(BaseClient):
|
|
|
163
155
|
"project": project
|
|
164
156
|
}
|
|
165
157
|
)
|
|
166
|
-
|
|
167
|
-
result = response.json()
|
|
168
|
-
return result
|
|
169
|
-
except JSONDecodeError as e:
|
|
170
|
-
logger.error(f"Unable to retrieve file list for project {project}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
171
|
-
raise InvalidAPIResponseException(f"Unable to retrieve file list for project {project}: {response.text}")
|
|
158
|
+
return parse_json_response(response, "retrieve file list for project", project=project)
|
pygeai/core/llm/clients.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from json import JSONDecodeError
|
|
3
1
|
|
|
4
2
|
from pygeai import logger
|
|
5
3
|
from pygeai.core.base.clients import BaseClient
|
|
6
4
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
5
|
from pygeai.core.llm.endpoints import GET_PROVIDER_LIST_V2, GET_PROVIDER_DATA_V2, GET_PROVIDER_MODELS_V2, \
|
|
8
6
|
GET_MODEL_DATA_V2
|
|
7
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
8
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LlmClient(BaseClient):
|
|
@@ -13,12 +13,7 @@ class LlmClient(BaseClient):
|
|
|
13
13
|
def get_provider_list(self) -> dict:
|
|
14
14
|
logger.debug("Obtaining provider list")
|
|
15
15
|
response = self.api_service.get(endpoint=GET_PROVIDER_LIST_V2)
|
|
16
|
-
|
|
17
|
-
result = response.json()
|
|
18
|
-
return result
|
|
19
|
-
except JSONDecodeError as e:
|
|
20
|
-
logger.error(f"Unable to obtain provider list: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
21
|
-
raise InvalidAPIResponseException(f"Unable to obtain provider list: {response.text}")
|
|
16
|
+
return parse_json_response(response, "obtain provider list")
|
|
22
17
|
|
|
23
18
|
def get_provider_data(self, provider_name: str) -> dict:
|
|
24
19
|
endpoint = GET_PROVIDER_DATA_V2.format(providerName=provider_name)
|
|
@@ -26,12 +21,7 @@ class LlmClient(BaseClient):
|
|
|
26
21
|
logger.debug(f"Obtaining provider data for {provider_name}")
|
|
27
22
|
|
|
28
23
|
response = self.api_service.get(endpoint=endpoint)
|
|
29
|
-
|
|
30
|
-
result = response.json()
|
|
31
|
-
return result
|
|
32
|
-
except JSONDecodeError as e:
|
|
33
|
-
logger.error(f"Unable to obtain provider data for {provider_name}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
34
|
-
raise InvalidAPIResponseException(f"Unable to obtain provider data for {provider_name}: {response.text}")
|
|
24
|
+
return parse_json_response(response, "obtain provider data", provider_name=provider_name)
|
|
35
25
|
|
|
36
26
|
def get_provider_models(self, provider_name: str) -> dict:
|
|
37
27
|
endpoint = GET_PROVIDER_MODELS_V2.format(providerName=provider_name)
|
|
@@ -39,12 +29,7 @@ class LlmClient(BaseClient):
|
|
|
39
29
|
logger.debug(f"Obtaining provider models for {provider_name}")
|
|
40
30
|
|
|
41
31
|
response = self.api_service.get(endpoint=endpoint)
|
|
42
|
-
|
|
43
|
-
result = response.json()
|
|
44
|
-
return result
|
|
45
|
-
except JSONDecodeError as e:
|
|
46
|
-
logger.error(f"Unable to obtain provider models for {provider_name}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
47
|
-
raise InvalidAPIResponseException(f"Unable to obtain provider models for {provider_name}: {response.text}")
|
|
32
|
+
return parse_json_response(response, "obtain provider models", provider_name=provider_name)
|
|
48
33
|
|
|
49
34
|
def get_model_data(
|
|
50
35
|
self,
|
|
@@ -60,9 +45,5 @@ class LlmClient(BaseClient):
|
|
|
60
45
|
logger.debug(f"Obtaining model data for {provider_name}/{model_name or model_id}")
|
|
61
46
|
|
|
62
47
|
response = self.api_service.get(endpoint=endpoint)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return result
|
|
66
|
-
except JSONDecodeError as e:
|
|
67
|
-
logger.error(f"Unable to obtain model data for {provider_name}/{model_name or model_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
68
|
-
raise InvalidAPIResponseException(f"Unable to obtain model data for {provider_name}/{model_name or model_id}: {response.text}")
|
|
48
|
+
model_identifier = model_name or model_id
|
|
49
|
+
return parse_json_response(response, f"obtain model data for {provider_name}/{model_identifier}")
|
pygeai/core/models.py
CHANGED
|
@@ -690,3 +690,110 @@ class DataAnalystAssistant(Assistant):
|
|
|
690
690
|
|
|
691
691
|
class ChatWithDataAssistant(Assistant):
|
|
692
692
|
type: Literal["ChatWithData"] = "ChatWithData"
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
class Role(CustomBaseModel):
|
|
696
|
+
"""
|
|
697
|
+
{
|
|
698
|
+
"id": "string",
|
|
699
|
+
"name": "string",
|
|
700
|
+
"externalId": "string",
|
|
701
|
+
"type": "string",
|
|
702
|
+
"origin": "string"
|
|
703
|
+
}
|
|
704
|
+
"""
|
|
705
|
+
id: str = Field(..., alias="id")
|
|
706
|
+
name: str = Field(..., alias="name")
|
|
707
|
+
external_id: Optional[str] = Field(None, alias="externalId")
|
|
708
|
+
type: Optional[str] = Field(None, alias="type")
|
|
709
|
+
origin: Optional[str] = Field(None, alias="origin")
|
|
710
|
+
|
|
711
|
+
def to_dict(self):
|
|
712
|
+
return self.model_dump(by_alias=True, exclude_none=True)
|
|
713
|
+
|
|
714
|
+
def __str__(self):
|
|
715
|
+
return str(self.to_dict())
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
class Member(CustomBaseModel):
|
|
719
|
+
"""
|
|
720
|
+
{
|
|
721
|
+
"email": "string",
|
|
722
|
+
"roles": [...]
|
|
723
|
+
}
|
|
724
|
+
"""
|
|
725
|
+
email: str = Field(..., alias="email")
|
|
726
|
+
roles: Optional[List[Role]] = Field(default_factory=list, alias="roles")
|
|
727
|
+
|
|
728
|
+
@field_validator("roles", mode="before")
|
|
729
|
+
@classmethod
|
|
730
|
+
def normalize_roles(cls, value):
|
|
731
|
+
if isinstance(value, list):
|
|
732
|
+
return [Role.model_validate(item) if isinstance(item, dict) else item for item in value]
|
|
733
|
+
return value
|
|
734
|
+
|
|
735
|
+
def to_dict(self):
|
|
736
|
+
return self.model_dump(by_alias=True, exclude_none=True)
|
|
737
|
+
|
|
738
|
+
def __str__(self):
|
|
739
|
+
return str(self.to_dict())
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
class ProjectMembership(CustomBaseModel):
|
|
743
|
+
"""
|
|
744
|
+
{
|
|
745
|
+
"organizationId": "string",
|
|
746
|
+
"organizationName": "string",
|
|
747
|
+
"projectDescription": "string",
|
|
748
|
+
"projectId": "string",
|
|
749
|
+
"projectName": "string",
|
|
750
|
+
"roles": [...]
|
|
751
|
+
}
|
|
752
|
+
"""
|
|
753
|
+
organization_id: Optional[str] = Field(None, alias="organizationId")
|
|
754
|
+
organization_name: Optional[str] = Field(None, alias="organizationName")
|
|
755
|
+
project_description: Optional[str] = Field(None, alias="projectDescription")
|
|
756
|
+
project_id: str = Field(..., alias="projectId")
|
|
757
|
+
project_name: str = Field(..., alias="projectName")
|
|
758
|
+
roles: Optional[List[Role]] = Field(default_factory=list, alias="roles")
|
|
759
|
+
|
|
760
|
+
@field_validator("roles", mode="before")
|
|
761
|
+
@classmethod
|
|
762
|
+
def normalize_roles(cls, value):
|
|
763
|
+
if isinstance(value, list):
|
|
764
|
+
return [Role.model_validate(item) if isinstance(item, dict) else item for item in value]
|
|
765
|
+
return value
|
|
766
|
+
|
|
767
|
+
def to_dict(self):
|
|
768
|
+
return self.model_dump(by_alias=True, exclude_none=True)
|
|
769
|
+
|
|
770
|
+
def __str__(self):
|
|
771
|
+
return str(self.to_dict())
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
class OrganizationMembership(CustomBaseModel):
|
|
775
|
+
"""
|
|
776
|
+
{
|
|
777
|
+
"isStationAvailable": true,
|
|
778
|
+
"organizationId": "string",
|
|
779
|
+
"organizationName": "string",
|
|
780
|
+
"projects": [...]
|
|
781
|
+
}
|
|
782
|
+
"""
|
|
783
|
+
is_station_available: Optional[bool] = Field(None, alias="isStationAvailable")
|
|
784
|
+
organization_id: str = Field(..., alias="organizationId")
|
|
785
|
+
organization_name: str = Field(..., alias="organizationName")
|
|
786
|
+
projects: Optional[List[ProjectMembership]] = Field(default_factory=list, alias="projects")
|
|
787
|
+
|
|
788
|
+
@field_validator("projects", mode="before")
|
|
789
|
+
@classmethod
|
|
790
|
+
def normalize_projects(cls, value):
|
|
791
|
+
if isinstance(value, list):
|
|
792
|
+
return [ProjectMembership.model_validate(item) if isinstance(item, dict) else item for item in value]
|
|
793
|
+
return value
|
|
794
|
+
|
|
795
|
+
def to_dict(self):
|
|
796
|
+
return self.model_dump(by_alias=True, exclude_none=True)
|
|
797
|
+
|
|
798
|
+
def __str__(self):
|
|
799
|
+
return str(self.to_dict())
|
pygeai/core/plugins/clients.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from json import JSONDecodeError
|
|
2
1
|
from typing import Optional, List, Dict
|
|
3
2
|
|
|
4
3
|
from pygeai import logger
|
|
5
4
|
from pygeai.core.base.clients import BaseClient
|
|
6
5
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
6
|
from pygeai.core.plugins.endpoints import LIST_ASSISTANTS_PLUGINS_V1
|
|
7
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
8
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class PluginClient(BaseClient):
|
|
@@ -26,10 +27,5 @@ class PluginClient(BaseClient):
|
|
|
26
27
|
endpoint=LIST_ASSISTANTS_PLUGINS_V1,
|
|
27
28
|
params=params
|
|
28
29
|
)
|
|
29
|
-
|
|
30
|
-
result = response.json()
|
|
31
|
-
return result
|
|
32
|
-
except JSONDecodeError as e:
|
|
33
|
-
logger.error(f"Unable to list assistants for organization {organization_id} and project {project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
34
|
-
raise InvalidAPIResponseException(f"Unable to list assistants for organization {organization_id} and project {project_id}: {response.text}")
|
|
30
|
+
return parse_json_response(response, f"list assistants for organization {organization_id} and project {project_id}")
|
|
35
31
|
|
pygeai/core/rerank/clients.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from json import JSONDecodeError
|
|
3
1
|
from typing import Any, Union
|
|
4
2
|
|
|
5
3
|
from pygeai import logger
|
|
6
4
|
from pygeai.core.base.clients import BaseClient
|
|
7
5
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
8
6
|
from pygeai.core.rerank.endpoints import RERANK_V1
|
|
7
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
8
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class RerankClient(BaseClient):
|
|
@@ -30,10 +30,5 @@ class RerankClient(BaseClient):
|
|
|
30
30
|
endpoint=RERANK_V1,
|
|
31
31
|
data=data
|
|
32
32
|
)
|
|
33
|
-
|
|
34
|
-
result = response.json()
|
|
35
|
-
return result
|
|
36
|
-
except JSONDecodeError as e:
|
|
37
|
-
logger.error(f"Unable to rerank chunks for query '{query}' with model {model}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
38
|
-
raise InvalidAPIResponseException(f"Unable to rerank chunks for query '{query}' with model {model}: {response.text}")
|
|
33
|
+
return parse_json_response(response, "rerank chunks for query with model", query=query, model=model)
|
|
39
34
|
|
pygeai/core/secrets/clients.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from json import JSONDecodeError
|
|
2
1
|
from typing import Optional, List, Dict
|
|
3
2
|
|
|
4
3
|
from pygeai import logger
|
|
@@ -6,6 +5,8 @@ from pygeai.core.base.clients import BaseClient
|
|
|
6
5
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
7
6
|
from pygeai.core.secrets.endpoints import LIST_SECRETS_V1, GET_SECRET_V1, CREATE_SECRET_V1, UPDATE_SECRET_V1, \
|
|
8
7
|
SET_SECRET_ACCESSES_V1, GET_SECRET_ACCESSES_V1
|
|
8
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
9
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class SecretClient(BaseClient):
|
|
@@ -44,12 +45,7 @@ class SecretClient(BaseClient):
|
|
|
44
45
|
endpoint=LIST_SECRETS_V1,
|
|
45
46
|
params=params
|
|
46
47
|
)
|
|
47
|
-
|
|
48
|
-
result = response.json()
|
|
49
|
-
return result
|
|
50
|
-
except JSONDecodeError as e:
|
|
51
|
-
logger.error(f"Unable to list secrets with params {params}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
52
|
-
raise InvalidAPIResponseException(f"Unable to list secrets with params {params}: {response.text}")
|
|
48
|
+
return parse_json_response(response, "list secrets with params")
|
|
53
49
|
|
|
54
50
|
def get_secret(self, secret_id: str) -> dict:
|
|
55
51
|
"""
|
|
@@ -69,12 +65,7 @@ class SecretClient(BaseClient):
|
|
|
69
65
|
response = self.api_service.get(
|
|
70
66
|
endpoint=endpoint
|
|
71
67
|
)
|
|
72
|
-
|
|
73
|
-
result = response.json()
|
|
74
|
-
return result
|
|
75
|
-
except JSONDecodeError as e:
|
|
76
|
-
logger.error(f"Unable to get secret with ID '{secret_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
77
|
-
raise InvalidAPIResponseException(f"Unable to get secret with ID '{secret_id}': {response.text}")
|
|
68
|
+
return parse_json_response(response, "get secret with ID", secret_id=secret_id)
|
|
78
69
|
|
|
79
70
|
def create_secret(
|
|
80
71
|
self,
|
|
@@ -111,12 +102,7 @@ class SecretClient(BaseClient):
|
|
|
111
102
|
endpoint=CREATE_SECRET_V1,
|
|
112
103
|
data=data
|
|
113
104
|
)
|
|
114
|
-
|
|
115
|
-
result = response.json()
|
|
116
|
-
return result
|
|
117
|
-
except JSONDecodeError as e:
|
|
118
|
-
logger.error(f"Unable to create secret with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
119
|
-
raise InvalidAPIResponseException(f"Unable to create secret with name '{name}': {response.text}")
|
|
105
|
+
return parse_json_response(response, "create secret with name", name=name)
|
|
120
106
|
|
|
121
107
|
def update_secret(
|
|
122
108
|
self,
|
|
@@ -157,12 +143,7 @@ class SecretClient(BaseClient):
|
|
|
157
143
|
endpoint=endpoint,
|
|
158
144
|
data=data
|
|
159
145
|
)
|
|
160
|
-
|
|
161
|
-
result = response.json()
|
|
162
|
-
return result
|
|
163
|
-
except JSONDecodeError as e:
|
|
164
|
-
logger.error(f"Unable to update secret with ID '{secret_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
165
|
-
raise InvalidAPIResponseException(f"Unable to update secret with ID '{secret_id}': {response.text}")
|
|
146
|
+
return parse_json_response(response, "update secret with ID", secret_id=secret_id)
|
|
166
147
|
|
|
167
148
|
def set_secret_accesses(
|
|
168
149
|
self,
|
|
@@ -202,12 +183,7 @@ class SecretClient(BaseClient):
|
|
|
202
183
|
endpoint=endpoint,
|
|
203
184
|
data=data
|
|
204
185
|
)
|
|
205
|
-
|
|
206
|
-
result = response.json()
|
|
207
|
-
return result
|
|
208
|
-
except JSONDecodeError as e:
|
|
209
|
-
logger.error(f"Unable to set accesses for secret with ID '{secret_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
210
|
-
raise InvalidAPIResponseException(f"Unable to set accesses for secret with ID '{secret_id}': {response.text}")
|
|
186
|
+
return parse_json_response(response, "set accesses for secret with ID", secret_id=secret_id)
|
|
211
187
|
|
|
212
188
|
def get_secret_accesses(self, secret_id: str) -> dict:
|
|
213
189
|
"""
|
|
@@ -227,9 +203,4 @@ class SecretClient(BaseClient):
|
|
|
227
203
|
response = self.api_service.get(
|
|
228
204
|
endpoint=endpoint
|
|
229
205
|
)
|
|
230
|
-
|
|
231
|
-
result = response.json()
|
|
232
|
-
return result
|
|
233
|
-
except JSONDecodeError as e:
|
|
234
|
-
logger.error(f"Unable to get accesses for secret with ID '{secret_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
235
|
-
raise InvalidAPIResponseException(f"Unable to get accesses for secret with ID '{secret_id}': {response.text}")
|
|
206
|
+
return parse_json_response(response, "get accesses for secret with ID", secret_id=secret_id)
|