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.
Files changed (85) hide show
  1. pygeai/_docs/source/content/api_reference/admin.rst +161 -0
  2. pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
  3. pygeai/_docs/source/content/api_reference/auth.rst +379 -0
  4. pygeai/_docs/source/content/api_reference/health.rst +58 -0
  5. pygeai/_docs/source/content/api_reference/project.rst +20 -18
  6. pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
  7. pygeai/_docs/source/content/api_reference.rst +6 -1
  8. pygeai/_docs/source/index.rst +59 -7
  9. pygeai/_docs/source/pygeai.auth.rst +29 -0
  10. pygeai/_docs/source/pygeai.cli.commands.rst +16 -0
  11. pygeai/_docs/source/pygeai.core.utils.rst +16 -0
  12. pygeai/_docs/source/pygeai.rst +1 -0
  13. pygeai/_docs/source/pygeai.tests.auth.rst +21 -0
  14. pygeai/_docs/source/pygeai.tests.cli.commands.rst +16 -0
  15. pygeai/_docs/source/pygeai.tests.core.base.rst +8 -0
  16. pygeai/_docs/source/pygeai.tests.core.files.rst +8 -0
  17. pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
  18. pygeai/_docs/source/pygeai.tests.core.rst +1 -0
  19. pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
  20. pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
  21. pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
  22. pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
  23. pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +8 -0
  24. pygeai/_docs/source/pygeai.tests.organization.rst +8 -0
  25. pygeai/_docs/source/pygeai.tests.rst +2 -0
  26. pygeai/_docs/source/pygeai.tests.snippets.auth.rst +10 -0
  27. pygeai/_docs/source/pygeai.tests.snippets.organization.rst +40 -0
  28. pygeai/_docs/source/pygeai.tests.snippets.rst +1 -0
  29. pygeai/admin/clients.py +7 -32
  30. pygeai/assistant/clients.py +9 -44
  31. pygeai/assistant/data/clients.py +1 -0
  32. pygeai/assistant/data_analyst/clients.py +4 -13
  33. pygeai/assistant/rag/clients.py +13 -67
  34. pygeai/auth/clients.py +88 -14
  35. pygeai/auth/endpoints.py +4 -0
  36. pygeai/chat/clients.py +1 -0
  37. pygeai/cli/commands/auth.py +178 -2
  38. pygeai/cli/commands/lab/ai_lab.py +0 -2
  39. pygeai/cli/commands/organization.py +241 -0
  40. pygeai/core/base/clients.py +1 -0
  41. pygeai/core/embeddings/clients.py +3 -7
  42. pygeai/core/feedback/clients.py +3 -8
  43. pygeai/core/files/clients.py +5 -18
  44. pygeai/core/llm/clients.py +7 -26
  45. pygeai/core/models.py +107 -0
  46. pygeai/core/plugins/clients.py +3 -7
  47. pygeai/core/rerank/clients.py +3 -8
  48. pygeai/core/secrets/clients.py +8 -37
  49. pygeai/core/utils/parsers.py +32 -0
  50. pygeai/core/utils/validators.py +10 -0
  51. pygeai/evaluation/clients.py +1 -0
  52. pygeai/evaluation/dataset/clients.py +1 -0
  53. pygeai/evaluation/plan/clients.py +1 -0
  54. pygeai/evaluation/result/clients.py +1 -0
  55. pygeai/gam/clients.py +6 -25
  56. pygeai/health/clients.py +3 -7
  57. pygeai/lab/agents/clients.py +13 -53
  58. pygeai/lab/agents/endpoints.py +2 -0
  59. pygeai/lab/clients.py +1 -0
  60. pygeai/lab/processes/clients.py +24 -127
  61. pygeai/lab/strategies/clients.py +7 -25
  62. pygeai/lab/tools/clients.py +22 -67
  63. pygeai/lab/tools/endpoints.py +3 -0
  64. pygeai/organization/clients.py +122 -51
  65. pygeai/organization/endpoints.py +6 -1
  66. pygeai/organization/limits/clients.py +17 -91
  67. pygeai/organization/managers.py +157 -1
  68. pygeai/organization/mappers.py +76 -2
  69. pygeai/organization/responses.py +25 -1
  70. pygeai/proxy/clients.py +1 -0
  71. pygeai/tests/auth/test_clients.py +183 -7
  72. pygeai/tests/organization/test_clients.py +184 -1
  73. pygeai/tests/organization/test_managers.py +122 -1
  74. pygeai/tests/snippets/auth/__init__.py +0 -0
  75. pygeai/tests/snippets/organization/get_memberships.py +12 -0
  76. pygeai/tests/snippets/organization/get_organization_members.py +6 -0
  77. pygeai/tests/snippets/organization/get_project_members.py +6 -0
  78. pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
  79. pygeai/tests/snippets/organization/get_project_roles.py +6 -0
  80. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/METADATA +1 -1
  81. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/RECORD +85 -64
  82. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/WHEEL +0 -0
  83. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/entry_points.txt +0 -0
  84. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/licenses/LICENSE +0 -0
  85. {pygeai-0.6.0b6.dist-info → pygeai-0.6.0b7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,32 @@
1
+ from json import JSONDecodeError
2
+
3
+ from pygeai import logger
4
+ from pygeai.core.common.exceptions import InvalidAPIResponseException
5
+
6
+
7
+ def parse_json_response(response, operation: str, **context):
8
+ """
9
+ Parse JSON response with standardized error handling.
10
+
11
+ :param response: HTTP response object
12
+ :param operation: Description of operation (e.g., "get project API token")
13
+ :param context: Additional context (e.g., api_token_id="123")
14
+ :return: Parsed JSON response
15
+ :raises InvalidAPIResponseException: If JSON parsing fails
16
+ """
17
+ try:
18
+ return response.json()
19
+ except JSONDecodeError as e:
20
+ full_msg = f"Unable to {operation}"
21
+ if context:
22
+ if len(context) == 1:
23
+ # Single context value: append as 'value'
24
+ value = list(context.values())[0]
25
+ full_msg += f" '{value}'"
26
+ else:
27
+ # Multiple context values: format as (key1='value1', key2='value2')
28
+ context_str = ", ".join([f"{k}='{v}'" for k, v in context.items()])
29
+ full_msg += f" ({context_str})"
30
+
31
+ logger.error(f"{full_msg}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
32
+ raise InvalidAPIResponseException(f"{full_msg}: {response.text}")
@@ -0,0 +1,10 @@
1
+ from pygeai import logger
2
+ from pygeai.core.common.exceptions import APIResponseError
3
+
4
+
5
+ def validate_status_code(response):
6
+ if response.status_code >= 300:
7
+ logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
8
+ raise APIResponseError(f"API returned an error: {response.text}")
9
+
10
+
@@ -2,6 +2,7 @@ from pygeai.core.base.clients import BaseClient
2
2
  from pygeai.core.base.session import Session
3
3
  from pygeai.core.common.exceptions import MissingRequirementException
4
4
  from pygeai.core.services.rest import ApiService
5
+ from pygeai.core.utils.validators import validate_status_code
5
6
 
6
7
 
7
8
  class EvaluationClient(BaseClient):
@@ -9,6 +9,7 @@ from pygeai.evaluation.dataset.endpoints import (
9
9
  CREATE_FILTER_VARIABLE, LIST_FILTER_VARIABLES, GET_FILTER_VARIABLE, UPDATE_FILTER_VARIABLE, DELETE_FILTER_VARIABLE,
10
10
  UPLOAD_DATASET_ROWS_FILE
11
11
  )
12
+ from pygeai.core.utils.validators import validate_status_code
12
13
 
13
14
 
14
15
  class EvaluationDatasetClient(EvaluationClient):
@@ -5,6 +5,7 @@ from pygeai.evaluation.plan.endpoints import LIST_EVALUATION_PLANS, CREATE_EVALU
5
5
  UPDATE_EVALUATION_PLAN, DELETE_EVALUATION_PLAN, LIST_EVALUATION_PLAN_SYSTEM_METRICS, \
6
6
  ADD_EVALUATION_PLAN_SYSTEM_METRIC, GET_EVALUATION_PLAN_SYSTEM_METRIC, UPDATE_EVALUATION_PLAN_SYSTEM_METRIC, \
7
7
  DELETE_EVALUATION_PLAN_SYSTEM_METRIC, LIST_SYSTEM_METRICS, GET_SYSTEM_METRIC, EXECUTE_EVALUATION_PLAN
8
+ from pygeai.core.utils.validators import validate_status_code
8
9
 
9
10
 
10
11
  class EvaluationPlanClient(EvaluationClient):
@@ -2,6 +2,7 @@ import json
2
2
 
3
3
  from pygeai.evaluation.clients import EvaluationClient
4
4
  from pygeai.evaluation.result.endpoints import LIST_EVALUATION_RESULTS, GET_EVALUATION_RESULT
5
+ from pygeai.core.utils.validators import validate_status_code
5
6
 
6
7
 
7
8
  class EvaluationResultClient(EvaluationClient):
pygeai/gam/clients.py CHANGED
@@ -1,8 +1,9 @@
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 MissingRequirementException, InvalidAPIResponseException
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.gam.endpoints import GET_ACCESS_TOKEN_V2, GET_USER_INFO_V2, IDP_SIGNIN_V1
7
8
 
8
9
 
@@ -104,12 +105,7 @@ class GAMClient(BaseClient):
104
105
  headers=headers,
105
106
  form=True
106
107
  )
107
- try:
108
- result = response.json()
109
- return result
110
- except JSONDecodeError as e:
111
- logger.error(f"Unable to get access token: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
112
- raise InvalidAPIResponseException(f"Unable to get access token: {response.text}")
108
+ return parse_json_response(response, "get access token")
113
109
 
114
110
  def get_user_info(
115
111
  self,
@@ -130,12 +126,7 @@ class GAMClient(BaseClient):
130
126
  endpoint=GET_USER_INFO_V2,
131
127
  headers=headers
132
128
  )
133
- try:
134
- result = response.json()
135
- return result
136
- except JSONDecodeError as e:
137
- logger.error(f"Unable to get user info: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
138
- raise InvalidAPIResponseException(f"Unable to get user info: {response.text}")
129
+ return parse_json_response(response, "get user info")
139
130
 
140
131
  def refresh_access_token(
141
132
  self,
@@ -173,21 +164,11 @@ class GAMClient(BaseClient):
173
164
  headers=headers,
174
165
  form=True
175
166
  )
176
- try:
177
- result = response.json()
178
- return result
179
- except JSONDecodeError as e:
180
- logger.error(f"Unable to refresh access token: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
181
- raise InvalidAPIResponseException(f"Unable to refresh access token: {response.text}")
167
+ return parse_json_response(response, "refresh access token")
182
168
 
183
169
  def get_authentication_types(self):
184
170
  response = self.api_service.get(
185
171
  endpoint=GET_ACCESS_TOKEN_V2,
186
172
  params={},
187
173
  )
188
- try:
189
- result = response.json()
190
- return result
191
- except JSONDecodeError as e:
192
- logger.error(f"Unable to get authentication types: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
193
- raise InvalidAPIResponseException(f"Unable to get authentication types: {response.text}")
174
+ return parse_json_response(response, "get authentication types")
pygeai/health/clients.py CHANGED
@@ -1,8 +1,9 @@
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
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.health.endpoints import STATUS_CHECK_V1
7
8
 
8
9
 
@@ -19,9 +20,4 @@ class HealthClient(BaseClient):
19
20
  response = self.api_service.get(
20
21
  endpoint=endpoint
21
22
  )
22
- try:
23
- result = response.json()
24
- return result
25
- except JSONDecodeError as e:
26
- logger.error(f"Unable to check API status: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
27
- raise InvalidAPIResponseException(f"Unable to check API status: {response.text}")
23
+ return parse_json_response(response, "check API status")
@@ -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.common.exceptions import MissingRequirementException, InvalidAPIResponseException
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.lab.agents.endpoints import CREATE_AGENT_V2, LIST_AGENTS_V2, GET_AGENT_V2, CREATE_SHARING_LINK_V2, \
7
- PUBLISH_AGENT_REVISION_V2, DELETE_AGENT_V2, UPDATE_AGENT_V2, UPSERT_AGENT_V2, EXPORT_AGENT_V2, IMPORT_AGENT_V2
8
+ PUBLISH_AGENT_REVISION_V2, DELETE_AGENT_V2, UPDATE_AGENT_V2, UPSERT_AGENT_V2, EXPORT_AGENT_V4, IMPORT_AGENT_V4
8
9
  from pygeai.lab.constants import VALID_ACCESS_SCOPES
9
10
  from pygeai.lab.clients import AILabClient
10
11
 
@@ -52,13 +53,7 @@ class AgentClient(AILabClient):
52
53
  "allowExternal": allow_external
53
54
  }
54
55
  )
55
- try:
56
- result = response.json()
57
- except JSONDecodeError as e:
58
- logger.error(f"Unable to list agents for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
59
- raise InvalidAPIResponseException(f"Unable to list agents for project {self.project_id}: {response.text}")
60
-
61
- return result
56
+ return parse_json_response(response, f"list agents for project {self.project_id}")
62
57
 
63
58
  def create_agent(
64
59
  self,
@@ -139,13 +134,8 @@ class AgentClient(AILabClient):
139
134
  data=data
140
135
  )
141
136
 
142
- try:
143
- result = response.json()
144
- except JSONDecodeError as e:
145
- logger.error(f"Unable to create agent for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
146
- raise InvalidAPIResponseException(f"Unable to create agent for project {self.project_id}: {response.text}")
137
+ return parse_json_response(response, f"create agent for project {self.project_id}")
147
138
 
148
- return result
149
139
 
150
140
  def get_agent(
151
141
  self,
@@ -185,13 +175,8 @@ class AgentClient(AILabClient):
185
175
  "allowDrafts": allow_drafts,
186
176
  }
187
177
  )
188
- try:
189
- result = response.json()
190
- except JSONDecodeError as e:
191
- logger.error(f"Unable to retrieve agent {agent_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
192
- raise InvalidAPIResponseException(f"Unable to retrieve agent {agent_id} for project {self.project_id}: {response.text}")
178
+ return parse_json_response(response, f"retrieve agent {agent_id} for project {self.project_id}")
193
179
 
194
- return result
195
180
 
196
181
  def create_sharing_link(
197
182
  self,
@@ -221,13 +206,8 @@ class AgentClient(AILabClient):
221
206
  headers=headers,
222
207
  params={}
223
208
  )
224
- try:
225
- result = response.json()
226
- except JSONDecodeError as e:
227
- logger.error(f"Unable to create sharing link for agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
228
- raise InvalidAPIResponseException(f"Unable to create sharing link for agent {agent_id} in project {self.project_id}: {response.text}")
209
+ return parse_json_response(response, f"create sharing link for agent {agent_id} in project {self.project_id}")
229
210
 
230
- return result
231
211
 
232
212
  def publish_agent_revision(
233
213
  self,
@@ -257,13 +237,8 @@ class AgentClient(AILabClient):
257
237
  "revision": revision,
258
238
  }
259
239
  )
260
- try:
261
- result = response.json()
262
- except JSONDecodeError as e:
263
- logger.error(f"Unable to publish revision {revision} for agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
264
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for agent {agent_id} in project {self.project_id}: {response.text}")
240
+ return parse_json_response(response, f"publish revision {revision} for agent {agent_id} in project {self.project_id}")
265
241
 
266
- return result
267
242
 
268
243
  def delete_agent(
269
244
  self,
@@ -381,13 +356,8 @@ class AgentClient(AILabClient):
381
356
  data=data
382
357
  )
383
358
 
384
- try:
385
- result = response.json()
386
- except JSONDecodeError as e:
387
- logger.error(f"Unable to update agent {agent_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
388
- raise InvalidAPIResponseException(f"Unable to update agent {agent_id} in project {self.project_id}: {response.text}")
359
+ return parse_json_response(response, f"update agent {agent_id} in project {self.project_id}")
389
360
 
390
- return result
391
361
 
392
362
  def export_agent(
393
363
  self,
@@ -404,7 +374,7 @@ class AgentClient(AILabClient):
404
374
  if not agent_id:
405
375
  raise MissingRequirementException("agent_id must be specified in order to export the agent")
406
376
 
407
- endpoint = EXPORT_AGENT_V2.format(agentId=agent_id)
377
+ endpoint = EXPORT_AGENT_V4.format(agentId=agent_id)
408
378
  headers = {
409
379
  "Authorization": self.api_service.token,
410
380
  "ProjectId": self.project_id
@@ -416,13 +386,8 @@ class AgentClient(AILabClient):
416
386
  endpoint=endpoint,
417
387
  headers=headers,
418
388
  )
419
- try:
420
- result = response.json()
421
- except JSONDecodeError as e:
422
- logger.error(f"Unable to export agent {agent_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
423
- raise InvalidAPIResponseException(f"Unable to export agent {agent_id} for project {self.project_id}: {response.text}")
389
+ return parse_json_response(response, f"export agent {agent_id} for project {self.project_id}")
424
390
 
425
- return result
426
391
 
427
392
  def import_agent(
428
393
  self,
@@ -439,7 +404,7 @@ class AgentClient(AILabClient):
439
404
  if not data:
440
405
  raise MissingRequirementException("data for spec must be specified in order to import the agent")
441
406
 
442
- endpoint = IMPORT_AGENT_V2
407
+ endpoint = IMPORT_AGENT_V4
443
408
  headers = {
444
409
  "Authorization": self.api_service.token,
445
410
  "ProjectId": self.project_id
@@ -450,10 +415,5 @@ class AgentClient(AILabClient):
450
415
  headers=headers,
451
416
  data=data
452
417
  )
453
- try:
454
- result = response.json()
455
- except JSONDecodeError as e:
456
- logger.error(f"Unable to import agent for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
457
- raise InvalidAPIResponseException(f"Unable to import agent for project {self.project_id}: {response.text}")
418
+ return parse_json_response(response, f"import agent for project {self.project_id}")
458
419
 
459
- return result
@@ -8,3 +8,5 @@ UPDATE_AGENT_V2 = "v2/agents/{agentId}" # PUT -> Update agent
8
8
  UPSERT_AGENT_V2 = "v2/agents/{agentId}/upsert" # PUT -> Update or Insert agent
9
9
  EXPORT_AGENT_V2 = "v2/agents/{agentId}/export" # GET -> Export agent
10
10
  IMPORT_AGENT_V2 = "v2/agents/import" # POST -> Import agent
11
+ EXPORT_AGENT_V4 = "v4/agents/{agentId}/export" # GET -> Export agent
12
+ IMPORT_AGENT_V4 = "v4/agents/import" # POST -> Import agent
pygeai/lab/clients.py CHANGED
@@ -2,6 +2,7 @@ from pygeai import logger
2
2
  from pygeai.admin.clients import AdminClient
3
3
  from pygeai.core.base.clients import BaseClient
4
4
  from pygeai.core.common.exceptions import APIError
5
+ from pygeai.core.utils.validators import validate_status_code
5
6
 
6
7
 
7
8
  class AILabClient(BaseClient):
@@ -1,8 +1,9 @@
1
- from json import JSONDecodeError
2
1
  from typing import List
3
2
 
4
3
  from pygeai import logger
5
4
  from pygeai.core.common.exceptions import InvalidAPIResponseException
5
+ from pygeai.core.utils.validators import validate_status_code
6
+ from pygeai.core.utils.parsers import parse_json_response
6
7
  from pygeai.lab.processes.endpoints import CREATE_PROCESS_V2, UPDATE_PROCESS_V2, UPSERT_PROCESS_V2, GET_PROCESS_V2, \
7
8
  LIST_PROCESSES_V2, LIST_PROCESS_INSTANCES_V2, DELETE_PROCESS_V2, PUBLISH_PROCESS_REVISION_V2, CREATE_TASK_V2, \
8
9
  UPDATE_TASK_V2, UPSERT_TASK_V2, GET_TASK_V2, LIST_TASKS_V2, DELETE_TASK_V2, PUBLISH_TASK_REVISION_V2, \
@@ -84,13 +85,8 @@ class AgenticProcessClient(AILabClient):
84
85
  logger.debug(f"Creating agentic process with data: {data}")
85
86
 
86
87
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
87
- try:
88
- result = response.json()
89
- except JSONDecodeError as e:
90
- logger.error(f"Unable to create process for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
91
- raise InvalidAPIResponseException(f"Unable to create process for project {self.project_id}: {response.text}")
88
+ return parse_json_response(response, f"create process for project {self.project_id}")
92
89
 
93
- return result
94
90
 
95
91
  def update_process(
96
92
  self,
@@ -194,13 +190,8 @@ class AgenticProcessClient(AILabClient):
194
190
  headers=headers,
195
191
  data=data
196
192
  )
197
- try:
198
- result = response.json()
199
- except JSONDecodeError as e:
200
- logger.error(f"Unable to update process {process_id or name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
201
- raise InvalidAPIResponseException(f"Unable to update process {process_id or name} in project {self.project_id}: {response.text}")
193
+ return parse_json_response(response, f"update process {process_id or name} in project {self.project_id}")
202
194
 
203
- return result
204
195
 
205
196
  def get_process(
206
197
  self,
@@ -248,13 +239,8 @@ class AgenticProcessClient(AILabClient):
248
239
  headers=headers,
249
240
  params=params
250
241
  )
251
- try:
252
- result = response.json()
253
- except JSONDecodeError as e:
254
- logger.error(f"Unable to retrieve process {process_id or process_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
255
- raise InvalidAPIResponseException(f"Unable to retrieve process {process_id or process_name} for project {self.project_id}: {response.text}")
242
+ return parse_json_response(response, f"retrieve process {process_id or process_name} for project {self.project_id}")
256
243
 
257
- return result
258
244
 
259
245
  def list_processes(
260
246
  self,
@@ -301,13 +287,8 @@ class AgenticProcessClient(AILabClient):
301
287
  headers=headers,
302
288
  params=params
303
289
  )
304
- try:
305
- result = response.json()
306
- except JSONDecodeError as e:
307
- logger.error(f"Unable to list processes for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
308
- raise InvalidAPIResponseException(f"Unable to list processes for project {self.project_id}: {response.text}")
290
+ return parse_json_response(response, f"list processes for project {self.project_id}")
309
291
 
310
- return result
311
292
 
312
293
  def list_process_instances(
313
294
  self,
@@ -348,13 +329,8 @@ class AgenticProcessClient(AILabClient):
348
329
  headers=headers,
349
330
  params=params
350
331
  )
351
- try:
352
- result = response.json()
353
- except JSONDecodeError as e:
354
- logger.error(f"Unable to list process instances for process {process_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
355
- raise InvalidAPIResponseException(f"Unable to list process instances for process {process_id} in project {self.project_id}: {response.text}")
332
+ return parse_json_response(response, f"list process instances for process {process_id} in project {self.project_id}")
356
333
 
357
- return result
358
334
 
359
335
  def delete_process(
360
336
  self,
@@ -435,13 +411,8 @@ class AgenticProcessClient(AILabClient):
435
411
  "revision": revision
436
412
  }
437
413
  )
438
- try:
439
- result = response.json()
440
- except JSONDecodeError as e:
441
- logger.error(f"Unable to publish revision {revision} for process {process_id or process_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
442
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for process {process_id or process_name} in project {self.project_id}: {response.text}")
414
+ return parse_json_response(response, f"publish revision {revision} for process {process_id or process_name} in project {self.project_id}")
443
415
 
444
- return result
445
416
 
446
417
  def create_task(
447
418
  self,
@@ -495,12 +466,7 @@ class AgenticProcessClient(AILabClient):
495
466
  logger.debug(f"Creating task with data: {data}")
496
467
 
497
468
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
498
- try:
499
- return response.json()
500
- except JSONDecodeError as e:
501
- logger.error(f"Unable to create task for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
502
- raise InvalidAPIResponseException(f"Unable to create task for project {self.project_id}: {response.text}")
503
-
469
+ return parse_json_response(response, f"create task for project {self.project_id}")
504
470
  def get_task(
505
471
  self,
506
472
  task_id: str,
@@ -531,12 +497,7 @@ class AgenticProcessClient(AILabClient):
531
497
  logger.debug(f"Retrieving task detail with name {task_name}")
532
498
 
533
499
  response = self.api_service.get(endpoint=endpoint, headers=headers)
534
- try:
535
- return response.json()
536
- except JSONDecodeError as e:
537
- logger.error(f"Unable to retrieve task {task_id or task_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
538
- raise InvalidAPIResponseException(f"Unable to retrieve task {task_id or task_name} for project {self.project_id}: {response.text}")
539
-
500
+ return parse_json_response(response, f"retrieve task {task_id or task_name} for project {self.project_id}")
540
501
  def list_tasks(
541
502
  self,
542
503
  id: str = None,
@@ -570,12 +531,7 @@ class AgenticProcessClient(AILabClient):
570
531
  logger.debug(f"Listing tasks for project with ID {self.project_id}")
571
532
 
572
533
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
573
- try:
574
- return response.json()
575
- except JSONDecodeError as e:
576
- logger.error(f"Unable to list tasks for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
577
- raise InvalidAPIResponseException(f"Unable to list tasks for project {self.project_id}: {response.text}")
578
-
534
+ return parse_json_response(response, f"list tasks for project {self.project_id}")
579
535
  def update_task(
580
536
  self,
581
537
  task_id: str,
@@ -638,12 +594,7 @@ class AgenticProcessClient(AILabClient):
638
594
  logger.debug(f"Updating task with ID {task_id} with data: {data}")
639
595
 
640
596
  response = self.api_service.put(endpoint=endpoint, headers=headers, data=data)
641
- try:
642
- return response.json()
643
- except JSONDecodeError as e:
644
- logger.error(f"Unable to update task {task_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
645
- raise InvalidAPIResponseException(f"Unable to update task {task_id} in project {self.project_id}: {response.text}")
646
-
597
+ return parse_json_response(response, f"update task {task_id} in project {self.project_id}")
647
598
  def delete_task(
648
599
  self,
649
600
  task_id: str,
@@ -720,12 +671,7 @@ class AgenticProcessClient(AILabClient):
720
671
  logger.debug(f"Publishing revision {revision} for task with name {task_name}")
721
672
 
722
673
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
723
- try:
724
- return response.json()
725
- except JSONDecodeError as e:
726
- logger.error(f"Unable to publish revision {revision} for task {task_id or task_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
727
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for task {task_id or task_name} in project {self.project_id}: {response.text}")
728
-
674
+ return parse_json_response(response, f"publish revision {revision} for task {task_id or task_name} in project {self.project_id}")
729
675
  def start_instance(
730
676
  self,
731
677
  process_name: str,
@@ -761,12 +707,7 @@ class AgenticProcessClient(AILabClient):
761
707
  logger.info(f"Starting instance for process with name '{process_name}'")
762
708
 
763
709
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
764
- try:
765
- return response.json()
766
- except JSONDecodeError as e:
767
- logger.error(f"Unable to start instance for process {process_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
768
- raise InvalidAPIResponseException(f"Unable to start instance for process {process_name} in project {self.project_id}: {response.text}")
769
-
710
+ return parse_json_response(response, f"start instance for process {process_name} in project {self.project_id}")
770
711
  def abort_instance(
771
712
  self,
772
713
  instance_id: str
@@ -793,12 +734,7 @@ class AgenticProcessClient(AILabClient):
793
734
  logger.info(f"Aborting instance with ID '{instance_id}'")
794
735
 
795
736
  response = self.api_service.post(endpoint=endpoint, headers=headers, data={})
796
- try:
797
- return response.json()
798
- except JSONDecodeError as e:
799
- logger.error(f"Unable to abort instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
800
- raise InvalidAPIResponseException(f"Unable to abort instance {instance_id} in project {self.project_id}: {response.text}")
801
-
737
+ return parse_json_response(response, f"abort instance {instance_id} in project {self.project_id}")
802
738
  def get_instance(
803
739
  self,
804
740
  instance_id: str
@@ -823,12 +759,7 @@ class AgenticProcessClient(AILabClient):
823
759
  logger.info(f"Retrieving instance detail with ID '{instance_id}'")
824
760
 
825
761
  response = self.api_service.get(endpoint=endpoint, headers=headers)
826
- try:
827
- return response.json()
828
- except JSONDecodeError as e:
829
- logger.error(f"Unable to retrieve instance {instance_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
830
- raise InvalidAPIResponseException(f"Unable to retrieve instance {instance_id} for project {self.project_id}: {response.text}")
831
-
762
+ return parse_json_response(response, f"retrieve instance {instance_id} for project {self.project_id}")
832
763
  def get_instance_history(
833
764
  self,
834
765
  instance_id: str
@@ -853,12 +784,7 @@ class AgenticProcessClient(AILabClient):
853
784
  logger.info(f"Retrieving instance history with ID '{instance_id}'")
854
785
 
855
786
  response = self.api_service.get(endpoint=endpoint, headers=headers)
856
- try:
857
- return response.json()
858
- except JSONDecodeError as e:
859
- logger.error(f"Unable to retrieve history for instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
860
- raise InvalidAPIResponseException(f"Unable to retrieve history for instance {instance_id} in project {self.project_id}: {response.text}")
861
-
787
+ return parse_json_response(response, f"retrieve history for instance {instance_id} in project {self.project_id}")
862
788
  def get_thread_information(
863
789
  self,
864
790
  thread_id: str
@@ -883,12 +809,7 @@ class AgenticProcessClient(AILabClient):
883
809
  logger.debug(f"Retrieving information about thread with ID {thread_id}")
884
810
 
885
811
  response = self.api_service.get(endpoint=endpoint, headers=headers)
886
- try:
887
- return response.json()
888
- except JSONDecodeError as e:
889
- logger.error(f"Unable to retrieve thread information for thread {thread_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
890
- raise InvalidAPIResponseException(f"Unable to retrieve thread information for thread {thread_id} in project {self.project_id}: {response.text}")
891
-
812
+ return parse_json_response(response, f"retrieve thread information for thread {thread_id} in project {self.project_id}")
892
813
  def send_user_signal(
893
814
  self,
894
815
  instance_id: str,
@@ -922,12 +843,7 @@ class AgenticProcessClient(AILabClient):
922
843
  logger.debug(f"Sending user signal to process instance with ID {instance_id} with data: {data}")
923
844
 
924
845
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
925
- try:
926
- return response.json()
927
- except JSONDecodeError as e:
928
- logger.error(f"Unable to send user signal {signal_name} to instance {instance_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
929
- raise InvalidAPIResponseException(f"Unable to send user signal {signal_name} to instance {instance_id} in project {self.project_id}: {response.text}")
930
-
846
+ return parse_json_response(response, f"send user signal {signal_name} to instance {instance_id} in project {self.project_id}")
931
847
  def create_kb(
932
848
  self,
933
849
  name: str,
@@ -967,12 +883,7 @@ class AgenticProcessClient(AILabClient):
967
883
  headers=headers,
968
884
  data=data
969
885
  )
970
- try:
971
- return response.json()
972
- except JSONDecodeError as e:
973
- logger.error(f"Unable to create knowledge base for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
974
- raise InvalidAPIResponseException(f"Unable to create knowledge base for project {self.project_id}: {response.text}")
975
-
886
+ return parse_json_response(response, f"create knowledge base for project {self.project_id}")
976
887
  def get_kb(
977
888
  self,
978
889
  kb_id: str = None,
@@ -1003,12 +914,8 @@ class AgenticProcessClient(AILabClient):
1003
914
  logger.debug(f"Retrieving KB detail with name {kb_name}")
1004
915
 
1005
916
  response = self.api_service.get(endpoint=endpoint, headers=headers)
1006
- try:
1007
- return response.json()
1008
- except JSONDecodeError as e:
1009
- logger.error(f"Unable to retrieve knowledge base {kb_id or kb_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
1010
- raise InvalidAPIResponseException(f"Unable to retrieve knowledge base {kb_id or kb_name} for project {self.project_id}: {response.text}")
1011
-
917
+ kb_identifier = kb_id or kb_name
918
+ return parse_json_response(response, f"retrieve knowledge base {kb_identifier} for project {self.project_id}")
1012
919
  def list_kbs(
1013
920
  self,
1014
921
  name: str = None,
@@ -1039,12 +946,7 @@ class AgenticProcessClient(AILabClient):
1039
946
  logger.debug(f"Listing tasks in project with ID {self.project_id}")
1040
947
 
1041
948
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
1042
- try:
1043
- return response.json()
1044
- except JSONDecodeError as e:
1045
- logger.error(f"Unable to list knowledge bases for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
1046
- raise InvalidAPIResponseException(f"Unable to list knowledge bases for project {self.project_id}: {response.text}")
1047
-
949
+ return parse_json_response(response, f"list knowledge bases for project {self.project_id}")
1048
950
  def delete_kb(
1049
951
  self,
1050
952
  kb_id: str = None,
@@ -1124,10 +1026,5 @@ class AgenticProcessClient(AILabClient):
1124
1026
  headers=headers,
1125
1027
  params=params
1126
1028
  )
1127
- try:
1128
- result = response.json()
1129
- except JSONDecodeError as e:
1130
- logger.error(f"Unable to list jobs for project {self.project_id}: JSONDecodeError parsing error (status {response.status_code}): {e}. Response: {response.text}")
1131
- raise InvalidAPIResponseException(f"Unable to list jobs for project {self.project_id}: {response.text}")
1029
+ return parse_json_response(response, f"list jobs for project {self.project_id}")
1132
1030
 
1133
- return result