pygeai 0.6.0b14__py3-none-any.whl → 0.7.0b1__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 (216) hide show
  1. pygeai/__init__.py +1 -2
  2. pygeai/_docs/source/content/api_reference/project.rst +392 -0
  3. pygeai/_docs/source/content/authentication.rst +130 -1
  4. pygeai/_docs/source/content/debugger.rst +327 -157
  5. pygeai/_docs/source/pygeai.core.common.rst +8 -0
  6. pygeai/_docs/source/pygeai.tests.auth.rst +56 -0
  7. pygeai/_docs/source/pygeai.tests.cli.rst +8 -0
  8. pygeai/admin/clients.py +1 -3
  9. pygeai/analytics/clients.py +1 -1
  10. pygeai/assistant/clients.py +2 -7
  11. pygeai/assistant/data/clients.py +0 -8
  12. pygeai/assistant/data_analyst/clients.py +0 -2
  13. pygeai/assistant/managers.py +1 -1
  14. pygeai/assistant/rag/clients.py +0 -2
  15. pygeai/assistant/rag/mappers.py +9 -11
  16. pygeai/auth/clients.py +26 -7
  17. pygeai/auth/endpoints.py +2 -1
  18. pygeai/chat/clients.py +2 -2
  19. pygeai/chat/managers.py +1 -1
  20. pygeai/cli/commands/admin.py +13 -25
  21. pygeai/cli/commands/analytics.py +31 -71
  22. pygeai/cli/commands/assistant.py +84 -138
  23. pygeai/cli/commands/auth.py +23 -46
  24. pygeai/cli/commands/base.py +0 -1
  25. pygeai/cli/commands/chat.py +218 -209
  26. pygeai/cli/commands/common.py +5 -5
  27. pygeai/cli/commands/configuration.py +79 -29
  28. pygeai/cli/commands/docs.py +3 -4
  29. pygeai/cli/commands/embeddings.py +13 -19
  30. pygeai/cli/commands/evaluation.py +133 -344
  31. pygeai/cli/commands/feedback.py +7 -15
  32. pygeai/cli/commands/files.py +26 -53
  33. pygeai/cli/commands/gam.py +28 -69
  34. pygeai/cli/commands/lab/ai_lab.py +96 -142
  35. pygeai/cli/commands/lab/common.py +1 -1
  36. pygeai/cli/commands/lab/spec.py +12 -32
  37. pygeai/cli/commands/llm.py +9 -18
  38. pygeai/cli/commands/migrate.py +43 -99
  39. pygeai/cli/commands/organization.py +223 -196
  40. pygeai/cli/commands/rag.py +35 -58
  41. pygeai/cli/commands/rerank.py +21 -25
  42. pygeai/cli/commands/secrets.py +39 -67
  43. pygeai/cli/commands/usage_limits.py +50 -136
  44. pygeai/cli/commands/validators.py +1 -1
  45. pygeai/cli/geai.py +32 -3
  46. pygeai/cli/geai_proxy.py +6 -2
  47. pygeai/cli/install_man.py +1 -1
  48. pygeai/cli/parsers.py +1 -1
  49. pygeai/core/base/clients.py +90 -21
  50. pygeai/core/base/mappers.py +39 -55
  51. pygeai/core/base/session.py +129 -18
  52. pygeai/core/common/config.py +50 -13
  53. pygeai/core/common/constants.py +8 -0
  54. pygeai/core/common/exceptions.py +6 -0
  55. pygeai/core/embeddings/clients.py +0 -1
  56. pygeai/core/embeddings/managers.py +0 -1
  57. pygeai/core/feedback/clients.py +0 -2
  58. pygeai/core/feedback/models.py +1 -1
  59. pygeai/core/files/clients.py +0 -3
  60. pygeai/core/files/managers.py +1 -1
  61. pygeai/core/files/mappers.py +4 -5
  62. pygeai/core/llm/clients.py +0 -1
  63. pygeai/core/models.py +4 -4
  64. pygeai/core/plugins/clients.py +0 -3
  65. pygeai/core/plugins/models.py +2 -2
  66. pygeai/core/rerank/clients.py +0 -2
  67. pygeai/core/secrets/clients.py +0 -2
  68. pygeai/core/services/rest.py +80 -14
  69. pygeai/core/singleton.py +24 -0
  70. pygeai/dbg/__init__.py +2 -2
  71. pygeai/dbg/debugger.py +276 -38
  72. pygeai/evaluation/clients.py +2 -4
  73. pygeai/evaluation/dataset/clients.py +0 -1
  74. pygeai/evaluation/plan/clients.py +0 -2
  75. pygeai/evaluation/result/clients.py +0 -2
  76. pygeai/gam/clients.py +1 -3
  77. pygeai/health/clients.py +1 -3
  78. pygeai/lab/clients.py +0 -1
  79. pygeai/lab/managers.py +0 -1
  80. pygeai/lab/models.py +0 -1
  81. pygeai/lab/strategies/clients.py +1 -2
  82. pygeai/lab/tools/clients.py +2 -2
  83. pygeai/lab/tools/mappers.py +1 -1
  84. pygeai/migration/strategies.py +5 -6
  85. pygeai/migration/tools.py +1 -1
  86. pygeai/organization/clients.py +118 -12
  87. pygeai/organization/endpoints.py +1 -0
  88. pygeai/organization/limits/clients.py +4 -6
  89. pygeai/organization/limits/managers.py +1 -4
  90. pygeai/organization/managers.py +2 -2
  91. pygeai/proxy/config.py +1 -0
  92. pygeai/proxy/managers.py +6 -5
  93. pygeai/tests/admin/test_clients.py +11 -11
  94. pygeai/tests/assistants/rag/test_clients.py +1 -1
  95. pygeai/tests/assistants/rag/test_models.py +1 -2
  96. pygeai/tests/assistants/test_clients.py +1 -1
  97. pygeai/tests/assistants/test_managers.py +1 -3
  98. pygeai/tests/auth/test_cli_configuration.py +252 -0
  99. pygeai/tests/auth/test_client_initialization.py +411 -0
  100. pygeai/tests/auth/test_clients.py +29 -27
  101. pygeai/tests/auth/test_config_manager.py +305 -0
  102. pygeai/tests/auth/test_header_injection.py +294 -0
  103. pygeai/tests/auth/test_oauth.py +3 -1
  104. pygeai/tests/auth/test_session_logging.py +119 -0
  105. pygeai/tests/auth/test_session_validation.py +408 -0
  106. pygeai/tests/auth/test_singleton_reset.py +201 -0
  107. pygeai/tests/chat/test_clients.py +1 -1
  108. pygeai/tests/chat/test_iris.py +1 -1
  109. pygeai/tests/chat/test_ui.py +0 -2
  110. pygeai/tests/cli/commands/lab/test_ai_lab.py +1 -3
  111. pygeai/tests/cli/commands/lab/test_common.py +0 -1
  112. pygeai/tests/cli/commands/test_chat.py +1 -1
  113. pygeai/tests/cli/commands/test_common.py +0 -1
  114. pygeai/tests/cli/commands/test_embeddings.py +2 -2
  115. pygeai/tests/cli/commands/test_evaluation.py +1 -9
  116. pygeai/tests/cli/commands/test_llm.py +1 -1
  117. pygeai/tests/cli/commands/test_migrate.py +1 -1
  118. pygeai/tests/cli/commands/test_rerank.py +0 -1
  119. pygeai/tests/cli/commands/test_secrets.py +1 -1
  120. pygeai/tests/cli/commands/test_show_help.py +0 -1
  121. pygeai/tests/cli/commands/test_validators.py +0 -1
  122. pygeai/tests/cli/test_credentials_flag.py +312 -0
  123. pygeai/tests/cli/test_error_handler.py +0 -1
  124. pygeai/tests/core/base/test_mappers.py +2 -2
  125. pygeai/tests/core/base/test_models.py +4 -4
  126. pygeai/tests/core/common/test_config.py +2 -7
  127. pygeai/tests/core/common/test_decorators.py +0 -1
  128. pygeai/tests/core/embeddings/test_managers.py +1 -1
  129. pygeai/tests/core/feedback/test_clients.py +2 -2
  130. pygeai/tests/core/files/test_clients.py +6 -6
  131. pygeai/tests/core/files/test_models.py +0 -1
  132. pygeai/tests/core/files/test_responses.py +0 -1
  133. pygeai/tests/core/llm/test_clients.py +1 -1
  134. pygeai/tests/core/plugins/test_clients.py +4 -4
  135. pygeai/tests/core/rerank/test_mappers.py +1 -3
  136. pygeai/tests/core/secrets/test_clients.py +2 -3
  137. pygeai/tests/core/services/test_rest.py +10 -10
  138. pygeai/tests/core/utils/test_console.py +0 -1
  139. pygeai/tests/dbg/test_debugger.py +95 -8
  140. pygeai/tests/evaluation/dataset/test_clients.py +24 -27
  141. pygeai/tests/evaluation/plan/test_clients.py +16 -18
  142. pygeai/tests/evaluation/result/test_clients.py +4 -5
  143. pygeai/tests/health/test_clients.py +2 -2
  144. pygeai/tests/integration/lab/agents/test_create_agent.py +1 -3
  145. pygeai/tests/integration/lab/agents/test_get_agent.py +1 -1
  146. pygeai/tests/integration/lab/processes/test_create_process.py +2 -2
  147. pygeai/tests/integration/lab/processes/test_create_task.py +2 -3
  148. pygeai/tests/integration/lab/processes/test_delete_process.py +0 -1
  149. pygeai/tests/integration/lab/processes/test_get_process.py +2 -4
  150. pygeai/tests/integration/lab/processes/test_list_process_instances.py +1 -3
  151. pygeai/tests/integration/lab/processes/test_update_process.py +3 -9
  152. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +1 -2
  153. pygeai/tests/integration/lab/tools/test_delete_tool.py +1 -1
  154. pygeai/tests/integration/lab/tools/test_list_tools.py +1 -1
  155. pygeai/tests/integration/lab/tools/test_update_tool.py +1 -1
  156. pygeai/tests/lab/agents/test_clients.py +17 -17
  157. pygeai/tests/lab/processes/test_clients.py +67 -67
  158. pygeai/tests/lab/processes/test_mappers.py +23 -23
  159. pygeai/tests/lab/spec/test_loader.py +0 -2
  160. pygeai/tests/lab/spec/test_parsers.py +1 -2
  161. pygeai/tests/lab/strategies/test_clients.py +10 -10
  162. pygeai/tests/lab/test_managers.py +3 -5
  163. pygeai/tests/lab/test_mappers.py +1 -4
  164. pygeai/tests/lab/tools/test_clients.py +21 -21
  165. pygeai/tests/lab/tools/test_mappers.py +0 -1
  166. pygeai/tests/organization/limits/test_clients.py +33 -33
  167. pygeai/tests/organization/limits/test_managers.py +7 -7
  168. pygeai/tests/organization/test_clients.py +78 -60
  169. pygeai/tests/proxy/test_clients.py +1 -1
  170. pygeai/tests/proxy/test_integration.py +1 -4
  171. pygeai/tests/proxy/test_managers.py +1 -2
  172. pygeai/tests/proxy/test_servers.py +1 -2
  173. pygeai/tests/snippets/assistants/rag/delete_rag_assistant.py +0 -1
  174. pygeai/tests/snippets/assistants/rag/get_documents.py +0 -1
  175. pygeai/tests/snippets/assistants/rag/get_rag_assistant_data.py +0 -1
  176. pygeai/tests/snippets/chat/get_request_status.py +0 -1
  177. pygeai/tests/snippets/dbg/file_debugging.py +72 -0
  178. pygeai/tests/snippets/dbg/module_debugging.py +60 -0
  179. pygeai/tests/snippets/embeddings/cohere_example.py +2 -2
  180. pygeai/tests/snippets/embeddings/openai_base64_example.py +1 -1
  181. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +8 -8
  182. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +5 -5
  183. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +3 -3
  184. pygeai/tests/snippets/lab/agentic_flow_example_1.py +1 -1
  185. pygeai/tests/snippets/lab/agentic_flow_example_2.py +3 -4
  186. pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +2 -2
  187. pygeai/tests/snippets/lab/agents/delete_agent.py +1 -2
  188. pygeai/tests/snippets/lab/agents/get_agent.py +1 -1
  189. pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +10 -10
  190. pygeai/tests/snippets/lab/agents/get_sharing_link.py +0 -1
  191. pygeai/tests/snippets/lab/agents/list_agents.py +1 -1
  192. pygeai/tests/snippets/lab/agents/publish_agent_revision.py +0 -1
  193. pygeai/tests/snippets/lab/agents/update_agent_properties.py +1 -1
  194. pygeai/tests/snippets/lab/crud_ui.py +3 -5
  195. pygeai/tests/snippets/lab/processes/kbs/get_kb.py +0 -1
  196. pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +0 -1
  197. pygeai/tests/snippets/lab/processes/list_processes.py +1 -1
  198. pygeai/tests/snippets/lab/samples/summarize_files.py +0 -3
  199. pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +0 -1
  200. pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +1 -1
  201. pygeai/tests/snippets/lab/tools/get_tool.py +1 -1
  202. pygeai/tests/snippets/lab/tools/publish_tool_revision.py +0 -1
  203. pygeai/tests/snippets/lab/tools/set_parameters.py +1 -2
  204. pygeai/tests/snippets/lab/use_cases/c_code_fixer_agent_flow.py +2 -3
  205. pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +1 -1
  206. pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +0 -1
  207. pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +0 -1
  208. pygeai/tests/snippets/lab/use_cases/update_web_designer.py +0 -1
  209. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +0 -1
  210. pygeai/tests/snippets/migrate/orchestrator_examples.py +1 -1
  211. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/METADATA +32 -7
  212. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/RECORD +216 -205
  213. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/WHEEL +0 -0
  214. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/entry_points.txt +0 -0
  215. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/licenses/LICENSE +0 -0
  216. {pygeai-0.6.0b14.dist-info → pygeai-0.7.0b1.dist-info}/top_level.txt +0 -0
