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
pygeai/assistant/clients.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from json import JSONDecodeError
|
|
3
1
|
|
|
4
2
|
from pygeai import logger
|
|
5
3
|
from pygeai.assistant.endpoints import GET_ASSISTANT_DATA_V1, CREATE_ASSISTANT_V1, UPDATE_ASSISTANT_V1, BEGIN_CONVERSATION_V1, \
|
|
@@ -8,6 +6,8 @@ from pygeai.assistant.data_analyst.endpoints import GET_DATA_ANALYST_STATUS_V1,
|
|
|
8
6
|
from pygeai.core.base.clients import BaseClient
|
|
9
7
|
from pygeai.core.common.decorators import handler_server_error
|
|
10
8
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
9
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
10
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class AssistantClient(BaseClient):
|
|
@@ -31,12 +31,7 @@ class AssistantClient(BaseClient):
|
|
|
31
31
|
"detail": detail
|
|
32
32
|
}
|
|
33
33
|
)
|
|
34
|
-
|
|
35
|
-
result = response.json()
|
|
36
|
-
return result
|
|
37
|
-
except JSONDecodeError as e:
|
|
38
|
-
logger.error(f"Unable to get assistant data for ID '{assistant_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
39
|
-
raise InvalidAPIResponseException(f"Unable to get assistant data for ID '{assistant_id}': {response.text}")
|
|
34
|
+
return parse_json_response(response, "get assistant data for ID", assistant_id=assistant_id)
|
|
40
35
|
|
|
41
36
|
def create_assistant(
|
|
42
37
|
self,
|
|
@@ -88,12 +83,7 @@ class AssistantClient(BaseClient):
|
|
|
88
83
|
endpoint=CREATE_ASSISTANT_V1,
|
|
89
84
|
data=data
|
|
90
85
|
)
|
|
91
|
-
|
|
92
|
-
result = response.json()
|
|
93
|
-
return result
|
|
94
|
-
except JSONDecodeError as e:
|
|
95
|
-
logger.error(f"Unable to create assistant with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
96
|
-
raise InvalidAPIResponseException(f"Unable to create assistant with name '{name}': {response.text}")
|
|
86
|
+
return parse_json_response(response, "create assistant with name", name=name)
|
|
97
87
|
|
|
98
88
|
def update_assistant(
|
|
99
89
|
self,
|
|
@@ -165,12 +155,7 @@ class AssistantClient(BaseClient):
|
|
|
165
155
|
endpoint=endpoint,
|
|
166
156
|
data=data
|
|
167
157
|
)
|
|
168
|
-
|
|
169
|
-
result = response.json()
|
|
170
|
-
return result
|
|
171
|
-
except JSONDecodeError as e:
|
|
172
|
-
logger.error(f"Unable to update assistant with ID '{assistant_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
173
|
-
raise InvalidAPIResponseException(f"Unable to update assistant with ID '{assistant_id}': {response.text}")
|
|
158
|
+
return parse_json_response(response, "update assistant", assistant_id=assistant_id)
|
|
174
159
|
|
|
175
160
|
def delete_assistant(
|
|
176
161
|
self,
|
|
@@ -186,12 +171,7 @@ class AssistantClient(BaseClient):
|
|
|
186
171
|
response = self.api_service.delete(
|
|
187
172
|
endpoint=endpoint
|
|
188
173
|
)
|
|
189
|
-
|
|
190
|
-
result = response.json()
|
|
191
|
-
return result
|
|
192
|
-
except JSONDecodeError as e:
|
|
193
|
-
logger.error(f"Unable to delete assistant with ID '{assistant_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
194
|
-
raise InvalidAPIResponseException(f"Unable to delete assistant with ID '{assistant_id}': {response.text}")
|
|
174
|
+
return parse_json_response(response, "delete assistant", assistant_id=assistant_id)
|
|
195
175
|
|
|
196
176
|
def send_chat_request(
|
|
197
177
|
self,
|
|
@@ -223,12 +203,7 @@ class AssistantClient(BaseClient):
|
|
|
223
203
|
endpoint=SEND_CHAT_REQUEST_V1,
|
|
224
204
|
data=data
|
|
225
205
|
)
|
|
226
|
-
|
|
227
|
-
result = response.json()
|
|
228
|
-
return result
|
|
229
|
-
except JSONDecodeError as e:
|
|
230
|
-
logger.error(f"Unable to send chat request to assistant '{assistant_name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
231
|
-
raise InvalidAPIResponseException(f"Unable to send chat request to assistant '{assistant_name}': {response.text}")
|
|
206
|
+
return parse_json_response(response, "send chat request to assistant", assistant_name=assistant_name)
|
|
232
207
|
|
|
233
208
|
def get_request_status(
|
|
234
209
|
self,
|
|
@@ -244,12 +219,7 @@ class AssistantClient(BaseClient):
|
|
|
244
219
|
response = self.api_service.get(
|
|
245
220
|
endpoint=endpoint
|
|
246
221
|
)
|
|
247
|
-
|
|
248
|
-
result = response.json()
|
|
249
|
-
return result
|
|
250
|
-
except JSONDecodeError as e:
|
|
251
|
-
logger.error(f"Unable to get request status for ID '{request_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
252
|
-
raise InvalidAPIResponseException(f"Unable to get request status for ID '{request_id}': {response.text}")
|
|
222
|
+
return parse_json_response(response, "get request status for ID", request_id=request_id)
|
|
253
223
|
|
|
254
224
|
def cancel_request(
|
|
255
225
|
self,
|
|
@@ -268,12 +238,7 @@ class AssistantClient(BaseClient):
|
|
|
268
238
|
"requestId": request_id
|
|
269
239
|
}
|
|
270
240
|
)
|
|
271
|
-
|
|
272
|
-
result = response.json()
|
|
273
|
-
return result
|
|
274
|
-
except JSONDecodeError as e:
|
|
275
|
-
logger.error(f"Unable to cancel request with ID '{request_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
276
|
-
raise InvalidAPIResponseException(f"Unable to cancel request with ID '{request_id}': {response.text}")
|
|
241
|
+
return parse_json_response(response, "cancel request", request_id=request_id)
|
|
277
242
|
|
|
278
243
|
|
|
279
244
|
|
pygeai/assistant/data/clients.py
CHANGED
|
@@ -6,6 +6,7 @@ from pygeai.assistant.endpoints import GET_ASSISTANT_DATA_V1, CREATE_ASSISTANT_V
|
|
|
6
6
|
from pygeai.assistant.data_analyst.endpoints import GET_DATA_ANALYST_STATUS_V1, EXTEND_DATA_ANALYST_DATASET_V1
|
|
7
7
|
from pygeai.core.base.clients import BaseClient
|
|
8
8
|
from pygeai.core.common.decorators import handler_server_error
|
|
9
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ChatWithDataAssistantClient(AssistantClient):
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from json import JSONDecodeError
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
|
|
4
3
|
from pygeai import logger
|
|
5
4
|
from pygeai.assistant.clients import AssistantClient
|
|
6
5
|
from pygeai.assistant.data_analyst.endpoints import GET_DATA_ANALYST_STATUS_V1, EXTEND_DATA_ANALYST_DATASET_V1
|
|
7
6
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
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 DataAnalystAssistantClient(AssistantClient):
|
|
@@ -34,12 +35,7 @@ class DataAnalystAssistantClient(AssistantClient):
|
|
|
34
35
|
headers=headers
|
|
35
36
|
)
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
result = response.json()
|
|
39
|
-
return result
|
|
40
|
-
except JSONDecodeError as e:
|
|
41
|
-
logger.error(f"Unable to get status for assistant ID '{assistant_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
42
|
-
raise InvalidAPIResponseException(f"Unable to get status for assistant ID '{assistant_id}': {response.text}")
|
|
38
|
+
return parse_json_response(response, "get status for assistant ID", assistant_id=assistant_id)
|
|
43
39
|
|
|
44
40
|
def extend_dataset(
|
|
45
41
|
self,
|
|
@@ -69,12 +65,7 @@ class DataAnalystAssistantClient(AssistantClient):
|
|
|
69
65
|
endpoint=endpoint,
|
|
70
66
|
files=files
|
|
71
67
|
)
|
|
72
|
-
|
|
73
|
-
result = response.json()
|
|
74
|
-
return result
|
|
75
|
-
except JSONDecodeError as e:
|
|
76
|
-
logger.error(f"Unable to extend dataset for assistant ID '{assistant_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
77
|
-
raise InvalidAPIResponseException(f"Unable to extend dataset for assistant ID '{assistant_id}': {response.text}")
|
|
68
|
+
return parse_json_response(response, "extend dataset for assistant ID", assistant_id=assistant_id)
|
|
78
69
|
finally:
|
|
79
70
|
for _, file_handle in files:
|
|
80
71
|
file_handle.close()
|
pygeai/assistant/rag/clients.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
-
from json import JSONDecodeError
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from typing import Any
|
|
6
5
|
|
|
@@ -12,6 +11,8 @@ from pygeai.core.base.clients import BaseClient
|
|
|
12
11
|
import urllib.parse
|
|
13
12
|
|
|
14
13
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
14
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
15
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class RAGAssistantClient(BaseClient):
|
|
@@ -21,22 +22,12 @@ class RAGAssistantClient(BaseClient):
|
|
|
21
22
|
|
|
22
23
|
def get_assistants_from_project(self) -> dict:
|
|
23
24
|
response = self.api_service.get(endpoint=GET_ASSISTANTS_FROM_PROJECT_V1)
|
|
24
|
-
|
|
25
|
-
result = response.json()
|
|
26
|
-
return result
|
|
27
|
-
except JSONDecodeError as e:
|
|
28
|
-
logger.error(f"Unable to get assistants from project: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
29
|
-
raise InvalidAPIResponseException(f"Unable to get assistants from project: {response.text}")
|
|
25
|
+
return parse_json_response(response, "get assistants from project")
|
|
30
26
|
|
|
31
27
|
def get_assistant_data(self, name: str) -> dict:
|
|
32
28
|
endpoint = GET_ASSISTANT_V1.format(name=name)
|
|
33
29
|
response = self.api_service.get(endpoint=endpoint)
|
|
34
|
-
|
|
35
|
-
result = response.json()
|
|
36
|
-
return result
|
|
37
|
-
except JSONDecodeError as e:
|
|
38
|
-
logger.error(f"Unable to get assistant data for name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
39
|
-
raise InvalidAPIResponseException(f"Unable to get assistant data for name '{name}': {response.text}")
|
|
30
|
+
return parse_json_response(response, "get assistant data for name", name=name)
|
|
40
31
|
|
|
41
32
|
def create_assistant(
|
|
42
33
|
self,
|
|
@@ -116,12 +107,7 @@ class RAGAssistantClient(BaseClient):
|
|
|
116
107
|
endpoint=CREATE_ASSISTANT_V1,
|
|
117
108
|
data=data
|
|
118
109
|
)
|
|
119
|
-
|
|
120
|
-
result = response.json()
|
|
121
|
-
return result
|
|
122
|
-
except JSONDecodeError as e:
|
|
123
|
-
logger.error(f"Unable to create assistant with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
124
|
-
raise InvalidAPIResponseException(f"Unable to create assistant with name '{name}': {response.text}")
|
|
110
|
+
return parse_json_response(response, "create assistant with name", name=name)
|
|
125
111
|
|
|
126
112
|
def update_assistant(
|
|
127
113
|
self,
|
|
@@ -154,23 +140,13 @@ class RAGAssistantClient(BaseClient):
|
|
|
154
140
|
endpoint=endpoint,
|
|
155
141
|
data=data
|
|
156
142
|
)
|
|
157
|
-
|
|
158
|
-
result = response.json()
|
|
159
|
-
return result
|
|
160
|
-
except JSONDecodeError as e:
|
|
161
|
-
logger.error(f"Unable to update assistant with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
162
|
-
raise InvalidAPIResponseException(f"Unable to update assistant with name '{name}': {response.text}")
|
|
143
|
+
return parse_json_response(response, "update assistant with name", name=name)
|
|
163
144
|
|
|
164
145
|
def delete_assistant(self, name: str) -> dict:
|
|
165
146
|
safe_name = self.get_url_safe_name(name)
|
|
166
147
|
endpoint = DELETE_ASSISTANT_V1.format(name=safe_name)
|
|
167
148
|
response = self.api_service.delete(endpoint=endpoint)
|
|
168
|
-
|
|
169
|
-
result = response.json()
|
|
170
|
-
return result
|
|
171
|
-
except JSONDecodeError as e:
|
|
172
|
-
logger.error(f"Unable to delete assistant with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
173
|
-
raise InvalidAPIResponseException(f"Unable to delete assistant with name '{name}': {response.text}")
|
|
149
|
+
return parse_json_response(response, "delete assistant with name", name=name)
|
|
174
150
|
|
|
175
151
|
def get_documents(
|
|
176
152
|
self,
|
|
@@ -187,34 +163,19 @@ class RAGAssistantClient(BaseClient):
|
|
|
187
163
|
"count": count
|
|
188
164
|
}
|
|
189
165
|
)
|
|
190
|
-
|
|
191
|
-
result = response.json()
|
|
192
|
-
return result
|
|
193
|
-
except JSONDecodeError as e:
|
|
194
|
-
logger.error(f"Unable to get documents for assistant '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
195
|
-
raise InvalidAPIResponseException(f"Unable to get documents for assistant '{name}': {response.text}")
|
|
166
|
+
return parse_json_response(response, "get documents for assistant", name=name)
|
|
196
167
|
|
|
197
168
|
def delete_all_documents(self, name: str) -> dict:
|
|
198
169
|
safe_name = self.get_url_safe_name(name)
|
|
199
170
|
endpoint = DELETE_ALL_DOCUMENTS_V1.format(name=safe_name)
|
|
200
171
|
response = self.api_service.delete(endpoint=endpoint)
|
|
201
|
-
|
|
202
|
-
result = response.json()
|
|
203
|
-
return result
|
|
204
|
-
except JSONDecodeError as e:
|
|
205
|
-
logger.error(f"Unable to delete all documents for assistant '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
206
|
-
raise InvalidAPIResponseException(f"Unable to delete all documents for assistant '{name}': {response.text}")
|
|
172
|
+
return parse_json_response(response, "delete all documents for assistant", name=name)
|
|
207
173
|
|
|
208
174
|
def retrieve_document(self, name: str, document_id: str) -> dict:
|
|
209
175
|
safe_name = self.get_url_safe_name(name)
|
|
210
176
|
endpoint = RETRIEVE_DOCUMENT_V1.format(name=safe_name, id=document_id)
|
|
211
177
|
response = self.api_service.get(endpoint=endpoint)
|
|
212
|
-
|
|
213
|
-
result = response.json()
|
|
214
|
-
return result
|
|
215
|
-
except JSONDecodeError as e:
|
|
216
|
-
logger.error(f"Unable to retrieve document with ID '{document_id}' for assistant '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
217
|
-
raise InvalidAPIResponseException(f"Unable to retrieve document with ID '{document_id}' for assistant '{name}': {response.text}")
|
|
178
|
+
return parse_json_response(response, "retrieve document", document_id=document_id)
|
|
218
179
|
|
|
219
180
|
def upload_document(
|
|
220
181
|
self,
|
|
@@ -234,12 +195,7 @@ class RAGAssistantClient(BaseClient):
|
|
|
234
195
|
else:
|
|
235
196
|
raise ValueError("Invalid upload_type. Use 'binary' or 'multipart'.")
|
|
236
197
|
|
|
237
|
-
|
|
238
|
-
result = response.json()
|
|
239
|
-
return result
|
|
240
|
-
except JSONDecodeError as e:
|
|
241
|
-
logger.error(f"Unable to upload document for assistant '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
242
|
-
raise InvalidAPIResponseException(f"Unable to upload document for assistant '{name}': {response.text}")
|
|
198
|
+
return parse_json_response(response, "upload document for assistant", name=name)
|
|
243
199
|
|
|
244
200
|
def _upload_binary_document(self, endpoint: str, file_path: str, content_type: str):
|
|
245
201
|
"""
|
|
@@ -310,22 +266,12 @@ class RAGAssistantClient(BaseClient):
|
|
|
310
266
|
safe_name = self.get_url_safe_name(name)
|
|
311
267
|
endpoint = DELETE_DOCUMENT_V1.format(name=safe_name, id=document_id)
|
|
312
268
|
response = self.api_service.delete(endpoint=endpoint)
|
|
313
|
-
|
|
314
|
-
result = response.json()
|
|
315
|
-
return result
|
|
316
|
-
except JSONDecodeError as e:
|
|
317
|
-
logger.error(f"Unable to delete document with ID '{document_id}' for assistant '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
318
|
-
raise InvalidAPIResponseException(f"Unable to delete document with ID '{document_id}' for assistant '{name}': {response.text}")
|
|
269
|
+
return parse_json_response(response, "delete document", document_id=document_id)
|
|
319
270
|
|
|
320
271
|
def execute_query(self, query: dict) -> dict:
|
|
321
272
|
response = self.api_service.post(
|
|
322
273
|
endpoint=EXECUTE_QUERY_V1,
|
|
323
274
|
data=query
|
|
324
275
|
)
|
|
325
|
-
|
|
326
|
-
result = response.json()
|
|
327
|
-
return result
|
|
328
|
-
except JSONDecodeError as e:
|
|
329
|
-
logger.error(f"Unable to execute query: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
330
|
-
raise InvalidAPIResponseException(f"Unable to execute query: {response.text}")
|
|
276
|
+
return parse_json_response(response, "execute query")
|
|
331
277
|
|
pygeai/auth/clients.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from json import JSONDecodeError
|
|
2
|
-
|
|
3
1
|
from pygeai import logger
|
|
4
|
-
from pygeai.auth.endpoints import GET_USER_PROFILE_INFO, GET_OAUTH2_ACCESS_TOKEN
|
|
2
|
+
from pygeai.auth.endpoints import GET_USER_PROFILE_INFO, GET_OAUTH2_ACCESS_TOKEN, \
|
|
3
|
+
CREATE_PROJECT_API_TOKEN_V2, DELETE_PROJECT_API_TOKEN_V2, UPDATE_PROJECT_API_TOKEN_V2, GET_PROJECT_API_TOKEN_V2
|
|
5
4
|
from pygeai.core.base.clients import BaseClient
|
|
6
|
-
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
5
|
+
from pygeai.core.common.exceptions import InvalidAPIResponseException, APIResponseError
|
|
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 AuthClient(BaseClient):
|
|
@@ -33,11 +34,8 @@ class AuthClient(BaseClient):
|
|
|
33
34
|
"password": password
|
|
34
35
|
}
|
|
35
36
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
except JSONDecodeError as e:
|
|
39
|
-
logger.error(f"Unable to obtain Oauth2 access token: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
|
|
40
|
-
raise InvalidAPIResponseException(f"Unable to obtain Oauth2 access token: {response.text}")
|
|
37
|
+
validate_status_code(response)
|
|
38
|
+
return parse_json_response(response, "obtain Oauth2 access token")
|
|
41
39
|
|
|
42
40
|
def get_user_profile_information(self, access_token: str) -> dict:
|
|
43
41
|
"""
|
|
@@ -48,8 +46,84 @@ class AuthClient(BaseClient):
|
|
|
48
46
|
"""
|
|
49
47
|
self.api_service.token = access_token
|
|
50
48
|
response = self.api_service.get(endpoint=GET_USER_PROFILE_INFO)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
validate_status_code(response)
|
|
50
|
+
return parse_json_response(response, "retrieve user profile information")
|
|
51
|
+
|
|
52
|
+
def create_project_api_token(
|
|
53
|
+
self,
|
|
54
|
+
project_id: str,
|
|
55
|
+
name: str,
|
|
56
|
+
description: str = None
|
|
57
|
+
) -> dict:
|
|
58
|
+
"""
|
|
59
|
+
Creates a new API token for a project.
|
|
60
|
+
|
|
61
|
+
:param project_id: str - The project identifier (required). Will be sent as header.
|
|
62
|
+
:param name: str - The name of the API token (required).
|
|
63
|
+
:param description: str - A description of the API token (optional).
|
|
64
|
+
:return: dict - The API response containing the created API token details in JSON format.
|
|
65
|
+
"""
|
|
66
|
+
headers = {"project-id": project_id}
|
|
67
|
+
data = {"name": name}
|
|
68
|
+
if description:
|
|
69
|
+
data["description"] = description
|
|
70
|
+
|
|
71
|
+
response = self.api_service.post(
|
|
72
|
+
endpoint=CREATE_PROJECT_API_TOKEN_V2,
|
|
73
|
+
data=data,
|
|
74
|
+
headers=headers
|
|
75
|
+
)
|
|
76
|
+
validate_status_code(response)
|
|
77
|
+
return parse_json_response(response, "create project API token")
|
|
78
|
+
|
|
79
|
+
def delete_project_api_token(self, api_token_id: str) -> dict:
|
|
80
|
+
"""
|
|
81
|
+
Revokes an API token by setting its status to "revoked".
|
|
82
|
+
|
|
83
|
+
:param api_token_id: str - The unique identifier of the API token to delete (required).
|
|
84
|
+
:return: dict - The API response confirming the deletion, in JSON format.
|
|
85
|
+
"""
|
|
86
|
+
endpoint = DELETE_PROJECT_API_TOKEN_V2.format(id=api_token_id)
|
|
87
|
+
response = self.api_service.delete(endpoint=endpoint)
|
|
88
|
+
validate_status_code(response)
|
|
89
|
+
return parse_json_response(response, "delete project API token", api_token_id=api_token_id)
|
|
90
|
+
|
|
91
|
+
def update_project_api_token(
|
|
92
|
+
self,
|
|
93
|
+
api_token_id: str,
|
|
94
|
+
description: str = None,
|
|
95
|
+
status: str = None
|
|
96
|
+
) -> dict:
|
|
97
|
+
"""
|
|
98
|
+
Updates an existing API token's description and/or status.
|
|
99
|
+
|
|
100
|
+
:param api_token_id: str - The unique identifier of the API token to update (required).
|
|
101
|
+
:param description: str - A new description for the API token (optional).
|
|
102
|
+
:param status: str - The new status for the API token: 'active' or 'blocked' (optional).
|
|
103
|
+
:return: dict - The API response containing the update result messages in JSON format.
|
|
104
|
+
"""
|
|
105
|
+
endpoint = UPDATE_PROJECT_API_TOKEN_V2.format(id=api_token_id)
|
|
106
|
+
data = {}
|
|
107
|
+
if description is not None:
|
|
108
|
+
data["description"] = description
|
|
109
|
+
if status is not None:
|
|
110
|
+
data["status"] = status
|
|
111
|
+
|
|
112
|
+
response = self.api_service.put(
|
|
113
|
+
endpoint=endpoint,
|
|
114
|
+
data=data
|
|
115
|
+
)
|
|
116
|
+
validate_status_code(response)
|
|
117
|
+
return parse_json_response(response, "update project API token", api_token_id=api_token_id)
|
|
118
|
+
|
|
119
|
+
def get_project_api_token(self, api_token_id: str) -> dict:
|
|
120
|
+
"""
|
|
121
|
+
Retrieves data for a specific project API token.
|
|
122
|
+
|
|
123
|
+
:param api_token_id: str - The unique identifier of the API token (required).
|
|
124
|
+
:return: dict - The API response containing the API token details in JSON format.
|
|
125
|
+
"""
|
|
126
|
+
endpoint = GET_PROJECT_API_TOKEN_V2.format(id=api_token_id)
|
|
127
|
+
response = self.api_service.get(endpoint=endpoint)
|
|
128
|
+
validate_status_code(response)
|
|
129
|
+
return parse_json_response(response, "get project API token", api_token_id=api_token_id)
|
pygeai/auth/endpoints.py
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
GET_OAUTH2_ACCESS_TOKEN = "/oauth/access_token" # POST -> Obtain an OAuth 2.0 access token
|
|
2
2
|
GET_USER_PROFILE_INFO = "/openid/userinfo" # GET -> Retrieve user profile information
|
|
3
|
+
CREATE_PROJECT_API_TOKEN_V2 = "v2/projects/tokens" # POST -> Create a new API token for a project
|
|
4
|
+
DELETE_PROJECT_API_TOKEN_V2 = "v2/projects/tokens/{id}" # DELETE -> Revoke an API token
|
|
5
|
+
UPDATE_PROJECT_API_TOKEN_V2 = "v2/projects/tokens/{id}" # PUT -> Update an API token
|
|
6
|
+
GET_PROJECT_API_TOKEN_V2 = "v2/projects/tokens/{id}" # GET -> Get data of a specific project API token
|
pygeai/chat/clients.py
CHANGED
|
@@ -6,6 +6,7 @@ from pygeai import logger
|
|
|
6
6
|
from pygeai.chat.endpoints import CHAT_V1, GENERATE_IMAGE_V1
|
|
7
7
|
from pygeai.core.base.clients import BaseClient
|
|
8
8
|
from pygeai.core.common.exceptions import InvalidAPIResponseException
|
|
9
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ChatClient(BaseClient):
|
pygeai/cli/commands/auth.py
CHANGED
|
@@ -92,6 +92,146 @@ get_user_profile_information_options = [
|
|
|
92
92
|
]
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
def create_project_api_token(option_list: list):
|
|
96
|
+
project_id = None
|
|
97
|
+
name = None
|
|
98
|
+
description = None
|
|
99
|
+
for option_flag, option_arg in option_list:
|
|
100
|
+
if option_flag.name == "project_id":
|
|
101
|
+
project_id = option_arg
|
|
102
|
+
if option_flag.name == "name":
|
|
103
|
+
name = option_arg
|
|
104
|
+
if option_flag.name == "description":
|
|
105
|
+
description = option_arg
|
|
106
|
+
|
|
107
|
+
if not (project_id and name):
|
|
108
|
+
raise MissingRequirementException("Cannot create project API token without project-id and name")
|
|
109
|
+
|
|
110
|
+
client = AuthClient()
|
|
111
|
+
result = client.create_project_api_token(
|
|
112
|
+
project_id=project_id,
|
|
113
|
+
name=name,
|
|
114
|
+
description=description
|
|
115
|
+
)
|
|
116
|
+
Console.write_stdout(f"Project API token created: \n{result}")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
create_project_api_token_options = [
|
|
120
|
+
Option(
|
|
121
|
+
"project_id",
|
|
122
|
+
["--project-id", "--pid"],
|
|
123
|
+
"The project identifier (required).",
|
|
124
|
+
True
|
|
125
|
+
),
|
|
126
|
+
Option(
|
|
127
|
+
"name",
|
|
128
|
+
["--name", "-n"],
|
|
129
|
+
"The name of the API token (required).",
|
|
130
|
+
True
|
|
131
|
+
),
|
|
132
|
+
Option(
|
|
133
|
+
"description",
|
|
134
|
+
["--description", "-d"],
|
|
135
|
+
"A description of the API token (optional).",
|
|
136
|
+
True
|
|
137
|
+
),
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def delete_project_api_token(option_list: list):
|
|
142
|
+
api_token_id = None
|
|
143
|
+
for option_flag, option_arg in option_list:
|
|
144
|
+
if option_flag.name == "api_token_id":
|
|
145
|
+
api_token_id = option_arg
|
|
146
|
+
|
|
147
|
+
if not api_token_id:
|
|
148
|
+
raise MissingRequirementException("Cannot delete project API token without api-token-id")
|
|
149
|
+
|
|
150
|
+
client = AuthClient()
|
|
151
|
+
result = client.delete_project_api_token(api_token_id=api_token_id)
|
|
152
|
+
Console.write_stdout(f"Project API token deleted: \n{result}")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
delete_project_api_token_options = [
|
|
156
|
+
Option(
|
|
157
|
+
"api_token_id",
|
|
158
|
+
["--api-token-id", "--tid"],
|
|
159
|
+
"The unique identifier of the API token to delete (required).",
|
|
160
|
+
True
|
|
161
|
+
),
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def update_project_api_token(option_list: list):
|
|
166
|
+
api_token_id = None
|
|
167
|
+
description = None
|
|
168
|
+
status = None
|
|
169
|
+
for option_flag, option_arg in option_list:
|
|
170
|
+
if option_flag.name == "api_token_id":
|
|
171
|
+
api_token_id = option_arg
|
|
172
|
+
if option_flag.name == "description":
|
|
173
|
+
description = option_arg
|
|
174
|
+
if option_flag.name == "status":
|
|
175
|
+
status = option_arg
|
|
176
|
+
|
|
177
|
+
if not api_token_id:
|
|
178
|
+
raise MissingRequirementException("Cannot update project API token without api-token-id")
|
|
179
|
+
|
|
180
|
+
client = AuthClient()
|
|
181
|
+
result = client.update_project_api_token(
|
|
182
|
+
api_token_id=api_token_id,
|
|
183
|
+
description=description,
|
|
184
|
+
status=status
|
|
185
|
+
)
|
|
186
|
+
Console.write_stdout(f"Project API token updated: \n{result}")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
update_project_api_token_options = [
|
|
190
|
+
Option(
|
|
191
|
+
"api_token_id",
|
|
192
|
+
["--api-token-id", "--tid"],
|
|
193
|
+
"The unique identifier of the API token to update (required).",
|
|
194
|
+
True
|
|
195
|
+
),
|
|
196
|
+
Option(
|
|
197
|
+
"description",
|
|
198
|
+
["--description", "-d"],
|
|
199
|
+
"A new description for the API token (optional).",
|
|
200
|
+
True
|
|
201
|
+
),
|
|
202
|
+
Option(
|
|
203
|
+
"status",
|
|
204
|
+
["--status"],
|
|
205
|
+
"The new status for the API token: 'active' or 'blocked' (optional).",
|
|
206
|
+
True
|
|
207
|
+
),
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def get_project_api_token(option_list: list):
|
|
212
|
+
api_token_id = None
|
|
213
|
+
for option_flag, option_arg in option_list:
|
|
214
|
+
if option_flag.name == "api_token_id":
|
|
215
|
+
api_token_id = option_arg
|
|
216
|
+
|
|
217
|
+
if not api_token_id:
|
|
218
|
+
raise MissingRequirementException("Cannot get project API token without api-token-id")
|
|
219
|
+
|
|
220
|
+
client = AuthClient()
|
|
221
|
+
result = client.get_project_api_token(api_token_id=api_token_id)
|
|
222
|
+
Console.write_stdout(f"Project API token details: \n{result}")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
get_project_api_token_options = [
|
|
226
|
+
Option(
|
|
227
|
+
"api_token_id",
|
|
228
|
+
["--api-token-id", "--tid"],
|
|
229
|
+
"The unique identifier of the API token (required).",
|
|
230
|
+
True
|
|
231
|
+
),
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
|
|
95
235
|
auth_commands = [
|
|
96
236
|
Command(
|
|
97
237
|
"help",
|
|
@@ -112,12 +252,48 @@ auth_commands = [
|
|
|
112
252
|
get_oauth2_access_token_options
|
|
113
253
|
),
|
|
114
254
|
Command(
|
|
115
|
-
"
|
|
255
|
+
"get_user_profile_information",
|
|
116
256
|
["get-user-information", "get-user-info", "gui"],
|
|
117
257
|
"Retrieve user profile information",
|
|
118
|
-
|
|
258
|
+
get_user_profile_information,
|
|
119
259
|
ArgumentsEnum.REQUIRED,
|
|
120
260
|
[],
|
|
121
261
|
get_user_profile_information_options
|
|
122
262
|
),
|
|
263
|
+
Command(
|
|
264
|
+
"create_project_api_token",
|
|
265
|
+
["create-project-api-token", "create-api-token", "cat"],
|
|
266
|
+
"Create a new API token for a project",
|
|
267
|
+
create_project_api_token,
|
|
268
|
+
ArgumentsEnum.REQUIRED,
|
|
269
|
+
[],
|
|
270
|
+
create_project_api_token_options
|
|
271
|
+
),
|
|
272
|
+
Command(
|
|
273
|
+
"delete_project_api_token",
|
|
274
|
+
["delete-project-api-token", "delete-api-token", "dat"],
|
|
275
|
+
"Revoke an API token",
|
|
276
|
+
delete_project_api_token,
|
|
277
|
+
ArgumentsEnum.REQUIRED,
|
|
278
|
+
[],
|
|
279
|
+
delete_project_api_token_options
|
|
280
|
+
),
|
|
281
|
+
Command(
|
|
282
|
+
"update_project_api_token",
|
|
283
|
+
["update-project-api-token", "update-api-token", "uat"],
|
|
284
|
+
"Update an existing API token",
|
|
285
|
+
update_project_api_token,
|
|
286
|
+
ArgumentsEnum.REQUIRED,
|
|
287
|
+
[],
|
|
288
|
+
update_project_api_token_options
|
|
289
|
+
),
|
|
290
|
+
Command(
|
|
291
|
+
"get_project_api_token",
|
|
292
|
+
["get-project-api-token", "get-api-token", "gat"],
|
|
293
|
+
"Get data of a specific project API token",
|
|
294
|
+
get_project_api_token,
|
|
295
|
+
ArgumentsEnum.REQUIRED,
|
|
296
|
+
[],
|
|
297
|
+
get_project_api_token_options
|
|
298
|
+
),
|
|
123
299
|
]
|
|
@@ -472,7 +472,6 @@ def export_agent(option_list: list):
|
|
|
472
472
|
Console.write_stdout(f"Agent spec: \n{result}")
|
|
473
473
|
|
|
474
474
|
|
|
475
|
-
|
|
476
475
|
export_agent_options = [
|
|
477
476
|
PROJECT_ID_OPTION,
|
|
478
477
|
Option(
|
|
@@ -1242,7 +1241,6 @@ def export_tool(option_list: list):
|
|
|
1242
1241
|
if option_flag.name == "file":
|
|
1243
1242
|
file = option_arg
|
|
1244
1243
|
|
|
1245
|
-
|
|
1246
1244
|
if not tool_id:
|
|
1247
1245
|
raise MissingRequirementException("Tool ID must be specified.")
|
|
1248
1246
|
|