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
@@ -1,7 +1,8 @@
1
- from json import JSONDecodeError
2
1
 
3
2
  from pygeai import logger
4
3
  from pygeai.core.common.exceptions import InvalidAPIResponseException
4
+ from pygeai.core.utils.validators import validate_status_code
5
+ from pygeai.core.utils.parsers import parse_json_response
5
6
  from pygeai.lab.clients import AILabClient
6
7
  from pygeai.lab.strategies.endpoints import LIST_REASONING_STRATEGIES_V2, CREATE_REASONING_STRATEGY_V2, \
7
8
  UPDATE_REASONING_STRATEGY_V2, UPSERT_REASONING_STRATEGY_V2, GET_REASONING_STRATEGY_V2
@@ -46,13 +47,8 @@ class ReasoningStrategyClient(AILabClient):
46
47
  logger.debug("Listing reasoning strategies")
47
48
 
48
49
  response = self.api_service.get(endpoint=endpoint, headers=headers, params=params)
49
- try:
50
- result = response.json()
51
- except JSONDecodeError as e:
52
- logger.error(f"Unable to list reasoning strategies: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
53
- raise InvalidAPIResponseException(f"Unable to list reasoning strategies: {response.text}")
50
+ return parse_json_response(response, "list reasoning strategies")
54
51
 
55
- return result
56
52
 
57
53
  def create_reasoning_strategy(
58
54
  self,
@@ -98,13 +94,8 @@ class ReasoningStrategyClient(AILabClient):
98
94
  logger.debug(f"Creating reasoning strategy with data: {data}")
99
95
 
100
96
  response = self.api_service.post(endpoint=endpoint, headers=headers, data=data)
101
- try:
102
- result = response.json()
103
- except JSONDecodeError as e:
104
- logger.error(f"Unable to create reasoning strategy for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
105
- raise InvalidAPIResponseException(f"Unable to create reasoning strategy for project {self.project_id}: {response.text}")
97
+ return parse_json_response(response, f"create reasoning strategy for project {self.project_id}")
106
98
 
107
- return result
108
99
 
109
100
  def update_reasoning_strategy(
110
101
  self,
@@ -174,13 +165,8 @@ class ReasoningStrategyClient(AILabClient):
174
165
  headers=headers,
175
166
  data=data
176
167
  )
177
- try:
178
- result = response.json()
179
- except JSONDecodeError as e:
180
- logger.error(f"Unable to update reasoning strategy {reasoning_strategy_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
181
- raise InvalidAPIResponseException(f"Unable to update reasoning strategy {reasoning_strategy_id} in project {self.project_id}: {response.text}")
168
+ return parse_json_response(response, f"update reasoning strategy {reasoning_strategy_id} in project {self.project_id}")
182
169
 
183
- return result
184
170
 
185
171
  def get_reasoning_strategy(
186
172
  self,
@@ -216,11 +202,7 @@ class ReasoningStrategyClient(AILabClient):
216
202
  endpoint=endpoint,
217
203
  headers=headers
218
204
  )
219
- try:
220
- result = response.json()
221
- except JSONDecodeError as e:
222
- logger.error(f"Unable to retrieve reasoning strategy {reasoning_strategy_id or reasoning_strategy_name} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
223
- raise InvalidAPIResponseException(f"Unable to retrieve reasoning strategy {reasoning_strategy_id or reasoning_strategy_name} for project {self.project_id}: {response.text}")
205
+ strategy_identifier = reasoning_strategy_id or reasoning_strategy_name
206
+ return parse_json_response(response, f"retrieve reasoning strategy {strategy_identifier} for project {self.project_id}")
224
207
 
225
- return result
226
208
 
@@ -1,11 +1,12 @@
1
1
  import json
2
- from json import JSONDecodeError
3
2
 
4
3
  from pygeai import logger
5
4
  from pygeai.core.common.exceptions import InvalidAPIResponseException, MissingRequirementException, APIResponseError
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.constants import VALID_SCOPES, VALID_ACCESS_SCOPES, VALID_REPORT_EVENTS
7
8
  from pygeai.lab.tools.endpoints import CREATE_TOOL_V2, LIST_TOOLS_V2, GET_TOOL_V2, UPDATE_TOOL_V2, UPSERT_TOOL_V2, \
8
- PUBLISH_TOOL_REVISION_V2, GET_PARAMETER_V2, SET_PARAMETER_V2, DELETE_TOOL_V2, EXPORT_TOOL_V2
9
+ PUBLISH_TOOL_REVISION_V2, GET_PARAMETER_V2, SET_PARAMETER_V2, DELETE_TOOL_V2, EXPORT_TOOL_V4
9
10
  from pygeai.lab.clients import AILabClient
10
11
 
11
12
 
@@ -115,16 +116,9 @@ class ToolClient(AILabClient):
115
116
  data=data
116
117
  )
117
118
 
118
- if response.status_code >= 300:
119
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
120
- raise APIResponseError(f"API returned an error: {response.text}")
121
- try:
122
- result = response.json()
123
- except JSONDecodeError as e:
124
- logger.error(f"Unable to create tool for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
125
- raise InvalidAPIResponseException(f"Unable to create tool for project {self.project_id}: {response.text}")
119
+ validate_status_code(response)
120
+ return parse_json_response(response, f"create tool for project {self.project_id}")
126
121
 
127
- return result
128
122
 
129
123
  def list_tools(
130
124
  self,
@@ -169,16 +163,9 @@ class ToolClient(AILabClient):
169
163
  "allowExternal": allow_external
170
164
  }
171
165
  )
172
- if response.status_code >= 300:
173
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
174
- raise APIResponseError(f"API returned an error: {response.text}")
175
- try:
176
- result = response.json()
177
- except JSONDecodeError as e:
178
- logger.error(f"Unable to list tools for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
179
- raise InvalidAPIResponseException(f"Unable to list tools for project {self.project_id}: {response.text}")
166
+ validate_status_code(response)
167
+ return parse_json_response(response, f"list tools for project {self.project_id}")
180
168
 
181
- return result
182
169
 
183
170
  def get_tool(
184
171
  self,
@@ -213,16 +200,9 @@ class ToolClient(AILabClient):
213
200
  "allowDrafts": allow_drafts,
214
201
  }
215
202
  )
216
- if response.status_code >= 300:
217
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
218
- raise APIResponseError(f"API returned an error: {response.text}")
219
- try:
220
- result = response.json()
221
- except JSONDecodeError as e:
222
- logger.error(f"Unable to retrieve tool {tool_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
223
- raise InvalidAPIResponseException(f"Unable to retrieve tool {tool_id} for project {self.project_id}: {response.text}")
203
+ validate_status_code(response)
204
+ return parse_json_response(response, f"retrieve tool {tool_id} for project {self.project_id}")
224
205
 
225
- return result
226
206
 
227
207
  def delete_tool(
228
208
  self,
@@ -256,9 +236,7 @@ class ToolClient(AILabClient):
256
236
  endpoint=endpoint,
257
237
  headers=headers
258
238
  )
259
- if response.status_code >= 300:
260
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
261
- raise APIResponseError(f"API returned an error: {response.text}")
239
+ validate_status_code(response)
262
240
 
263
241
  if response.status_code != 204:
264
242
  logger.error(f"Unable to delete tool {tool_id or tool_name} in project {self.project_id}: JSON parsing error (status {response.status_code}). Response: {response.text}")
@@ -376,16 +354,9 @@ class ToolClient(AILabClient):
376
354
  headers=headers,
377
355
  data=data
378
356
  )
379
- if response.status_code >= 300:
380
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
381
- raise APIResponseError(f"API returned an error: {response.text}")
382
- try:
383
- result = response.json()
384
- except JSONDecodeError as e:
385
- logger.error(f"Unable to update tool {tool_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
386
- raise InvalidAPIResponseException(f"Unable to update tool {tool_id} in project {self.project_id}: {response.text}")
357
+ validate_status_code(response)
358
+ return parse_json_response(response, f"update tool {tool_id} in project {self.project_id}")
387
359
 
388
- return result
389
360
 
390
361
  def publish_tool_revision(
391
362
  self,
@@ -414,13 +385,8 @@ class ToolClient(AILabClient):
414
385
  "revision": revision,
415
386
  }
416
387
  )
417
- try:
418
- result = response.json()
419
- except JSONDecodeError as e:
420
- logger.error(f"Unable to publish revision {revision} for tool {tool_id} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
421
- raise InvalidAPIResponseException(f"Unable to publish revision {revision} for tool {tool_id} in project {self.project_id}: {response.text}")
388
+ return parse_json_response(response, f"publish revision {revision} for tool {tool_id} in project {self.project_id}")
422
389
 
423
- return result
424
390
 
425
391
  def get_parameter(
426
392
  self,
@@ -464,16 +430,10 @@ class ToolClient(AILabClient):
464
430
  "allowDrafts": allow_drafts,
465
431
  }
466
432
  )
467
- if response.status_code >= 300:
468
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
469
- raise APIResponseError(f"API returned an error: {response.text}")
470
- try:
471
- result = response.json()
472
- except JSONDecodeError as e:
473
- logger.error(f"Unable to retrieve parameters for tool {tool_id or tool_public_name} in project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
474
- raise InvalidAPIResponseException(f"Unable to retrieve parameters for tool {tool_id or tool_public_name} in project {self.project_id}: {response.text}")
433
+ validate_status_code(response)
434
+ tool_identifier = tool_id or tool_public_name
435
+ return parse_json_response(response, f"retrieve parameters for tool {tool_identifier} in project {self.project_id}")
475
436
 
476
- return result
477
437
 
478
438
  def set_parameter(
479
439
  self,
@@ -527,6 +487,7 @@ class ToolClient(AILabClient):
527
487
  else:
528
488
  return {}
529
489
 
490
+ '''
530
491
  def export_tool(
531
492
  self,
532
493
  tool_id: str,
@@ -543,7 +504,7 @@ class ToolClient(AILabClient):
543
504
  if not tool_id:
544
505
  raise MissingRequirementException("tool_id must be specified in order to retrieve the tool")
545
506
 
546
- endpoint = EXPORT_TOOL_V2.format(toolId=tool_id)
507
+ endpoint = EXPORT_TOOL_V4.format(toolId=tool_id)
547
508
  headers = {
548
509
  "Authorization": self.api_service.token,
549
510
  "ProjectId": self.project_id
@@ -555,13 +516,7 @@ class ToolClient(AILabClient):
555
516
  endpoint=endpoint,
556
517
  headers=headers,
557
518
  )
558
- if response.status_code >= 300:
559
- logger.error(f"Invalid status code returned from the API endpoint: {response.text}")
560
- raise APIResponseError(f"API returned an error: {response.text}")
561
- try:
562
- result = response.json()
563
- except JSONDecodeError as e:
564
- logger.error(f"Unable to export tool {tool_id} for project {self.project_id}: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
565
- raise InvalidAPIResponseException(f"Unable to export tool {tool_id} for project {self.project_id}: {response.text}")
566
-
567
- return result
519
+ validate_status_code(response)
520
+ return parse_json_response(response, f"export tool {tool_id} for project {self.project_id}")
521
+
522
+ '''
@@ -8,3 +8,6 @@ PUBLISH_TOOL_REVISION_V2 = "v2/tools/{toolId}/publish-revision" # POST -> Publi
8
8
  GET_PARAMETER_V2 = "v2/tools/{toolPublicName}/config" # GET -> Get tool parameter
9
9
  SET_PARAMETER_V2 = "v2/tools/{toolPublicName}/config" # POST -> Set tool parameter
10
10
  EXPORT_TOOL_V2 = "v2/tools/{toolId}/export" # GET -> Export tool
11
+ IMPORT_TOOL_V2 = "v2/tools/import" # POST -> Import tool
12
+ EXPORT_TOOL_V4 = "v4/tools/{toolId}/export" # GET -> Export tool
13
+ IMPORT_TOOL_V4 = "v4/tools/import" # POST -> Import tool
@@ -1,11 +1,13 @@
1
- import json
2
- from json import JSONDecodeError
3
1
 
4
2
  from pygeai import logger
5
3
  from pygeai.core.common.exceptions import InvalidAPIResponseException
6
4
  from pygeai.organization.endpoints import GET_ASSISTANT_LIST_V1, GET_PROJECT_LIST_V1, GET_PROJECT_V1, \
7
- CREATE_PROJECT_V1, UPDATE_PROJECT_V1, DELETE_PROJECT_V1, GET_PROJECT_TOKENS_V1, GET_REQUEST_DATA_V1
5
+ CREATE_PROJECT_V1, UPDATE_PROJECT_V1, DELETE_PROJECT_V1, GET_PROJECT_TOKENS_V1, GET_REQUEST_DATA_V1, \
6
+ GET_MEMBERSHIPS_V2, GET_PROJECT_MEMBERSHIPS_V2, GET_PROJECT_ROLES_V2, GET_PROJECT_MEMBERS_V2, \
7
+ GET_ORGANIZATION_MEMBERS_V2
8
8
  from pygeai.core.base.clients import BaseClient
9
+ from pygeai.core.utils.validators import validate_status_code
10
+ from pygeai.core.utils.parsers import parse_json_response
9
11
 
10
12
 
11
13
  class OrganizationClient(BaseClient):
@@ -23,12 +25,7 @@ class OrganizationClient(BaseClient):
23
25
  :return: AssistantListResponse - The API response containing the list of assistants and the project.
24
26
  """
25
27
  response = self.api_service.get(endpoint=GET_ASSISTANT_LIST_V1, params={"detail": detail})
26
- try:
27
- result = response.json()
28
- return result
29
- except JSONDecodeError as e:
30
- logger.error(f"Unable to get assistant list: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
31
- raise InvalidAPIResponseException(f"Unable to get assistant list: {response.text}")
28
+ return parse_json_response(response, "get assistant list")
32
29
 
33
30
  def get_project_list(
34
31
  self,
@@ -59,12 +56,7 @@ class OrganizationClient(BaseClient):
59
56
  "detail": detail
60
57
  }
61
58
  )
62
- try:
63
- result = response.json()
64
- return result
65
- except JSONDecodeError as e:
66
- logger.error(f"Unable to get project list: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
67
- raise InvalidAPIResponseException(f"Unable to get project list: {response.text}")
59
+ return parse_json_response(response, "get project list")
68
60
 
69
61
  def get_project_data(
70
62
  self,
@@ -80,12 +72,7 @@ class OrganizationClient(BaseClient):
80
72
  response = self.api_service.get(
81
73
  endpoint=endpoint
82
74
  )
83
- try:
84
- result = response.json()
85
- return result
86
- except JSONDecodeError as e:
87
- logger.error(f"Unable to get project data for ID '{project_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
88
- raise InvalidAPIResponseException(f"Unable to get project data for ID '{project_id}': {response.text}")
75
+ return parse_json_response(response, "get project data for ID", project_id=project_id)
89
76
 
90
77
  def create_project(
91
78
  self,
@@ -122,12 +109,7 @@ class OrganizationClient(BaseClient):
122
109
  "description": description
123
110
  }
124
111
  )
125
- try:
126
- result = response.json()
127
- return result
128
- except JSONDecodeError as e:
129
- logger.error(f"Unable to create project with name '{name}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
130
- raise InvalidAPIResponseException(f"Unable to create project with name '{name}': {response.text}")
112
+ return parse_json_response(response, "create project with name", name=name)
131
113
 
132
114
  def update_project(
133
115
  self,
@@ -151,12 +133,7 @@ class OrganizationClient(BaseClient):
151
133
  "description": description
152
134
  }
153
135
  )
154
- try:
155
- result = response.json()
156
- return result
157
- except JSONDecodeError as e:
158
- logger.error(f"Unable to update project with ID '{project_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
159
- raise InvalidAPIResponseException(f"Unable to update project with ID '{project_id}': {response.text}")
136
+ return parse_json_response(response, "update project with ID", project_id=project_id)
160
137
 
161
138
  def delete_project(
162
139
  self,
@@ -170,12 +147,7 @@ class OrganizationClient(BaseClient):
170
147
  """
171
148
  endpoint = DELETE_PROJECT_V1.format(id=project_id)
172
149
  response = self.api_service.delete(endpoint=endpoint)
173
- try:
174
- result = response.json()
175
- return result
176
- except JSONDecodeError as e:
177
- logger.error(f"Unable to delete project with ID '{project_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
178
- raise InvalidAPIResponseException(f"Unable to delete project with ID '{project_id}': {response.text}")
150
+ return parse_json_response(response, "delete project with ID", project_id=project_id)
179
151
 
180
152
  def get_project_tokens(
181
153
  self,
@@ -189,12 +161,7 @@ class OrganizationClient(BaseClient):
189
161
  """
190
162
  endpoint = GET_PROJECT_TOKENS_V1.format(id=project_id)
191
163
  response = self.api_service.get(endpoint=endpoint)
192
- try:
193
- result = response.json()
194
- return result
195
- except JSONDecodeError as e:
196
- logger.error(f"Unable to get tokens for project with ID '{project_id}': JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
197
- raise InvalidAPIResponseException(f"Unable to get tokens for project with ID '{project_id}': {response.text}")
164
+ return parse_json_response(response, "get tokens for project with ID", project_id=project_id)
198
165
 
199
166
  def export_request_data(
200
167
  self,
@@ -221,9 +188,113 @@ class OrganizationClient(BaseClient):
221
188
  "count": count
222
189
  }
223
190
  )
224
- try:
225
- result = response.json()
226
- return result
227
- except JSONDecodeError as e:
228
- logger.error(f"Unable to export request data: JSON parsing error (status {response.status_code}): {e}. Response: {response.text}")
229
- raise InvalidAPIResponseException(f"Unable to export request data: {response.text}")
191
+ return parse_json_response(response, "export request data")
192
+
193
+ def get_memberships(
194
+ self,
195
+ email: str = None,
196
+ start_page: int = 1,
197
+ page_size: int = 20,
198
+ order_key: str = None,
199
+ order_direction: str = "desc",
200
+ role_types: str = None
201
+ ) -> dict:
202
+ """
203
+ Retrieves a list of Organizations and Projects a user belongs to with their Roles.
204
+
205
+ :param email: str - The email address of the user to search for (optional, case-insensitive).
206
+ :param start_page: int - The page number for pagination (default is 1).
207
+ :param page_size: int - The number of items per page (default is 20).
208
+ :param order_key: str - Field for sorting. Only 'organizationName' is supported (optional).
209
+ :param order_direction: str - Sort direction: 'asc' or 'desc' (default is 'desc').
210
+ :param role_types: str - Comma-separated list of role types: 'backend', 'frontend' (optional, case-insensitive).
211
+ :return: dict - The API response containing the list of organizations and projects with roles, in JSON format.
212
+ """
213
+ params = {
214
+ "startPage": start_page,
215
+ "pageSize": page_size,
216
+ "orderDirection": order_direction
217
+ }
218
+ if email:
219
+ params["email"] = email
220
+ if order_key:
221
+ params["orderKey"] = order_key
222
+ if role_types:
223
+ params["roleTypes"] = role_types
224
+
225
+ response = self.api_service.get(endpoint=GET_MEMBERSHIPS_V2, params=params)
226
+ return parse_json_response(response, "get memberships")
227
+
228
+ def get_project_memberships(
229
+ self,
230
+ email: str = None,
231
+ start_page: int = 1,
232
+ page_size: int = 20,
233
+ order_key: str = None,
234
+ order_direction: str = "desc",
235
+ role_types: str = None
236
+ ) -> dict:
237
+ """
238
+ Retrieves a list of Projects and Roles for a user within a specific Organization.
239
+
240
+ :param email: str - The email address of the user to search for (optional, case-insensitive).
241
+ :param start_page: int - The page number for pagination (default is 1).
242
+ :param page_size: int - The number of items per page (default is 20).
243
+ :param order_key: str - Field for sorting. Only 'projectName' is supported (optional).
244
+ :param order_direction: str - Sort direction: 'asc' or 'desc' (default is 'desc').
245
+ :param role_types: str - Comma-separated list of role types: 'backend', 'frontend' (optional, case-insensitive).
246
+ :return: dict - The API response containing the list of projects with roles, in JSON format.
247
+ """
248
+ params = {
249
+ "startPage": start_page,
250
+ "pageSize": page_size,
251
+ "orderDirection": order_direction
252
+ }
253
+ if email:
254
+ params["email"] = email
255
+ if order_key:
256
+ params["orderKey"] = order_key
257
+ if role_types:
258
+ params["roleTypes"] = role_types
259
+
260
+ response = self.api_service.get(endpoint=GET_PROJECT_MEMBERSHIPS_V2, params=params)
261
+ return parse_json_response(response, "get project memberships")
262
+
263
+ def get_project_roles(
264
+ self,
265
+ project_id: str
266
+ ) -> dict:
267
+ """
268
+ Retrieves all Roles supported by a specific Project.
269
+
270
+ :param project_id: str - The unique identifier (GUID) of the project (required).
271
+ :return: dict - The API response containing the list of roles for the project, in JSON format.
272
+ """
273
+ response = self.api_service.get(endpoint=GET_PROJECT_ROLES_V2, params={"projectId": project_id})
274
+ return parse_json_response(response, "get project roles for project", project_id=project_id)
275
+
276
+ def get_project_members(
277
+ self,
278
+ project_id: str
279
+ ) -> dict:
280
+ """
281
+ Retrieves all members and their Roles for a specific Project.
282
+
283
+ :param project_id: str - The unique identifier (GUID) of the project (required).
284
+ :return: dict - The API response containing the list of members with their roles, in JSON format.
285
+ """
286
+ response = self.api_service.get(endpoint=GET_PROJECT_MEMBERS_V2, params={"projectId": project_id})
287
+ return parse_json_response(response, "get project members for project", project_id=project_id)
288
+
289
+ def get_organization_members(
290
+ self,
291
+ organization_id: str
292
+ ) -> dict:
293
+ """
294
+ Retrieves all members and their Roles for a specific Organization.
295
+
296
+ :param organization_id: str - The unique identifier (GUID) of the organization (required).
297
+ :return: dict - The API response containing the list of members with their roles, in JSON format.
298
+ """
299
+ response = self.api_service.get(endpoint=GET_ORGANIZATION_MEMBERS_V2, params={"organizationId": organization_id})
300
+ return parse_json_response(response, "get organization members for organization", organization_id=organization_id)
@@ -1,4 +1,4 @@
1
- GET_ASSISTANT_LIST_V1 = "v1/organization/assistants" # GET Gets the list of assistants
1
+ GET_ASSISTANT_LIST_V1 = "v1/organization/assistants" # GET - Gets the list of assistants
2
2
  GET_PROJECT_LIST_V1 = "v1/organization/projects" # GET - Gets the list of projects
3
3
  GET_PROJECT_V1 = "v1/organization/project/{id}" # GET - Gets project details
4
4
  CREATE_PROJECT_V1 = "v1/organization/project" # POST - Creates a project
@@ -6,3 +6,8 @@ UPDATE_PROJECT_V1 = "v1/organization/project/{id}" # PUT - Updat
6
6
  DELETE_PROJECT_V1 = "v1/organization/project/{id}" # DELETE - Deletes a project
7
7
  GET_PROJECT_TOKENS_V1 = "v1/organization/project/{id}/tokens" # GET - Gets the list of Tokens for the project
8
8
  GET_REQUEST_DATA_V1 = "v1/organization/request/export" # GET - Exports request data
9
+ GET_MEMBERSHIPS_V2 = "v2/accessControl/memberships" # GET - Lists Organizations and Projects a user belongs to with their Roles
10
+ GET_PROJECT_MEMBERSHIPS_V2 = "v2/accessControl/projects/memberships" # GET - Lists Projects and Roles for a user within a specific Organization
11
+ GET_PROJECT_ROLES_V2 = "v2/accessControl/projects/roles" # GET - Lists all Roles supported by a specific Project
12
+ GET_PROJECT_MEMBERS_V2 = "v2/accessControl/projects/members" # GET - Lists all members and their Roles for a specific Project
13
+ GET_ORGANIZATION_MEMBERS_V2 = "v2/accessControl/organizations/members" # GET - Lists all members and their Roles for a specific Organization