@@ -19,16 +19,12 @@ def show_help():
19
19
 
20
20
 
21
21
  def list_assistants(option_list: list):
22
- organization_id = None
23
- project_id = None
24
- for option_flag, option_arg in option_list:
25
- if option_flag.name == "organization_id":
26
- organization_id = option_arg
27
- if option_flag.name == "project_id":
28
- project_id = option_arg
22
+ opts = {opt.name: arg for opt, arg in option_list}
23
+ organization_id = opts.get("organization_id")
24
+ project_id = opts.get("project_id")
29
25
 
30
- if not organization_id and project_id:
31
- raise MissingRequirementException("Organization ID and Project ID are required.")
26
+ if not organization_id and project_id:
27
+ raise MissingRequirementException("Organization ID and Project ID are required.")
32
28
 
33
29
  client = PluginClient()
34
30
  result = client.list_assistants(organization_id=organization_id, project_id=project_id)
@@ -53,13 +49,9 @@ assistants_list_options = [
53
49
 
54
50
 
55
51
  def get_project_list(option_list: list):
56
- detail = "summary"
57
- name = None
58
- for option_flag, option_arg in option_list:
59
- if option_flag.name == "detail":
60
- detail = option_arg
61
- if option_flag.name == "name":
62
- name = option_arg
52
+ opts = {opt.name: arg for opt, arg in option_list}
53
+ detail = opts.get("detail", "summary")
54
+ name = opts.get("name")
63
55
 
64
56
  client = OrganizationClient()
65
57
  result = client.get_project_list(detail, name)
@@ -73,10 +65,8 @@ project_list_options = [
73
65
 
74
66
 
75
67
  def get_project_detail(option_list: list):
76
- project_id = None
77
- for option_flag, option_arg in option_list:
78
- if option_flag.name == "project_id":
79
- project_id = option_arg
68
+ opts = {opt.name: arg for opt, arg in option_list}
69
+ project_id = opts.get("project_id")
80
70
 
81
71
  if not project_id:
82
72
  raise MissingRequirementException("Cannot retrieve project detail without project-id")
@@ -92,41 +82,17 @@ project_detail_options = [
92
82
 
93
83
 
94
84
  def create_project(option_list: list):
95
- name = None
96
- email = None
97
- description = None
98
- subscription_type = None
99
- usage_unit = None
100
- soft_limit = None
101
- hard_limit = None
102
- renewal_status = None
85
+ opts = {opt.name: arg for opt, arg in option_list}
86
+ name = opts.get("name")
87
+ email = opts.get("admin_email")
88
+ description = opts.get("description")
89
+ subscription_type = opts.get("subscription_type")
90
+ usage_unit = opts.get("usage_unit")
91
+ soft_limit = opts.get("soft_limit")
92
+ hard_limit = opts.get("hard_limit")
93
+ renewal_status = opts.get("renewal_status")
94
+
103
95
  usage_limit = {}
104
-
105
- for option_flag, option_arg in option_list:
106
- if option_flag.name == "name":
107
- name = option_arg
108
-
109
- if option_flag.name == "description":
110
- description = option_arg
111
-
112
- if option_flag.name == "admin_email":
113
- email = option_arg
114
-
115
- if option_flag.name == "subscription_type":
116
- subscription_type = option_arg
117
-
118
- if option_flag.name == "usage_unit":
119
- usage_unit = option_arg
120
-
121
- if option_flag.name == "soft_limit":
122
- soft_limit = option_arg
123
-
124
- if option_flag.name == "hard_limit":
125
- hard_limit = option_arg
126
-
127
- if option_flag.name == "renewal_status":
128
- renewal_status = option_arg
129
-
130
96
  if subscription_type or usage_unit or soft_limit or hard_limit or renewal_status:
131
97
  usage_limit.update({
132
98
  "subscriptionType": subscription_type,
@@ -172,18 +138,10 @@ create_project_options = [
172
138
 
173
139
 
174
140
  def update_project(option_list: list):
175
- project_id = None
176
- name = None
177
- description = None
178
- for option_flag, option_arg in option_list:
179
- if option_flag.name == "project_id":
180
- project_id = option_arg
181
-
182
- if option_flag.name == "name":
183
- name = option_arg
184
-
185
- if option_flag.name == "description":
186
- description = option_arg
141
+ opts = {opt.name: arg for opt, arg in option_list}
142
+ project_id = opts.get("project_id")
143
+ name = opts.get("name")
144
+ description = opts.get("description")
187
145
 
188
146
  if not (project_id and name):
189
147
  raise MissingRequirementException("Cannot update project without project-id and/or name")
@@ -201,10 +159,8 @@ update_project_options = [
201
159
 
202
160
 
203
161
  def delete_project(option_list: list):
204
- project_id = None
205
- for option_flag, option_arg in option_list:
206
- if option_flag.name == "project_id":
207
- project_id = option_arg
162
+ opts = {opt.name: arg for opt, arg in option_list}
163
+ project_id = opts.get("project_id")
208
164
 
209
165
  if not project_id:
210
166
  raise MissingRequirementException("Cannot delete project without project-id")
@@ -220,10 +176,8 @@ delete_project_options = [
220
176
 
221
177
 
222
178
  def get_project_tokens(option_list: list):
223
- project_id = None
224
- for option_flag, option_arg in option_list:
225
- if option_flag.name == "project_id":
226
- project_id = option_arg
179
+ opts = {opt.name: arg for opt, arg in option_list}
180
+ project_id = opts.get("project_id")
227
181
 
228
182
  if not project_id:
229
183
  raise MissingRequirementException("Cannot retrieve project tokens without project-id")
@@ -239,22 +193,11 @@ get_project_tokens_options = [
239
193
 
240
194
 
241
195
  def export_request_data(option_list: list):
242
- assistant_name = None
243
- status = None
244
- skip = 0
245
- count = 0
246
- for option_flag, option_arg in option_list:
247
- if option_flag.name == "assistant_name":
248
- assistant_name = option_arg
249
-
250
- if option_flag.name == "status":
251
- status = option_arg
252
-
253
- if option_flag.name == "skip":
254
- skip = option_arg
255
-
256
- if option_flag.name == "count":
257
- count = option_arg
196
+ opts = {opt.name: arg for opt, arg in option_list}
197
+ assistant_name = opts.get("assistant_name")
198
+ status = opts.get("status")
199
+ skip = opts.get("skip", 0)
200
+ count = opts.get("count", 0)
258
201
 
259
202
  client = OrganizationClient()
260
203
  result = client.export_request_data(assistant_name, status, skip, count)
@@ -290,26 +233,13 @@ export_request_data_options = [
290
233
 
291
234
 
292
235
  def get_memberships(option_list: list):
293
- email = None
294
- start_page = 1
295
- page_size = 20
296
- order_key = None
297
- order_direction = "desc"
298
- role_types = None
299
-
300
- for option_flag, option_arg in option_list:
301
- if option_flag.name == "email":
302
- email = option_arg
303
- if option_flag.name == "start_page":
304
- start_page = int(option_arg)
305
- if option_flag.name == "page_size":
306
- page_size = int(option_arg)
307
- if option_flag.name == "order_key":
308
- order_key = option_arg
309
- if option_flag.name == "order_direction":
310
- order_direction = option_arg
311
- if option_flag.name == "role_types":
312
- role_types = option_arg
236
+ opts = {opt.name: arg for opt, arg in option_list}
237
+ email = opts.get("email")
238
+ start_page = int(opts.get("start_page", 1))
239
+ page_size = int(opts.get("page_size", 20))
240
+ order_key = opts.get("order_key")
241
+ order_direction = opts.get("order_direction", "desc")
242
+ role_types = opts.get("role_types")
313
243
 
314
244
  client = OrganizationClient()
315
245
  result = client.get_memberships(email, start_page, page_size, order_key, order_direction, role_types)
@@ -357,26 +287,13 @@ get_memberships_options = [
357
287
 
358
288
 
359
289
  def get_project_memberships(option_list: list):
360
- email = None
361
- start_page = 1
362
- page_size = 20
363
- order_key = None
364
- order_direction = "desc"
365
- role_types = None
366
-
367
- for option_flag, option_arg in option_list:
368
- if option_flag.name == "email":
369
- email = option_arg
370
- if option_flag.name == "start_page":
371
- start_page = int(option_arg)
372
- if option_flag.name == "page_size":
373
- page_size = int(option_arg)
374
- if option_flag.name == "order_key":
375
- order_key = option_arg
376
- if option_flag.name == "order_direction":
377
- order_direction = option_arg
378
- if option_flag.name == "role_types":
379
- role_types = option_arg
290
+ opts = {opt.name: arg for opt, arg in option_list}
291
+ email = opts.get("email")
292
+ start_page = int(opts.get("start_page", 1))
293
+ page_size = int(opts.get("page_size", 20))
294
+ order_key = opts.get("order_key")
295
+ order_direction = opts.get("order_direction", "desc")
296
+ role_types = opts.get("role_types")
380
297
 
381
298
  client = OrganizationClient()
382
299
  result = client.get_project_memberships(email, start_page, page_size, order_key, order_direction, role_types)
@@ -424,54 +341,123 @@ get_project_memberships_options = [
424
341
 
425
342
 
426
343
  def get_project_roles(option_list: list):
427
- project_id = None
428
- for option_flag, option_arg in option_list:
429
- if option_flag.name == "project_id":
430
- project_id = option_arg
344
+ opts = {opt.name: arg for opt, arg in option_list}
345
+ project_id = opts.get("project_id")
346
+ start_page = int(opts.get("start_page", 1))
347
+ page_size = int(opts.get("page_size", 20))
348
+ order_key = opts.get("order_key")
349
+ order_direction = opts.get("order_direction", "desc")
350
+ role_types = opts.get("role_types")
431
351
 
432
352
  if not project_id:
433
353
  raise MissingRequirementException("Cannot retrieve project roles without project-id")
434
354
 
435
355
  client = OrganizationClient()
436
- result = client.get_project_roles(project_id)
356
+ result = client.get_project_roles(project_id, start_page, page_size, order_key, order_direction, role_types)
437
357
  Console.write_stdout(f"Project roles: \n{result}")
438
358
 
439
359
 
440
360
  get_project_roles_options = [
441
361
  PROJECT_ID_OPTION,
362
+ Option(
363
+ "start_page",
364
+ ["--start-page"],
365
+ "Page number for pagination (default: 1)",
366
+ True
367
+ ),
368
+ Option(
369
+ "page_size",
370
+ ["--page-size"],
371
+ "Number of items per page (default: 20)",
372
+ True
373
+ ),
374
+ Option(
375
+ "order_key",
376
+ ["--order-key"],
377
+ "Field for sorting (only 'name' supported)",
378
+ True
379
+ ),
380
+ Option(
381
+ "order_direction",
382
+ ["--order-direction"],
383
+ "Sort direction: asc or desc (default: desc)",
384
+ True
385
+ ),
386
+ Option(
387
+ "role_types",
388
+ ["--role-types"],
389
+ "Comma-separated list: backend, frontend (optional, case-insensitive)",
390
+ True
391
+ ),
442
392
  ]
443
393
 
444
394
 
445
395
  def get_project_members(option_list: list):
446
- project_id = None
447
- for option_flag, option_arg in option_list:
448
- if option_flag.name == "project_id":
449
- project_id = option_arg
396
+ opts = {opt.name: arg for opt, arg in option_list}
397
+ project_id = opts.get("project_id")
398
+ start_page = int(opts.get("start_page", 1))
399
+ page_size = int(opts.get("page_size", 20))
400
+ order_key = opts.get("order_key")
401
+ order_direction = opts.get("order_direction", "desc")
402
+ role_types = opts.get("role_types")
450
403
 
451
404
  if not project_id:
452
405
  raise MissingRequirementException("Cannot retrieve project members without project-id")
453
406
 
454
407
  client = OrganizationClient()
455
- result = client.get_project_members(project_id)
408
+ result = client.get_project_members(project_id, start_page, page_size, order_key, order_direction, role_types)
456
409
  Console.write_stdout(f"Project members: \n{result}")
457
410
 
458
411
 
459
412
  get_project_members_options = [
460
413
  PROJECT_ID_OPTION,
414
+ Option(
415
+ "start_page",
416
+ ["--start-page"],
417
+ "Page number for pagination (default: 1)",
418
+ True
419
+ ),
420
+ Option(
421
+ "page_size",
422
+ ["--page-size"],
423
+ "Number of items per page (default: 20)",
424
+ True
425
+ ),
426
+ Option(
427
+ "order_key",
428
+ ["--order-key"],
429
+ "Field for sorting (only 'name' supported)",
430
+ True
431
+ ),
432
+ Option(
433
+ "order_direction",
434
+ ["--order-direction"],
435
+ "Sort direction: asc or desc (default: desc)",
436
+ True
437
+ ),
438
+ Option(
439
+ "role_types",
440
+ ["--role-types"],
441
+ "Comma-separated list: backend, frontend (optional, case-insensitive)",
442
+ True
443
+ ),
461
444
  ]
462
445
 
463
446
 
464
447
  def get_organization_members(option_list: list):
465
- organization_id = None
466
- for option_flag, option_arg in option_list:
467
- if option_flag.name == "organization_id":
468
- organization_id = option_arg
448
+ opts = {opt.name: arg for opt, arg in option_list}
449
+ organization_id = opts.get("organization_id")
450
+ start_page = int(opts.get("start_page", 1))
451
+ page_size = int(opts.get("page_size", 20))
452
+ order_key = opts.get("order_key")
453
+ order_direction = opts.get("order_direction", "desc")
454
+ role_types = opts.get("role_types")
469
455
 
470
456
  if not organization_id:
471
457
  raise MissingRequirementException("Cannot retrieve organization members without organization-id")
472
458
 
473
459
  client = OrganizationClient()
474
- result = client.get_organization_members(organization_id)
460
+ result = client.get_organization_members(organization_id, start_page, page_size, order_key, order_direction, role_types)
475
461
  Console.write_stdout(f"Organization members: \n{result}")
476
462
 
477
463
 
@@ -482,24 +468,68 @@ get_organization_members_options = [
482
468
  "GUID of the organization (required)",
483
469
  True
484
470
  ),
471
+ Option(
472
+ "start_page",
473
+ ["--start-page"],
474
+ "Page number for pagination (default: 1)",
475
+ True
476
+ ),
477
+ Option(
478
+ "page_size",
479
+ ["--page-size"],
480
+ "Number of items per page (default: 20)",
481
+ True
482
+ ),
483
+ Option(
484
+ "order_key",
485
+ ["--order-key"],
486
+ "Field for sorting (only 'email' supported)",
487
+ True
488
+ ),
489
+ Option(
490
+ "order_direction",
491
+ ["--order-direction"],
492
+ "Sort direction: asc or desc (default: desc)",
493
+ True
494
+ ),
495
+ Option(
496
+ "role_types",
497
+ ["--role-types"],
498
+ "Comma-separated list: backend (only for organizations, case-insensitive)",
499
+ True
500
+ ),
501
+ ]
502
+
503
+
504
+ def get_runtime_policies(option_list: list):
505
+ opts = {opt.name: arg for opt, arg in option_list}
506
+ organization_id = opts.get("organization_id")
507
+
508
+ client = OrganizationClient()
509
+ result = client.get_runtime_policies(organization_id)
510
+ Console.write_stdout(f"Plugin runtime policies: \n{result}")
511
+
512
+
513
+ get_runtime_policies_options = [
514
+ Option(
515
+ "organization_id",
516
+ ["--organization-id", "--oid"],
517
+ "GUID of the organization (optional, defaults to token's organization)",
518
+ True
519
+ ),
485
520
  ]
486
521
 
487
522
 
488
523
  def add_project_member(option_list: list):
489
- project_id = None
490
- user_email = None
524
+ opts = {opt.name: arg for opt, arg in option_list}
525
+ project_id = opts.get("project_id")
526
+ user_email = opts.get("user_email")
527
+ batch_file = opts.get("batch_file")
528
+
491
529
  roles = []
492
- batch_file = None
493
-
494
- for option_flag, option_arg in option_list:
495
- if option_flag.name == "project_id":
496
- project_id = option_arg
497
- if option_flag.name == "user_email":
498
- user_email = option_arg
499
- if option_flag.name == "roles":
500
- roles = [r.strip() for r in option_arg.split(",")]
501
- if option_flag.name == "batch_file":
502
- batch_file = option_arg
530
+ roles_arg = opts.get("roles")
531
+ if roles_arg:
532
+ roles = [r.strip() for r in roles_arg.split(",")]
503
533
 
504
534
  client = OrganizationClient()
505
535
 
@@ -589,15 +619,9 @@ add_project_member_options = [
589
619
 
590
620
 
591
621
  def create_organization(option_list: list):
592
- name = None
593
- email = None
594
-
595
- for option_flag, option_arg in option_list:
596
- if option_flag.name == "name":
597
- name = option_arg
598
-
599
- if option_flag.name == "admin_email":
600
- email = option_arg
622
+ opts = {opt.name: arg for opt, arg in option_list}
623
+ name = opts.get("name")
624
+ email = opts.get("admin_email")
601
625
 
602
626
  if not (name and email):
603
627
  raise MissingRequirementException("Cannot create organization without name and administrator's email")
@@ -624,26 +648,22 @@ create_organization_options = [
624
648
 
625
649
 
626
650
  def get_organization_list(option_list: list):
651
+ opts = {opt.name: arg for opt, arg in option_list}
652
+ order_direction = opts.get("order_direction", "desc")
653
+
627
654
  start_page = None
655
+ start_page_arg = opts.get("start_page")
656
+ if start_page_arg:
657
+ start_page = int(start_page_arg)
658
+
628
659
  page_size = None
629
- order_key = None
630
- order_direction = "desc"
631
- filter_key = None
632
- filter_value = None
633
-
634
- for option_flag, option_arg in option_list:
635
- if option_flag.name == "start_page":
636
- start_page = int(option_arg)
637
- if option_flag.name == "page_size":
638
- page_size = int(option_arg)
639
- if option_flag.name == "order_key":
640
- order_key = option_arg
641
- if option_flag.name == "order_direction":
642
- order_direction = option_arg
643
- if option_flag.name == "filter_key":
644
- filter_key = option_arg
645
- if option_flag.name == "filter_value":
646
- filter_value = option_arg
660
+ page_size_arg = opts.get("page_size")
661
+ if page_size_arg:
662
+ page_size = int(page_size_arg)
663
+
664
+ order_key = opts.get("order_key")
665
+ filter_key = opts.get("filter_key")
666
+ filter_value = opts.get("filter_value")
647
667
 
648
668
  client = OrganizationClient()
649
669
  result = client.get_organization_list(start_page, page_size, order_key, order_direction, filter_key, filter_value)
@@ -691,10 +711,8 @@ get_organization_list_options = [
691
711
 
692
712
 
693
713
  def delete_organization(option_list: list):
694
- organization_id = None
695
- for option_flag, option_arg in option_list:
696
- if option_flag.name == "organization_id":
697
- organization_id = option_arg
714
+ opts = {opt.name: arg for opt, arg in option_list}
715
+ organization_id = opts.get("organization_id")
698
716
 
699
717
  if not organization_id:
700
718
  raise MissingRequirementException("Cannot delete organization without organization-id")
@@ -840,12 +858,21 @@ organization_commands = [
840
858
  [],
841
859
  get_organization_members_options
842
860
  ),
861
+ Command(
862
+ "get_runtime_policies",
863
+ ["get-runtime-policies"],
864
+ "Get runtime policies for a plugin",
865
+ get_runtime_policies,
866
+ ArgumentsEnum.OPTIONAL,
867
+ [],
868
+ get_runtime_policies_options
869
+ ),
843
870
  Command(
844
871
  "add_project_member",
845
- ["add-project-member", "apm"],
846
- "Add a user to a project by sending an invitation email",
872
+ ["add-project-member"],
873
+ "Add a member to a project (single or batch)",
847
874
  add_project_member,
848
- ArgumentsEnum.REQUIRED,
875
+ ArgumentsEnum.OPTIONAL,
849
876
  [],
850
877
  add_project_member_options
851
878
  ),
@@ -859,9 +886,9 @@ organization_commands = [
859
886
  create_organization_options
860
887
  ),
861
888
  Command(
862
- "organization_list",
863
- ["list-organizations"],
864
- "List organization information",
889
+ "get_organization_list",
890
+ ["get-organization-list"],
891
+ "Get organization list",
865
892
  get_organization_list,
866
893
  ArgumentsEnum.OPTIONAL,
867
894
  [],
@@ -870,7 +897,7 @@ organization_commands = [
870
897
  Command(
871
898
  "delete_organization",
872
899
  ["delete-organization"],
873
- "Delete existing organization",
900
+ "Delete organization",
874
901
  delete_organization,
875
902
  ArgumentsEnum.REQUIRED,
876
903
  [],