pyegeria 5.4.0.28__py3-none-any.whl → 5.5.3.3__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.

Potentially problematic release.


This version of pyegeria might be problematic. Click here for more details.

Files changed (433) hide show
  1. commands/__init__.py +24 -0
  2. commands/cat/Dr-Egeria_md-orig.py +2 -2
  3. commands/cat/collection_actions.py +197 -0
  4. commands/cat/dr_egeria_command_help.py +137 -38
  5. commands/cat/dr_egeria_jupyter.py +7 -7
  6. commands/cat/dr_egeria_md.py +10 -267
  7. commands/cat/exp_list_glossaries.py +11 -14
  8. commands/cat/get_asset_graph.py +37 -267
  9. commands/cat/{get_collection.py → get_collection_tree.py} +10 -18
  10. commands/cat/get_project_dependencies.py +14 -14
  11. commands/cat/get_project_structure.py +15 -14
  12. commands/cat/get_tech_type_elements.py +16 -116
  13. commands/cat/glossary_actions.py +145 -298
  14. commands/cat/list_assets.py +3 -11
  15. commands/cat/list_cert_types.py +17 -63
  16. commands/cat/list_collections.py +17 -139
  17. commands/cat/list_deployed_catalogs.py +15 -27
  18. commands/cat/list_deployed_database_schemas.py +27 -43
  19. commands/cat/list_deployed_databases.py +16 -31
  20. commands/cat/list_deployed_servers.py +35 -54
  21. commands/cat/list_glossaries.py +18 -17
  22. commands/cat/list_projects.py +10 -12
  23. commands/cat/list_tech_type_elements.py +21 -37
  24. commands/cat/list_tech_types.py +13 -25
  25. commands/cat/list_terms.py +38 -79
  26. commands/cat/list_todos.py +4 -11
  27. commands/cat/list_user_ids.py +3 -10
  28. commands/cat/my_reports.py +559 -0
  29. commands/cat/run_report.py +394 -0
  30. commands/cat/{list_format_set.py → run_report_orig.py} +136 -44
  31. commands/cli/egeria.py +182 -219
  32. commands/cli/egeria_cat.py +32 -59
  33. commands/cli/egeria_my.py +13 -0
  34. commands/cli/egeria_ops.py +69 -74
  35. commands/cli/egeria_tech.py +17 -93
  36. commands/{cat → deprecated}/list_data_designer.py +2 -4
  37. commands/{cat → deprecated}/list_data_structures_full.py +3 -6
  38. commands/deprecated/old_get_asset_graph.py +315 -0
  39. commands/my/__init__.py +0 -2
  40. commands/my/list_my_profile.py +27 -34
  41. commands/my/list_my_roles.py +1 -7
  42. commands/my/monitor_my_todos.py +1 -7
  43. commands/my/monitor_open_todos.py +6 -7
  44. commands/my/todo_actions.py +4 -5
  45. commands/ops/__init__.py +0 -2
  46. commands/ops/gov_server_actions.py +17 -21
  47. commands/ops/list_archives.py +17 -38
  48. commands/ops/list_catalog_targets.py +33 -40
  49. commands/ops/load_archive.py +14 -11
  50. commands/ops/{monitor_engine_activity_c.py → monitor_active_engine_activity.py} +51 -82
  51. commands/ops/{monitor_integ_daemon_status.py → monitor_daemon_status.py} +35 -55
  52. commands/ops/monitor_engine_activity.py +79 -77
  53. commands/ops/{monitor_gov_eng_status.py → monitor_engine_status.py} +10 -7
  54. commands/ops/monitor_platform_status.py +38 -50
  55. commands/ops/monitor_server_startup.py +6 -11
  56. commands/ops/monitor_server_status.py +7 -11
  57. commands/ops/orig_monitor_server_list.py +8 -8
  58. commands/ops/orig_monitor_server_status.py +1 -5
  59. commands/ops/refresh_integration_daemon.py +5 -5
  60. commands/ops/restart_integration_daemon.py +5 -5
  61. commands/ops/table_integ_daemon_status.py +6 -6
  62. commands/ops/x_engine_actions.py +7 -7
  63. commands/tech/__init__.py +0 -2
  64. commands/tech/{generic_actions.py → element_actions.py} +6 -11
  65. commands/tech/get_element_info.py +20 -29
  66. commands/tech/get_guid_info.py +23 -42
  67. commands/tech/get_tech_details.py +20 -35
  68. commands/tech/get_tech_type_template.py +28 -39
  69. commands/tech/list_all_om_type_elements.py +24 -30
  70. commands/tech/list_all_om_type_elements_x.py +22 -28
  71. commands/tech/list_all_related_elements.py +19 -28
  72. commands/tech/list_anchored_elements.py +22 -30
  73. commands/tech/list_asset_types.py +19 -24
  74. commands/tech/list_elements_by_classification_by_property_value.py +26 -32
  75. commands/tech/list_elements_by_property_value.py +19 -25
  76. commands/tech/list_elements_by_property_value_x.py +20 -28
  77. commands/tech/list_elements_for_classification.py +28 -41
  78. commands/tech/list_gov_action_processes.py +16 -27
  79. commands/tech/list_information_supply_chains.py +22 -30
  80. commands/tech/list_registered_services.py +14 -26
  81. commands/tech/list_related_elements_with_prop_value.py +15 -25
  82. commands/tech/list_related_specification.py +1 -4
  83. commands/tech/list_relationship_types.py +15 -25
  84. commands/tech/list_relationships.py +20 -36
  85. commands/tech/list_solution_blueprints.py +28 -33
  86. commands/tech/list_solution_components.py +23 -29
  87. commands/tech/list_solution_roles.py +21 -32
  88. commands/tech/list_tech_templates.py +51 -54
  89. commands/tech/list_valid_metadata_values.py +5 -9
  90. commands/tech/table_tech_templates.py +2 -6
  91. commands/tech/x_list_related_elements.py +1 -4
  92. examples/GeoSpatial Products Example.py +524 -0
  93. examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
  94. examples/Jupyter Notebooks/README.md +2 -0
  95. examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
  96. examples/Jupyter Notebooks/common/__init__.py +14 -0
  97. examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
  98. examples/Jupyter Notebooks/common/environment-check.ipynb +52 -0
  99. examples/Jupyter Notebooks/common/globals.ipynb +184 -0
  100. examples/Jupyter Notebooks/common/globals.py +154 -0
  101. examples/Jupyter Notebooks/common/orig_globals.py +152 -0
  102. examples/format_sets/all_format_sets.json +910 -0
  103. examples/format_sets/custom_format_sets.json +268 -0
  104. examples/format_sets/subset_format_sets.json +187 -0
  105. examples/format_sets_save_load_example.py +291 -0
  106. examples/jacquard_data_sets.py +129 -0
  107. examples/output_formats_example.py +193 -0
  108. examples/test_jacquard_data_sets.py +54 -0
  109. examples/test_jacquard_data_sets_scenarios.py +94 -0
  110. md_processing/__init__.py +33 -24
  111. md_processing/command_dispatcher.py +33 -0
  112. md_processing/command_mapping.py +221 -0
  113. md_processing/data/commands/commands_data_designer.json +537 -0
  114. md_processing/data/commands/commands_external_reference.json +733 -0
  115. md_processing/data/commands/commands_feedback.json +155 -0
  116. md_processing/data/commands/commands_general.json +204 -0
  117. md_processing/data/commands/commands_glossary.json +218 -0
  118. md_processing/data/commands/commands_governance.json +3678 -0
  119. md_processing/data/commands/commands_product_manager.json +865 -0
  120. md_processing/data/commands/commands_project.json +642 -0
  121. md_processing/data/commands/commands_solution_architect.json +366 -0
  122. md_processing/data/commands.json +6489 -30060
  123. md_processing/data/{commands-working.json → commands_working.json} +9304 -13513
  124. md_processing/data/gened_report_specs.py +6584 -0
  125. md_processing/data/generated_format_sets.json +6533 -0
  126. md_processing/data/generated_format_sets_old.json +4137 -0
  127. md_processing/data/generated_format_sets_old.py +45 -0
  128. md_processing/dr_egeria.py +182 -0
  129. md_processing/md_commands/data_designer_commands.py +195 -583
  130. md_processing/md_commands/ext_ref_commands.py +530 -0
  131. md_processing/md_commands/feedback_commands.py +726 -0
  132. md_processing/md_commands/glossary_commands.py +106 -490
  133. md_processing/md_commands/governance_officer_commands.py +129 -18
  134. md_processing/md_commands/product_manager_commands.py +362 -115
  135. md_processing/md_commands/project_commands.py +351 -134
  136. md_processing/md_commands/solution_architect_commands.py +276 -232
  137. md_processing/md_commands/view_commands.py +295 -0
  138. md_processing/md_processing_utils/common_md_proc_utils.py +258 -166
  139. md_processing/md_processing_utils/common_md_utils.py +138 -43
  140. md_processing/md_processing_utils/determine_width.py +103 -0
  141. md_processing/md_processing_utils/extraction_utils.py +100 -39
  142. md_processing/md_processing_utils/gen_report_specs.py +643 -0
  143. md_processing/md_processing_utils/generate_dr_help.py +61 -33
  144. md_processing/md_processing_utils/generate_md_cmd_templates.py +20 -19
  145. md_processing/md_processing_utils/generate_md_templates.py +3 -12
  146. md_processing/md_processing_utils/md_processing_constants.py +1053 -72
  147. pyegeria/__init__.py +203 -158
  148. pyegeria/core/__init__.py +40 -0
  149. pyegeria/core/_base_platform_client.py +574 -0
  150. pyegeria/core/_base_server_client.py +573 -0
  151. pyegeria/{_exceptions_new.py → core/_exceptions.py} +62 -30
  152. pyegeria/{_globals.py → core/_globals.py} +14 -3
  153. pyegeria/core/_server_client.py +6073 -0
  154. pyegeria/{_validators.py → core/_validators.py} +7 -8
  155. pyegeria/core/config.py +654 -0
  156. pyegeria/{create_tech_guid_lists.py → core/create_tech_guid_lists.py} +0 -1
  157. pyegeria/core/load_config.py +37 -0
  158. pyegeria/{logging_configuration.py → core/logging_configuration.py} +1 -1
  159. pyegeria/core/mcp_adapter.py +144 -0
  160. pyegeria/core/mcp_server.py +212 -0
  161. pyegeria/core/utils.py +405 -0
  162. pyegeria/{_client.py → deprecated/_client.py} +24 -25
  163. pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
  164. pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1987 -1877
  165. pyegeria/{output_formatter.py → deprecated/output_formatter_with_machine_keys.py} +298 -45
  166. pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +155 -171
  167. pyegeria/{valid_metadata_omvs.py → deprecated/valid_metadata_omvs.py} +93 -93
  168. pyegeria/{x_action_author_omvs.py → deprecated/x_action_author_omvs.py} +2 -3
  169. pyegeria/egeria_cat_client.py +26 -70
  170. pyegeria/egeria_client.py +130 -93
  171. pyegeria/egeria_config_client.py +40 -46
  172. pyegeria/egeria_tech_client.py +141 -54
  173. pyegeria/models/__init__.py +150 -0
  174. pyegeria/{models.py → models/models.py} +156 -20
  175. pyegeria/omvs/__init__.py +84 -0
  176. pyegeria/omvs/action_author.py +342 -0
  177. pyegeria/omvs/actor_manager.py +5980 -0
  178. pyegeria/omvs/asset_catalog.py +842 -0
  179. pyegeria/omvs/asset_maker.py +2736 -0
  180. pyegeria/omvs/automated_curation.py +4403 -0
  181. pyegeria/omvs/classification_manager.py +11213 -0
  182. pyegeria/{collection_manager.py → omvs/collection_manager.py} +1334 -1160
  183. pyegeria/omvs/community_matters_omvs.py +468 -0
  184. pyegeria/{core_omag_server_config.py → omvs/core_omag_server_config.py} +157 -157
  185. pyegeria/{data_designer.py → omvs/data_designer.py} +1115 -660
  186. pyegeria/omvs/data_discovery.py +869 -0
  187. pyegeria/omvs/data_engineer.py +372 -0
  188. pyegeria/omvs/digital_business.py +1133 -0
  189. pyegeria/omvs/external_links.py +1752 -0
  190. pyegeria/omvs/feedback_manager.py +834 -0
  191. pyegeria/{full_omag_server_config.py → omvs/full_omag_server_config.py} +73 -69
  192. pyegeria/{glossary_manager.py → omvs/glossary_manager.py} +857 -519
  193. pyegeria/{governance_officer.py → omvs/governance_officer.py} +964 -468
  194. pyegeria/omvs/lineage_linker.py +314 -0
  195. pyegeria/omvs/location_arena.py +1525 -0
  196. pyegeria/omvs/metadata_expert.py +668 -0
  197. pyegeria/omvs/metadata_explorer_omvs.py +2943 -0
  198. pyegeria/omvs/my_profile.py +1042 -0
  199. pyegeria/omvs/notification_manager.py +358 -0
  200. pyegeria/omvs/people_organizer.py +394 -0
  201. pyegeria/{platform_services.py → omvs/platform_services.py} +113 -193
  202. pyegeria/omvs/product_manager.py +1825 -0
  203. pyegeria/omvs/project_manager.py +1907 -0
  204. pyegeria/omvs/reference_data.py +1140 -0
  205. pyegeria/omvs/registered_info.py +334 -0
  206. pyegeria/omvs/runtime_manager.py +2817 -0
  207. pyegeria/omvs/schema_maker.py +446 -0
  208. pyegeria/{server_operations.py → omvs/server_operations.py} +27 -26
  209. pyegeria/{solution_architect_omvs.py → omvs/solution_architect.py} +1886 -1505
  210. pyegeria/omvs/specification_properties.py +37 -0
  211. pyegeria/omvs/subject_area.py +1042 -0
  212. pyegeria/omvs/template_manager_omvs.py +236 -0
  213. pyegeria/omvs/time_keeper.py +1761 -0
  214. pyegeria/omvs/valid_metadata.py +3221 -0
  215. pyegeria/omvs/valid_metadata_lists.py +37 -0
  216. pyegeria/omvs/valid_type_lists.py +37 -0
  217. pyegeria/view/__init__.py +28 -0
  218. pyegeria/{_output_format_models.py → view/_output_format_models.py} +160 -24
  219. pyegeria/view/_output_formats.py +14 -0
  220. pyegeria/view/base_report_formats.py +2719 -0
  221. pyegeria/view/dr_egeria_reports.py +56 -0
  222. pyegeria/view/format_set_executor.py +397 -0
  223. pyegeria/{md_processing_utils.py → view/md_processing_utils.py} +5 -5
  224. pyegeria/{mermaid_utilities.py → view/mermaid_utilities.py} +2 -154
  225. pyegeria/view/output_formatter.py +1297 -0
  226. pyegeria-5.5.3.3.dist-info/METADATA +218 -0
  227. pyegeria-5.5.3.3.dist-info/RECORD +241 -0
  228. {pyegeria-5.4.0.28.dist-info → pyegeria-5.5.3.3.dist-info}/WHEEL +2 -1
  229. pyegeria-5.5.3.3.dist-info/entry_points.txt +103 -0
  230. pyegeria-5.5.3.3.dist-info/top_level.txt +4 -0
  231. commands/cat/.DS_Store +0 -0
  232. commands/cat/.env +0 -8
  233. commands/cat/README.md +0 -16
  234. commands/cat/debug_log +0 -1126
  235. commands/cat/debug_log.2025-08-18_11-34-38_088636.zip +0 -0
  236. commands/cat/list_categories.py +0 -192
  237. commands/cat/logs/pyegeria.log +0 -4
  238. commands/cli/debug_log +0 -0
  239. commands/cli/debug_log.log +0 -0
  240. commands/cli/txt_custom_v2.tcss +0 -19
  241. commands/my/README.md +0 -17
  242. commands/ops/README.md +0 -24
  243. commands/ops/logs/pyegeria.log +0 -0
  244. commands/ops/monitor_asset_events.py +0 -108
  245. commands/tech/README.md +0 -24
  246. md_processing/.DS_Store +0 -0
  247. md_processing/dr-egeria-outbox/Collections-2025-08-12-13-30-37.md +0 -163
  248. md_processing/dr-egeria-outbox/Collections-2025-08-12-13-35-58.md +0 -474
  249. md_processing/dr_egeria_inbox/Derive-Dr-Gov-Defs.md +0 -8
  250. md_processing/dr_egeria_inbox/Dr.Egeria Templates.md +0 -873
  251. md_processing/dr_egeria_inbox/arch_test.md +0 -57
  252. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
  253. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
  254. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
  255. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
  256. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
  257. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
  258. md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
  259. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
  260. md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
  261. md_processing/dr_egeria_inbox/cat_test.md +0 -100
  262. md_processing/dr_egeria_inbox/collections.md +0 -39
  263. md_processing/dr_egeria_inbox/data_designer_debug.log +0 -6
  264. md_processing/dr_egeria_inbox/data_designer_out.md +0 -60
  265. md_processing/dr_egeria_inbox/data_designer_search_test.md +0 -11
  266. md_processing/dr_egeria_inbox/data_field.md +0 -54
  267. md_processing/dr_egeria_inbox/data_spec.md +0 -77
  268. md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
  269. md_processing/dr_egeria_inbox/data_test.md +0 -179
  270. md_processing/dr_egeria_inbox/data_test2.md +0 -429
  271. md_processing/dr_egeria_inbox/data_test3.md +0 -462
  272. md_processing/dr_egeria_inbox/dr_egeria_data_designer_1.md +0 -124
  273. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
  274. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
  275. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -318
  276. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
  277. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
  278. md_processing/dr_egeria_inbox/generated_help_report.md +0 -9
  279. md_processing/dr_egeria_inbox/glossary_creation_experiment.ipynb +0 -341
  280. md_processing/dr_egeria_inbox/glossary_list.md +0 -5
  281. md_processing/dr_egeria_inbox/glossary_search_test.md +0 -40
  282. md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
  283. md_processing/dr_egeria_inbox/gov_def.md +0 -482
  284. md_processing/dr_egeria_inbox/gov_def2.md +0 -447
  285. md_processing/dr_egeria_inbox/img.png +0 -0
  286. md_processing/dr_egeria_inbox/product.md +0 -211
  287. md_processing/dr_egeria_inbox/rel.md +0 -8
  288. md_processing/dr_egeria_inbox/sb.md +0 -119
  289. md_processing/dr_egeria_inbox/solution-components.md +0 -136
  290. md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
  291. md_processing/dr_egeria_inbox/synonym_test.md +0 -42
  292. md_processing/dr_egeria_inbox/t2.md +0 -268
  293. md_processing/dr_egeria_outbox/.obsidian/app.json +0 -1
  294. md_processing/dr_egeria_outbox/.obsidian/appearance.json +0 -1
  295. md_processing/dr_egeria_outbox/.obsidian/community-plugins.json +0 -6
  296. md_processing/dr_egeria_outbox/.obsidian/core-plugins.json +0 -31
  297. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/data.json +0 -10
  298. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/main.js +0 -4459
  299. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/manifest.json +0 -10
  300. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/data.json +0 -3
  301. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/main.js +0 -153
  302. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/manifest.json +0 -11
  303. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/styles.css +0 -1
  304. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/main.js +0 -500
  305. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +0 -12
  306. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/styles.css +0 -1
  307. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/main.js +0 -37
  308. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/manifest.json +0 -11
  309. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/styles.css +0 -220
  310. md_processing/dr_egeria_outbox/.obsidian/types.json +0 -28
  311. md_processing/dr_egeria_outbox/.obsidian/workspace.json +0 -220
  312. md_processing/dr_egeria_outbox/Untitled.canvas +0 -1
  313. md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:22-dr_egeria_intro_part1.md +0 -312
  314. md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:23-dr_egeria_intro_part1.md +0 -265
  315. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:06-dr_egeria_intro_part1.md +0 -230
  316. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:30-dr_egeria_intro_part1.md +0 -296
  317. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:31-dr_egeria_intro_part1.md +0 -253
  318. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:08-dr_egeria_intro_part2.md +0 -343
  319. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:12-dr_egeria_intro_part2.md +0 -343
  320. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +0 -426
  321. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +0 -212
  322. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +0 -201
  323. md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 14:55-product.md +0 -77
  324. md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:05-product.md +0 -75
  325. md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:11-product.md +0 -74
  326. md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 20:40-collections.md +0 -49
  327. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +0 -719
  328. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +0 -41
  329. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +0 -33
  330. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +0 -192
  331. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:08-gov_def2.md +0 -486
  332. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:10-gov_def2.md +0 -486
  333. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:53-gov_def2.md +0 -486
  334. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:54-gov_def2.md +0 -486
  335. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:03-gov_def2.md +0 -486
  336. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:06-gov_def2.md +0 -486
  337. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:10-gov_def2.md +0 -486
  338. md_processing/dr_egeria_outbox/tuesday/processed-2025-07-16 19:15-gov_def2.md +0 -527
  339. md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 12:08-gov_def2.md +0 -527
  340. md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 14:27-gov_def2.md +0 -485
  341. md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +0 -209
  342. md_processing/family_docs/Data Designer/Create_Data_Class.md +0 -164
  343. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +0 -30
  344. md_processing/family_docs/Data Designer/Create_Data_Field.md +0 -162
  345. md_processing/family_docs/Data Designer/Create_Data_Specification.md +0 -36
  346. md_processing/family_docs/Data Designer/Create_Data_Structure.md +0 -38
  347. md_processing/family_docs/Data Designer/View_Data_Classes.md +0 -78
  348. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +0 -78
  349. md_processing/family_docs/Data Designer/View_Data_Fields.md +0 -78
  350. md_processing/family_docs/Data Designer/View_Data_Specifications.md +0 -78
  351. md_processing/family_docs/Data Designer/View_Data_Structures.md +0 -78
  352. md_processing/family_docs/Data Designer.md +0 -842
  353. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +0 -42
  354. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +0 -36
  355. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +0 -96
  356. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +0 -72
  357. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +0 -102
  358. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +0 -134
  359. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +0 -60
  360. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +0 -26
  361. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +0 -30
  362. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +0 -48
  363. md_processing/family_docs/Digital Product Manager.md +0 -668
  364. md_processing/family_docs/Glossary/Attach_Category_Parent.md +0 -18
  365. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +0 -26
  366. md_processing/family_docs/Glossary/Create_Category.md +0 -38
  367. md_processing/family_docs/Glossary/Create_Glossary.md +0 -42
  368. md_processing/family_docs/Glossary/Create_Term.md +0 -70
  369. md_processing/family_docs/Glossary.md +0 -206
  370. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +0 -106
  371. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +0 -112
  372. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +0 -114
  373. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +0 -114
  374. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +0 -114
  375. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +0 -128
  376. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +0 -122
  377. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +0 -106
  378. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +0 -122
  379. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +0 -122
  380. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +0 -106
  381. md_processing/family_docs/Governance Officer/Create_License_Type.md +0 -112
  382. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +0 -122
  383. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +0 -106
  384. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +0 -118
  385. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +0 -114
  386. md_processing/family_docs/Governance Officer/Create_Security_Group.md +0 -120
  387. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +0 -122
  388. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +0 -106
  389. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +0 -32
  390. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +0 -32
  391. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +0 -32
  392. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +0 -82
  393. md_processing/family_docs/Governance Officer.md +0 -2412
  394. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +0 -70
  395. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +0 -44
  396. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +0 -96
  397. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +0 -66
  398. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +0 -32
  399. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +0 -32
  400. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +0 -32
  401. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +0 -32
  402. md_processing/family_docs/Solution Architect/View_Solution_Components.md +0 -32
  403. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +0 -32
  404. md_processing/family_docs/Solution Architect.md +0 -490
  405. md_processing/md_processing_utils/debug_log +0 -574
  406. md_processing/md_processing_utils/debug_log.log +0 -0
  407. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +0 -2065
  408. md_processing/md_processing_utils/generated_help_terms.md +0 -842
  409. pyegeria/.DS_Store +0 -0
  410. pyegeria/README.md +0 -35
  411. pyegeria/_client_new.py +0 -1102
  412. pyegeria/_output_formats.py +0 -730
  413. pyegeria/asset_catalog_omvs.py +0 -864
  414. pyegeria/automated_curation_omvs.py +0 -3765
  415. pyegeria/config.py +0 -523
  416. pyegeria/egeria_my_client.py +0 -91
  417. pyegeria/feedback_manager_omvs.py +0 -4573
  418. pyegeria/load_config_orig.py +0 -218
  419. pyegeria/md_processing_helpers.py +0 -58
  420. pyegeria/md_processing_utils_orig.py +0 -1103
  421. pyegeria/metadata_explorer_omvs.py +0 -2326
  422. pyegeria/my_profile_omvs.py +0 -1022
  423. pyegeria/project_manager.py +0 -1591
  424. pyegeria/registered_info.py +0 -167
  425. pyegeria/template_manager_omvs.py +0 -1414
  426. pyegeria/utils.py +0 -256
  427. pyegeria-5.4.0.28.dist-info/METADATA +0 -77
  428. pyegeria-5.4.0.28.dist-info/RECORD +0 -343
  429. pyegeria-5.4.0.28.dist-info/entry_points.txt +0 -105
  430. /commands/cat/debug_log.log → /pyegeria/deprecated/__init__.py +0 -0
  431. /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
  432. /pyegeria/{collection_models.py → models/collection_models.py} +0 -0
  433. {pyegeria-5.4.0.28.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,1907 @@
1
+ """
2
+ SPDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+
5
+ Create, maintain and explore projects.
6
+ https://egeria-project.org/concepts/project
7
+
8
+ """
9
+
10
+ import asyncio
11
+ from typing import Any, Optional
12
+
13
+ from pyegeria.core._globals import NO_ELEMENTS_FOUND
14
+ from pyegeria.view.base_report_formats import select_report_spec
15
+ from pyegeria.core._server_client import ServerClient
16
+ from pyegeria.view.base_report_formats import get_report_spec_match
17
+ from pyegeria.core.config import settings as app_settings
18
+ from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequestBody, NewElementRequestBody,
19
+ TemplateRequestBody, DeleteElementRequestBody, DeleteRelationshipRequestBody, UpdateElementRequestBody,
20
+ NewRelationshipRequestBody)
21
+ from pyegeria.view.output_formatter import generate_output, populate_common_columns, overlay_additional_values
22
+ from pyegeria.core.utils import body_slimmer, dynamic_catch
23
+
24
+ EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
25
+ from loguru import logger
26
+
27
+ PROJECT_TYPES = ["Project", "Campaign", "StudyProject", "Task", "PersonalProject"]
28
+
29
+
30
+ class ProjectManager(ServerClient):
31
+ """
32
+ Client for the Project Manager View Service.
33
+
34
+ The Project Manager View Service provides methods to manage projects,
35
+ including project links, classification, and teams.
36
+
37
+ Attributes
38
+ ----------
39
+ view_server : str
40
+ The name of the View Server to use.
41
+ platform_url : str
42
+ URL of the server platform to connect to.
43
+ user_id : str
44
+ The identity of the user calling the method.
45
+ user_pwd : str
46
+ The password associated with the user_id. Defaults to None.
47
+ """
48
+
49
+ def __init__(
50
+ self,
51
+ view_server: str,
52
+ platform_url: str,
53
+ user_id: str,
54
+ user_pwd: Optional[str] = None,
55
+ token: Optional[str] = None,
56
+ ):
57
+ self.view_server = view_server
58
+ self.platform_url = platform_url
59
+ self.user_id = user_id
60
+ self.user_pwd = user_pwd
61
+ self.project_command_base: str = (
62
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects"
63
+ )
64
+ self.url_marker = 'project-manager'
65
+ ServerClient.__init__(self, view_server, platform_url, user_id, user_pwd, token)
66
+
67
+ def _extract_additional_project_properties(self, element: dict, columns_struct: dict)-> dict:
68
+
69
+
70
+ roles_required = any(column.get('key') == 'project_roles'
71
+ for column in columns_struct.get('formats', {}).get('attributes', []))
72
+ project_props = {}
73
+
74
+ if roles_required:
75
+ project_roles = element['elementHeader'].get('projectRoles', [])
76
+ project_roles_list = []
77
+ for project_role in project_roles:
78
+ project_roles_list.append(project_role.get('classificationName', ""))
79
+ project_roles_md = (", \n".join(project_roles_list)).rstrip(',') if project_roles_list else ''
80
+ project_props = {
81
+ 'project_roles': project_roles_md,
82
+ }
83
+ return project_props
84
+
85
+
86
+
87
+
88
+ def _extract_project_properties(self, element: dict, columns_struct: dict) -> dict:
89
+ props = element.get('properties', {}) or {}
90
+ normalized = {
91
+ 'properties': props,
92
+ 'elementHeader': element.get('elementHeader', {}),
93
+ }
94
+ # Common population pipeline
95
+ col_data = populate_common_columns(element, columns_struct)
96
+ columns_list = col_data.get('formats', {}).get('attributes', [])
97
+ # Overlay extras (project perspectives) only where empty
98
+ extra = self._extract_additional_project_properties(element, columns_struct)
99
+ col_data = overlay_additional_values(col_data, extra)
100
+ return col_data
101
+
102
+
103
+ def _generate_project_output(self, elements: dict | list[dict], search_string: str,
104
+ element_type_name: str | None,
105
+ output_format: str = 'DICT',
106
+ report_spec: dict | str = None) -> str | list[dict]:
107
+ entity_type = 'Project'
108
+ if report_spec:
109
+ if isinstance(report_spec, str):
110
+ output_formats = select_report_spec(report_spec, output_format)
111
+ elif isinstance(report_spec, dict):
112
+ output_formats = get_report_spec_match(report_spec, output_format)
113
+ else:
114
+ output_formats = None
115
+ else:
116
+ output_formats = select_report_spec(entity_type, output_format)
117
+ if output_formats is None:
118
+ output_formats = select_report_spec('Default', output_format)
119
+ return generate_output(
120
+ elements=elements,
121
+ search_string=search_string,
122
+ entity_type=entity_type,
123
+ output_format=output_format,
124
+ extract_properties_func=self._extract_project_properties,
125
+ get_additional_props_func=None,
126
+ columns_struct=output_formats,
127
+ )
128
+
129
+ #
130
+ # Retrieving Projects= Information - https://egeria-project.org/concepts/project
131
+ #
132
+ @dynamic_catch
133
+ async def _async_get_linked_projects(
134
+ self,
135
+ parent_guid: str,
136
+ body: Optional[dict | GetRequestBody] = None,
137
+ output_format: str = 'JSON',
138
+ report_spec: str | dict = None,
139
+ ) -> list | str:
140
+ """Returns the list of projects that are linked off of the supplied element. Any relationship will do.
141
+ The request body is optional, but if supplied acts as a filter on project status. Async version.
142
+
143
+ Parameters
144
+ ----------
145
+ parent_guid: str
146
+ The identity of the parent to find linked projects from.
147
+ project_status: str, optional
148
+ Optionally, filter results by project status.
149
+ output_format: str, default = "JSON"
150
+ - Type of output to return.
151
+ report_spec: dict | str, default = None
152
+ - Output format set to use. If None, the default output format set is used.
153
+
154
+ start_from: int, [default=0], optional
155
+ When multiple pages of results are available, the page number to start from.
156
+ page_size: int, [default=None]
157
+ The number of items to return in a single page. If not specified, the default will be taken from
158
+ the class instance.
159
+ Returns
160
+ -------
161
+ List | str
162
+
163
+ A list of projects linked off of the supplied element filtered by project status and effective time.
164
+
165
+ Raises
166
+ ------
167
+
168
+ PyegeriaInvalidParameterException
169
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
170
+ PyegeriaAPIException
171
+ Raised by the server when an issue arises in processing a valid request
172
+ NotAuthorizedException
173
+ The principle specified by the user_id does not have authorization for the requested action
174
+
175
+ """
176
+
177
+ url = (
178
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/"
179
+ f"metadata-elements/{parent_guid}/projects"
180
+ )
181
+
182
+ response = await self._async_get_guid_request(url, "Project", self._extract_project_properties,
183
+ body=body,
184
+ output_format=output_format,
185
+ report_spec=report_spec)
186
+ return response
187
+
188
+ @dynamic_catch
189
+ def get_linked_projects(
190
+ self,
191
+ parent_guid: str,
192
+ body: Optional[dict | GetRequestBody] = None,
193
+ output_format: str = 'JSON',
194
+ report_spec: str | dict = None) -> str | dict:
195
+
196
+ """Returns the list of projects that are linked off of the supplied element. Any relationship will do.
197
+ The request body is optional, but if supplied acts as a filter on project status.
198
+
199
+ Parameters
200
+ ----------
201
+ parent_guid: str
202
+ The identity of the parent to find linked projects from
203
+ project_status: str, optional
204
+ Optionally, filter results by project status.
205
+ effective_time: str, optional
206
+ Time at which to query for projects. Time format is "YYYY-MM-DDTHH:MM:SS" (ISO 8601).
207
+ output_format: str, default = "JSON"
208
+ - Type of output to return.
209
+ report_spec: dict | str, default = None
210
+ - Output format set to use. If None, the default output format set is used.
211
+
212
+ start_from: int, [default=0], optional
213
+ When multiple pages of results are available, the page number to start from.
214
+ page_size: int, [default=None]
215
+ The number of items to return in a single page. If not specified, the default will be taken from
216
+ the class instance.
217
+ Returns
218
+ -------
219
+ List | str
220
+
221
+ A list of projects linked off of the supplied element filtered by project status and effective time.
222
+
223
+ Raises
224
+ ------
225
+
226
+ PyegeriaInvalidParameterException
227
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
228
+ PyegeriaAPIException
229
+ Raised by the server when an issue arises in processing a valid request
230
+ NotAuthorizedException
231
+ The principle specified by the user_id does not have authorization for the requested action
232
+
233
+ """
234
+ loop = asyncio.get_event_loop()
235
+ resp = loop.run_until_complete(
236
+ self._async_get_linked_projects(
237
+ parent_guid,
238
+ body,
239
+ output_format,
240
+ report_spec
241
+ )
242
+ )
243
+ return resp
244
+
245
+ @dynamic_catch
246
+ async def _async_get_classified_projects(
247
+ self,
248
+ project_classification: str,
249
+ start_from: int = 0,
250
+ page_size: int = 0,
251
+ output_format: str = 'JSON',
252
+ report_spec: str | dict = None,
253
+ body: Optional[dict | GetRequestBody] = None,) -> str | dict:
254
+
255
+ """Returns the list of projects with a particular classification. The name of the classification is
256
+ supplied in the request body. Examples of these classifications include StudyProject, PersonalProject,
257
+ Campaign, or Task. There is also GlossaryProject and GovernanceProject. Async version.
258
+
259
+ Parameters
260
+ ----------
261
+ project_classification: str
262
+ The project classification to search for.
263
+ start_from: int, [default=0], optional
264
+ When multiple pages of results are available, the page number to start from.
265
+ page_size: int, [default=None]
266
+ The number of items to return in a single page. If not specified, the default will be taken from
267
+ the class instance.
268
+ Returns
269
+ -------
270
+ List | str
271
+
272
+ A list of projects filtered by project classification, and effective time.
273
+
274
+ Raises
275
+ ------
276
+
277
+ PyegeriaInvalidParameterException
278
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
279
+ PyegeriaAPIException
280
+ Raised by the server when an issue arises in processing a valid request
281
+ NotAuthorizedException
282
+ The principle specified by the user_id does not have authorization for the requested action
283
+
284
+ """
285
+
286
+ url = (
287
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/"
288
+ f"projects/by-classifications"
289
+ )
290
+ response = await self._async_get_name_request(url, "Project", self._extract_project_properties,
291
+ filter_string = project_classification, start_from=start_from,
292
+ page_size=page_size, body=body,
293
+ output_format=output_format,
294
+ report_spec=report_spec)
295
+ return response
296
+
297
+ @dynamic_catch
298
+ def get_classified_projects(
299
+ self,
300
+ project_classification: str,
301
+ start_from: int = 0,
302
+ page_size: int = 0,
303
+ output_format: str = 'JSON',
304
+ report_spec: str | dict = None,
305
+ body: Optional[dict | GetRequestBody] = None,
306
+ ) -> str | dict:
307
+ """Returns the list of projects with a particular classification. The name of the classification is
308
+ supplied in the request body. Examples of these classifications include StudyProject, PersonalProject,
309
+ Campaign or Task. There is also GlossaryProject and GovernanceProject.
310
+
311
+ Parameters
312
+ ----------
313
+ project_classification: str
314
+ The project classification to search for.
315
+ effective_time: str, optional
316
+ Time at which to query for projects. Time format is "YYYY-MM-DDTHH:MM:SS" (ISO 8601).
317
+
318
+ start_from: int, [default=0], optional
319
+ When multiple pages of results are available, the page number to start from.
320
+ page_size: int, [default=None]
321
+ The number of items to return in a single page. If not specified, the default will be taken from
322
+ the class instance.
323
+ Returns
324
+ -------
325
+ List | str
326
+
327
+ A list of projects filtered by project classification, and effective time.
328
+
329
+ Raises
330
+ ------
331
+
332
+ PyegeriaInvalidParameterException
333
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
334
+ PyegeriaAPIException
335
+ Raised by the server when an issue arises in processing a valid request
336
+ NotAuthorizedException
337
+ The principle specified by the user_id does not have authorization for the requested action
338
+
339
+ """
340
+ loop = asyncio.get_event_loop()
341
+ resp = loop.run_until_complete(
342
+ self._async_get_classified_projects(project_classification,
343
+ start_from,page_size,
344
+
345
+ output_format,
346
+ report_spec,
347
+ body
348
+ )
349
+ )
350
+ return resp
351
+
352
+ async def _async_get_project_team(
353
+ self,
354
+ project_guid: str,
355
+ team_role: Optional[str] = None,
356
+ start_from: int = 0,
357
+ page_size: int = 0,
358
+ output_format: str = 'JSON',
359
+ report_spec: str | dict = None,
360
+ body: Optional[dict | FilterRequestBody] = None,) -> str | dict:
361
+
362
+ """Returns the list of actors that are linked off of the project. This includes the project managers.
363
+ The optional request body allows a teamRole to be specified as a filter. To filter out the project managers,
364
+ specify "ProjectManagement" as the team role. Async version.
365
+
366
+ Parameters
367
+ ----------
368
+ project_guid: str
369
+ Identifier of the project to return information for.
370
+ team_role: str, [default=None]
371
+ The team role to filter by. If None, all team members will be returned.
372
+ start_from: int, [default=0], optional
373
+ When multiple pages of results are available, the page number to start from.
374
+ page_size: int, [default=None]
375
+ The number of items to return in a single page. If not specified, the default will be taken from
376
+ the class instance.
377
+ Returns
378
+ -------
379
+ List | str
380
+
381
+ A list of projects filtered by project classification, and effective time.
382
+
383
+ Raises
384
+ ------
385
+
386
+ PyegeriaException
387
+
388
+ """
389
+ url = (
390
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/"
391
+ f"projects/{project_guid}/team"
392
+ )
393
+ if body is None and (team_role is not None and team_role != "*"):
394
+ body = { "filter" : team_role }
395
+ response = await self._async_make_request("POST", url, body)
396
+ else:
397
+ response = await self._async_make_request("POST", url)
398
+
399
+ elements = response.json().get("elements", NO_ELEMENTS_FOUND)
400
+ if type(elements) is str or len(elements) == 0:
401
+ logger.info(NO_ELEMENTS_FOUND)
402
+ return NO_ELEMENTS_FOUND
403
+
404
+ if output_format != 'JSON': # return a simplified markdown representation
405
+ logger.info(f"Found elements, output format: {output_format} and report_spec: {report_spec}")
406
+ return self._generate_project_output(elements, team_role, "Project Team",
407
+ output_format, report_spec)
408
+ return elements
409
+
410
+ @dynamic_catch
411
+ def get_project_team(
412
+ self,
413
+ project_guid: str,
414
+ team_role: Optional[str] = None,
415
+ start_from: int = 0,
416
+ page_size: int = 0,
417
+ output_format: str = 'JSON',
418
+ report_spec: str | dict = None,
419
+ body: Optional[dict | FilterRequestBody] = None,
420
+ ) -> str | dict:
421
+ """Returns the list of actors that are linked off of the project. This includes the project managers.
422
+ The optional request body allows a teamRole to be specified as a filter. To filter out the project managers,
423
+ specify "ProjectManagement" as the team perspective.
424
+
425
+ Parameters
426
+ ----------
427
+ project_guid: str
428
+ Identifier of the project to return information for.
429
+ team_role: str, [default=None]
430
+ The team perspective to filter by. If None, all team members will be returned.
431
+ start_from: int, [default=0], optional
432
+ When multiple pages of results are available, the page number to start from.
433
+ page_size: int, [default=None]
434
+ The number of items to return in a single page. If not specified, the default will be taken from
435
+ the class instance.
436
+ Returns
437
+ -------
438
+ List | str
439
+
440
+ A list of projects filtered by project classification, and effective time.
441
+
442
+ Raises
443
+ ------
444
+
445
+ PyegeriaException
446
+
447
+ """
448
+ loop = asyncio.get_event_loop()
449
+ resp = loop.run_until_complete(
450
+ self._async_get_project_team(project_guid, team_role, start_from, page_size,
451
+ output_format,report_spec, body )
452
+ )
453
+ return resp
454
+
455
+
456
+
457
+ @dynamic_catch
458
+ async def _async_find_projects(self, search_string: str = "*",
459
+ starts_with: bool = True, ends_with: bool = False,
460
+ ignore_case: bool = False,
461
+ anchor_domain: Optional[str] = None,
462
+ metadata_element_type: Optional[str] = None,
463
+ metadata_element_subtypes: Optional[list[str]] = None,
464
+ skip_relationships: Optional[list[str]] = None,
465
+ include_only_relationships: Optional[list[str]] = None,
466
+ skip_classified_elements: Optional[list[str]] = None,
467
+ include_only_classified_elements: Optional[list[str]] = None,
468
+ graph_query_depth: int = 3,
469
+ governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
470
+ effective_time: Optional[str] = None, relationship_page_size: int = 0,
471
+ limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
472
+ sequencing_property: Optional[str] = None,
473
+ output_format: str = "JSON",
474
+ report_spec: str | dict = "Referenceable",
475
+ start_from: int = 0, page_size: int = 100,
476
+ property_names: Optional[list[str]] = None,
477
+ body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
478
+ """ Retrieve the list of project metadata elements that contain the search string. Async Version.
479
+
480
+ Parameters
481
+ ----------
482
+ search_string: str
483
+ Search string to match against - None or '*' indicate match against all projects.
484
+ starts_with : bool, [default=True], optional
485
+ Starts with the supplied string.
486
+ ends_with : bool, [default=False], optional
487
+ Ends with the supplied string
488
+ ignore_case : bool, [default=False], optional
489
+ Ignore case when searching
490
+ anchor_domain: str, optional
491
+ The anchor domain to search in.
492
+ metadata_element_type: str, optional
493
+ The type of metadata element to search for.
494
+ metadata_element_subtypes: list[str], optional
495
+ The subtypes of metadata element to search for.
496
+ skip_relationships: list[str], optional
497
+ The types of relationships to skip.
498
+ include_only_relationships: list[str], optional
499
+ The types of relationships to include.
500
+ skip_classified_elements: list[str], optional
501
+ The types of classified elements to skip.
502
+ include_only_classified_elements: list[str], optional
503
+ The types of classified elements to include.
504
+ graph_query_depth: int, [default=3], optional
505
+ The depth of the graph query.
506
+ governance_zone_filter: list[str], optional
507
+ The governance zones to search in.
508
+ as_of_time: str, optional
509
+ The time to search as of.
510
+ effective_time: str, optional
511
+ The effective time to search at.
512
+ relationship_page_size: int, [default=0], optional
513
+ The page size for relationships.
514
+ limit_results_by_status: list[str], optional
515
+ The statuses to limit results by.
516
+ sequencing_order: str, optional
517
+ The order to sequence results by.
518
+ sequencing_property: str, optional
519
+ The property to sequence results by.
520
+ output_format: str, default = "JSON"
521
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
522
+ report_spec: str | dict , optional, default = "Referenceable"
523
+ - The desired output columns/fields to include.
524
+ start_from: int, [default=0], optional
525
+ When multiple pages of results are available, the page number to start from.
526
+ page_size: int, [default=100]
527
+ The number of items to return in a single page.
528
+ property_names: list[str], optional
529
+ The names of properties to search for.
530
+ body: dict | SearchStringRequestBody, optional, default = None
531
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
532
+
533
+ Returns
534
+ -------
535
+ List | str
536
+
537
+ Output depends on the output format specified.
538
+
539
+ Raises
540
+ ------
541
+
542
+ ValidationError
543
+ If the client passes incorrect parameters on the request that don't conform to the data model.
544
+ PyegeriaException
545
+ Issues raised in communicating or server side processing.
546
+ NotAuthorizedException
547
+ The principle specified by the user_id does not have authorization for the requested action
548
+
549
+ """
550
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/by-search-string"
551
+ response = await self._async_find_request(url, _type="Project", _gen_output=self._generate_project_output,
552
+ search_string=search_string, starts_with=starts_with,
553
+ ends_with=ends_with, ignore_case=ignore_case,
554
+ anchor_domain=anchor_domain,
555
+ metadata_element_type=metadata_element_type,
556
+ metadata_element_subtypes=metadata_element_subtypes,
557
+ skip_relationships=skip_relationships,
558
+ include_only_relationships=include_only_relationships,
559
+ skip_classified_elements=skip_classified_elements,
560
+ include_only_classified_elements=include_only_classified_elements,
561
+ graph_query_depth=graph_query_depth,
562
+ governance_zone_filter=governance_zone_filter,
563
+ as_of_time=as_of_time, effective_time=effective_time,
564
+ relationship_page_size=relationship_page_size,
565
+ limit_results_by_status=limit_results_by_status,
566
+ sequencing_order=sequencing_order,
567
+ sequencing_property=sequencing_property,
568
+ output_format=output_format, report_spec=report_spec,
569
+ start_from=start_from, page_size=page_size,
570
+ property_names=property_names, body=body)
571
+
572
+ return response
573
+
574
+ @dynamic_catch
575
+ def find_projects(self, search_string: str = "*",
576
+ starts_with: bool = True, ends_with: bool = False,
577
+ ignore_case: bool = False,
578
+ anchor_domain: Optional[str] = None,
579
+ metadata_element_type: Optional[str] = None,
580
+ metadata_element_subtypes: Optional[list[str]] = None,
581
+ skip_relationships: Optional[list[str]] = None,
582
+ include_only_relationships: Optional[list[str]] = None,
583
+ skip_classified_elements: Optional[list[str]] = None,
584
+ include_only_classified_elements: Optional[list[str]] = None,
585
+ graph_query_depth: int = 3,
586
+ governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
587
+ effective_time: Optional[str] = None, relationship_page_size: int = 0,
588
+ limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
589
+ sequencing_property: Optional[str] = None,
590
+ output_format: str = "JSON",
591
+ report_spec: str | dict = "Referenceable",
592
+ start_from: int = 0, page_size: int = 100,
593
+ property_names: Optional[list[str]] = None,
594
+ body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
595
+ """ Retrieve the list of project metadata elements that contain the search string.
596
+
597
+ Parameters
598
+ ----------
599
+ search_string: str
600
+ Search string to match against - None or '*' indicate match against all projects.
601
+ starts_with : bool, [default=True], optional
602
+ Starts with the supplied string.
603
+ ends_with : bool, [default=False], optional
604
+ Ends with the supplied string
605
+ ignore_case : bool, [default=False], optional
606
+ Ignore case when searching
607
+ anchor_domain: str, optional
608
+ The anchor domain to search in.
609
+ metadata_element_type: str, optional
610
+ The type of metadata element to search for.
611
+ metadata_element_subtypes: list[str], optional
612
+ The subtypes of metadata element to search for.
613
+ skip_relationships: list[str], optional
614
+ The types of relationships to skip.
615
+ include_only_relationships: list[str], optional
616
+ The types of relationships to include.
617
+ skip_classified_elements: list[str], optional
618
+ The types of classified elements to skip.
619
+ include_only_classified_elements: list[str], optional
620
+ The types of classified elements to include.
621
+ graph_query_depth: int, [default=3], optional
622
+ The depth of the graph query.
623
+ governance_zone_filter: list[str], optional
624
+ The governance zones to search in.
625
+ as_of_time: str, optional
626
+ The time to search as of.
627
+ effective_time: str, optional
628
+ The effective time to search at.
629
+ relationship_page_size: int, [default=0], optional
630
+ The page size for relationships.
631
+ limit_results_by_status: list[str], optional
632
+ The statuses to limit results by.
633
+ sequencing_order: str, optional
634
+ The order to sequence results by.
635
+ sequencing_property: str, optional
636
+ The property to sequence results by.
637
+ output_format: str, default = "JSON"
638
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
639
+ report_spec: str | dict , optional, default = "Referenceable"
640
+ - The desired output columns/fields to include.
641
+ start_from: int, [default=0], optional
642
+ When multiple pages of results are available, the page number to start from.
643
+ page_size: int, [default=100]
644
+ The number of items to return in a single page.
645
+ property_names: list[str], optional
646
+ The names of properties to search for.
647
+ body: dict | SearchStringRequestBody, optional, default = None
648
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
649
+
650
+ Returns
651
+ -------
652
+ List | str
653
+
654
+ Output depends on the output format specified.
655
+
656
+ Raises
657
+ -------
658
+
659
+ ValidationError
660
+ If the client passes incorrect parameters on the request that don't conform to the data model.
661
+ PyegeriaException
662
+ Issues raised in communicating or server side processing.
663
+ NotAuthorizedException
664
+ The principle specified by the user_id does not have authorization for the requested action
665
+
666
+ """
667
+ loop = asyncio.get_event_loop()
668
+ return loop.run_until_complete(self._async_find_projects(search_string=search_string,
669
+ starts_with=starts_with,
670
+ ends_with=ends_with,
671
+ ignore_case=ignore_case,
672
+ anchor_domain=anchor_domain,
673
+ metadata_element_type=metadata_element_type,
674
+ metadata_element_subtypes=metadata_element_subtypes,
675
+ skip_relationships=skip_relationships,
676
+ include_only_relationships=include_only_relationships,
677
+ skip_classified_elements=skip_classified_elements,
678
+ include_only_classified_elements=include_only_classified_elements,
679
+ graph_query_depth=graph_query_depth,
680
+ governance_zone_filter=governance_zone_filter,
681
+ as_of_time=as_of_time,
682
+ effective_time=effective_time,
683
+ relationship_page_size=relationship_page_size,
684
+ limit_results_by_status=limit_results_by_status,
685
+ sequencing_order=sequencing_order,
686
+ sequencing_property=sequencing_property,
687
+ output_format=output_format,
688
+ report_spec=report_spec,
689
+ start_from=start_from,
690
+ page_size=page_size,
691
+ property_names=property_names,
692
+ body=body))
693
+
694
+ @dynamic_catch
695
+ async def _async_get_projects_by_name(
696
+ self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
697
+ body: Optional[dict | FilterRequestBody] = None,
698
+ start_from: int = 0, page_size: int = 0,
699
+ output_format: str = 'JSON',
700
+ report_spec: str | dict = None) -> list | str:
701
+ url = f"{self.project_command_base}/by-name"
702
+
703
+ response = await self._async_get_name_request(url, _type="Projects",
704
+ _gen_output=self._generate_project_output,
705
+ filter_string=filter_string,
706
+ classification_names=classification_names,
707
+ start_from=start_from, page_size=page_size,
708
+ output_format=output_format, report_spec=report_spec,
709
+ body=body)
710
+
711
+ return response
712
+
713
+ @dynamic_catch
714
+ def get_projects_by_name(
715
+ self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
716
+ body: Optional[dict | FilterRequestBody] = None,
717
+ start_from: int = 0, page_size: int = 0,
718
+ output_format: str = 'JSON',
719
+ report_spec: str | dict = None) -> list | str:
720
+
721
+ loop = asyncio.get_event_loop()
722
+ resp = loop.run_until_complete(
723
+ self._async_get_projects_by_name(
724
+ filter_string,
725
+ classification_names,
726
+ body,
727
+ start_from,
728
+ page_size,
729
+ output_format,
730
+ report_spec,
731
+ )
732
+ )
733
+ return resp
734
+
735
+ @dynamic_catch
736
+ async def _async_get_project_by_guid(self, project_guid: str, element_type: Optional[str] = None,
737
+ body: Optional[dict | GetRequestBody] = None,
738
+ output_format: str = 'JSON',
739
+ report_spec: str | dict = None) -> dict | str:
740
+ """Return the properties of a specific project. Async version.
741
+
742
+ Parameters
743
+ ----------
744
+ project_guid: str,
745
+ unique identifier of the collection.
746
+ element_type: str, default = None, optional
747
+ type of collection - Collection, DataSpec, Agreement, etc.
748
+ body: dict | GetRequestBody, optional, default = None
749
+ full request body.
750
+ output_format: str, default = "JSON"
751
+ - one of "DICT", "MERMAID" or "JSON"
752
+ report_spec: str | dict, optional, default = None
753
+ The desired output columns/fields to include.
754
+
755
+ Returns
756
+ -------
757
+ dict | str
758
+
759
+ A JSON dict representing the specified collection. Returns a string if none found.
760
+
761
+ Raises
762
+ ------
763
+
764
+ PyegeriaInvalidParameterException
765
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
766
+ PyegeriaAPIException
767
+ Raised by the server when an issue arises in processing a valid request
768
+ NotAuthorizedException
769
+ The principle specified by the user_id does not have authorization for the requested action
770
+
771
+ Notes
772
+ ----
773
+ Body sample:
774
+ {
775
+ "class": "GetRequestBody",
776
+ "asOfTime": "{{$isoTimestamp}}",
777
+ "effectiveTime": "{{$isoTimestamp}}",
778
+ "forLineage": false,
779
+ "forDuplicateProcessing": false
780
+ }
781
+ """
782
+
783
+ url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/"
784
+ f"{project_guid}")
785
+ type = element_type if element_type else "Project"
786
+
787
+ response = await self._async_get_guid_request(url, _type=type,
788
+ _gen_output=self._generate_project_output,
789
+ output_format=output_format, report_spec=report_spec,
790
+ body=body)
791
+
792
+ return response
793
+
794
+ @dynamic_catch
795
+ def get_project_by_guid(self, project_guid: str, element_type: Optional[str] = None,
796
+ body: Optional[dict | GetRequestBody] = None,
797
+ output_format: str = 'JSON',
798
+ report_spec: str | dict = None) -> dict | str:
799
+ """Return the properties of a specific project.
800
+
801
+ Parameters
802
+ ----------
803
+ project_guid: str,
804
+ unique identifier of the collection.
805
+ element_type: str, default = None, optional
806
+ type of collection - Collection, DataSpec, Agreement, etc.
807
+ body: dict | GetRequestBody, optional, default = None
808
+ full request body.
809
+ output_format: str, default = "JSON"
810
+ - one of "DICT", "MERMAID" or "JSON"
811
+ report_spec: str | dict, optional, default = None
812
+ The desired output columns/fields to include.
813
+
814
+ Returns
815
+ -------
816
+ dict | str
817
+
818
+ A JSON dict representing the specified collection. Returns a string if none found.
819
+
820
+ Raises
821
+ ------
822
+
823
+ PyegeriaInvalidParameterException
824
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
825
+ PyegeriaAPIException
826
+ Raised by the server when an issue arises in processing a valid request
827
+ NotAuthorizedException
828
+ The principle specified by the user_id does not have authorization for the requested action
829
+
830
+ Notes
831
+ ----
832
+ Body sample:
833
+ {
834
+ "class": "GetRequestBody",
835
+ "asOfTime": "{{$isoTimestamp}}",
836
+ "effectiveTime": "{{$isoTimestamp}}",
837
+ "forLineage": false,
838
+ "forDuplicateProcessing": false
839
+ }
840
+ """
841
+ loop = asyncio.get_event_loop()
842
+ resp = loop.run_until_complete(
843
+ self._async_get_project_by_guid(project_guid, element_type, body, output_format, report_spec)
844
+ )
845
+
846
+ return resp
847
+
848
+ @dynamic_catch
849
+ async def _async_get_project_graph(
850
+ self,
851
+ project_guid: str,
852
+ element_type: Optional[str] = None,
853
+ body: Optional[dict | GetRequestBody] = None,
854
+ output_format: str = 'JSON',
855
+ report_spec: str | dict = None,
856
+ ) -> dict | str:
857
+ """Return the mermaid graph of a specific project. Async version.
858
+
859
+ Parameters
860
+ ----------
861
+ project_guid: str,
862
+ unique identifier of the project.
863
+ body: dict | GetRequestBody, optional, default = None
864
+ full request body.
865
+
866
+ Returns
867
+ -------
868
+ str
869
+
870
+ A mermaid markdown string representing the graph of the project.
871
+ Raises
872
+ ------
873
+
874
+ PyegeriaInvalidParameterException
875
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
876
+ PyegeriaAPIException
877
+ Raised by the server when an issue arises in processing a valid request
878
+ NotAuthorizedException
879
+ The principle specified by the user_id does not have authorization for the requested action
880
+
881
+ """
882
+
883
+ url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/"
884
+ f"{project_guid}/graph")
885
+ element_type = element_type if element_type else "Project"
886
+ response = await self._async_get_guid_request(url, _type=element_type,
887
+ _gen_output=self._generate_project_output,
888
+ output_format=output_format, report_spec=report_spec,
889
+ body=body)
890
+
891
+ return response
892
+
893
+ @dynamic_catch
894
+ def get_project_graph(
895
+ self,
896
+ project_guid: str,
897
+ element_type: Optional[str] = None,
898
+ body: Optional[dict | GetRequestBody] = None,
899
+ output_format: str = 'JSON',
900
+ report_spec: str | dict = None,
901
+ ) -> dict | str:
902
+ """Return the mermaid graph of a specific project. Async version.
903
+
904
+ Parameters
905
+ ----------
906
+ project_guid: str,
907
+ unique identifier of the project.
908
+ body: dict | GetRequestBody, optional, default = None
909
+ full request body.
910
+
911
+ Returns
912
+ -------
913
+ str
914
+
915
+ A mermaid markdown string representing the graph of the project.
916
+ Raises
917
+ ------
918
+
919
+ PyegeriaInvalidParameterException
920
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
921
+ PyegeriaAPIException
922
+ Raised by the server when an issue arises in processing a valid request
923
+ NotAuthorizedException
924
+ The principle specified by the user_id does not have authorization for the requested action
925
+
926
+ """
927
+ loop = asyncio.get_event_loop()
928
+ resp = loop.run_until_complete(
929
+ self._async_get_project_graph(project_guid, element_type, body, output_format, report_spec)
930
+ )
931
+
932
+ return resp
933
+
934
+ #
935
+ # Create project methods
936
+ #
937
+ @dynamic_catch
938
+ async def _async_create_project(
939
+ self,
940
+ body: dict | NewElementRequestBody,
941
+ ) -> str:
942
+ """Create project: https://egeria-project.org/concepts/project Async version.
943
+
944
+ Parameters
945
+ ----------.
946
+ body: dict
947
+ A dict representing the details of the project to create. To create different kinds of projects,
948
+ set the initial_classifications in the body to be, for instance, "PersonalProject" or "Campaign".
949
+
950
+
951
+ Returns
952
+ -------
953
+ str - the guid of the created project
954
+
955
+ Raises
956
+ ------
957
+ PyegeriaInvalidParameterException
958
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
959
+ PyegeriaAPIException
960
+ Raised by the server when an issue arises in processing a valid request
961
+ NotAuthorizedException
962
+ The principle specified by the user_id does not have authorization for the requested action
963
+ Notes
964
+ -----
965
+
966
+ Body structure like:
967
+ {
968
+ "class": "NewElementRequestBody",
969
+ "anchorGUID" : "anchor GUID, if set then isOwnAnchor=false",
970
+ "isOwnAnchor" : False,
971
+ "parentGUID" : "parent GUID, if set, set all parameters beginning 'parent'",
972
+ "parentRelationshipTypeName" : "open metadata type name",
973
+ "parentAtEnd1": True,
974
+ "initialClassifications" : {
975
+ "Folder" : {
976
+ "class": "FolderProperties"
977
+ }
978
+ },
979
+ "projectProperties": {
980
+ "class" : "ProjectProperties",
981
+ "qualifiedName": "Must provide a unique name here",
982
+ "identifier" : "Add business identifier",
983
+ "name" : "Add display name here",
984
+ "description" : "Add description of the project here",
985
+ "projectStatus": "Add appropriate valid value for type",
986
+ "projectPhase" : "Add appropriate valid value for phase",
987
+ "projectHealth" : "Add appropriate valid value for health",
988
+ "startDate" : "date/time",
989
+ "plannedEndDate" : "date/time"
990
+ }
991
+ }
992
+
993
+ """
994
+
995
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects"
996
+
997
+ return await self._async_create_element_body_request(url, ["ProjectProperties"], body)
998
+
999
+ @dynamic_catch
1000
+ def create_project(
1001
+ self,
1002
+ body: dict | NewElementRequestBody,
1003
+ ) -> str:
1004
+ """Create project: https://egeria-project.org/concepts/project
1005
+
1006
+ Parameters
1007
+ ----------.
1008
+ body: dict
1009
+ A dict representing the details of the project to create.
1010
+
1011
+ Returns
1012
+ -------
1013
+ str - the guid of the created collection
1014
+
1015
+ Raises
1016
+ ------
1017
+ PyegeriaInvalidParameterException
1018
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1019
+ PyegeriaAPIException
1020
+ Raised by the server when an issue arises in processing a valid request
1021
+ NotAuthorizedException
1022
+ The principle specified by the user_id does not have authorization for the requested action
1023
+
1024
+ Notes
1025
+ -----
1026
+ Body structure like:
1027
+ {
1028
+ "anchorGUID" : "anchor GUID, if set then isOwnAnchor=false",
1029
+ "isOwnAnchor" : False,
1030
+ "parentGUID" : "parent GUID, if set, set all parameters beginning 'parent'",
1031
+ "parentRelationshipTypeName" : "open metadata type name",
1032
+ "parentAtEnd1": True,
1033
+ "projectProperties": {
1034
+ "class" : "ProjectProperties",
1035
+ "qualifiedName": "Must provide a unique name here",
1036
+ "identifier" : "Add business identifier",
1037
+ "name" : "Add display name here",
1038
+ "description" : "Add description of the project here",
1039
+ "projectStatus": "Add appropriate valid value for type",
1040
+ "projectPhase" : "Add appropriate valid value for phase",
1041
+ "projectHealth" : "Add appropriate valid value for health",
1042
+ "startDate" : "date/time",
1043
+ "plannedEndDate" : "date/time"
1044
+ }
1045
+ }
1046
+
1047
+ """
1048
+ loop = asyncio.get_event_loop()
1049
+ resp = loop.run_until_complete(
1050
+ self._async_create_project(body)
1051
+ )
1052
+ return resp
1053
+
1054
+ @dynamic_catch
1055
+ async def _async_create_project_from_template(
1056
+ self,
1057
+ body: dict | TemplateRequestBody,
1058
+ ) -> str:
1059
+ """Create a new metadata element to represent a project using an existing metadata element as a template.
1060
+ The template defines additional classifications and relationships that should be added to the new project.
1061
+ Async version.
1062
+
1063
+ Parameters
1064
+ ----------
1065
+
1066
+ body: dict
1067
+ A dict representing the details of the collection to create.
1068
+
1069
+
1070
+ Returns
1071
+ -------
1072
+ str - the guid of the created project.
1073
+
1074
+ Raises
1075
+ ------
1076
+ PyegeriaInvalidParameterException
1077
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1078
+ PyegeriaAPIException
1079
+ Raised by the server when an issue arises in processing a valid request
1080
+ NotAuthorizedException
1081
+ The principle specified by the user_id does not have authorization for the requested action
1082
+
1083
+ Notes
1084
+ -----
1085
+ JSON Structure looks like:
1086
+ {
1087
+ "class": "TemplateRequestBody",
1088
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
1089
+ "isOwnAnchor": false,
1090
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
1091
+ "parentRelationshipTypeName": "open metadata type name",
1092
+ "parentAtEnd1": true,
1093
+ "templateGUID": "template GUID",
1094
+ "replacementProperties": {
1095
+ "class": "ElementProperties",
1096
+ "propertyValueMap" : {
1097
+ "propertyName" : {
1098
+ "class": "PrimitiveTypePropertyValue",
1099
+ "typeName": "string",
1100
+ "primitiveTypeCategory" : "OM_PRIMITIVE_TYPE_STRING",
1101
+ "primitiveValue" : "value of property"
1102
+ }
1103
+ }
1104
+ },
1105
+ "placeholderPropertyValues" : {
1106
+ "placeholderProperty1Name" : "property1Value",
1107
+ "placeholderProperty2Name" : "property2Value"
1108
+ }
1109
+ }
1110
+
1111
+
1112
+ """
1113
+
1114
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/from-template"
1115
+ return await self._async_create_element_from_template(url, body)
1116
+
1117
+ @dynamic_catch
1118
+ def create_project_from_template(
1119
+ self,
1120
+ body: dict,
1121
+ ) -> str:
1122
+ """Create a new metadata element to represent a project using an existing metadata element as a template.
1123
+ The template defines additional classifications and relationships that should be added to the new project.
1124
+
1125
+ Parameters
1126
+ ----------
1127
+
1128
+ body: dict
1129
+ A dict representing the details of the collection to create.
1130
+
1131
+
1132
+ Returns
1133
+ -------
1134
+ str - the guid of the created project.
1135
+
1136
+ Raises
1137
+ ------
1138
+ PyegeriaInvalidParameterException
1139
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1140
+ PyegeriaAPIException
1141
+ Raised by the server when an issue arises in processing a valid request
1142
+ NotAuthorizedException
1143
+ The principle specified by the user_id does not have authorization for the requested action
1144
+
1145
+ Notes
1146
+ -----
1147
+ JSON Structure looks like:
1148
+ {
1149
+ "class": "TemplateRequestBody",
1150
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
1151
+ "isOwnAnchor": false,
1152
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
1153
+ "parentRelationshipTypeName": "open metadata type name",
1154
+ "parentAtEnd1": true,
1155
+ "templateGUID": "template GUID",
1156
+ "replacementProperties": {
1157
+ "class": "ElementProperties",
1158
+ "propertyValueMap" : {
1159
+ "propertyName" : {
1160
+ "class": "PrimitiveTypePropertyValue",
1161
+ "typeName": "string",
1162
+ "primitiveTypeCategory" : "OM_PRIMITIVE_TYPE_STRING",
1163
+ "primitiveValue" : "value of property"
1164
+ }
1165
+ }
1166
+ },
1167
+ "placeholderPropertyValues" : {
1168
+ "placeholderProperty1Name" : "property1Value",
1169
+ "placeholderProperty2Name" : "property2Value"
1170
+ }
1171
+ }
1172
+ """
1173
+ loop = asyncio.get_event_loop()
1174
+ resp = loop.run_until_complete(self._async_create_project_from_template(body))
1175
+ return resp
1176
+
1177
+ #
1178
+ #
1179
+ #
1180
+
1181
+ @dynamic_catch
1182
+ async def _async_update_project(
1183
+ self,
1184
+ project_guid: str,
1185
+ body: dict | UpdateElementRequestBody
1186
+ ) -> None:
1187
+ """Update the properties of a project. Async Version.
1188
+
1189
+ Parameters
1190
+ ----------
1191
+ project_guid: str
1192
+ Unique identifier for the project.
1193
+ qualified_name: str, optional, defaults to None
1194
+ The unique identifier of the project.
1195
+ identifier: str
1196
+ A project identifier.
1197
+ display_name: str
1198
+ The display name of the element. Will also be used as the basis of the qualified_name.
1199
+ description: str
1200
+ A description of the collection.
1201
+ project_status: str, optional
1202
+ The project status
1203
+ project_phase: str, optional
1204
+ Project phase as defined in valid values
1205
+ project_health: str, optional
1206
+ Project health as defined in valid values
1207
+ start_date: str, optional, defaults to None
1208
+ Start date of the project in ISO 8601 string format.
1209
+ planned_end_date: str, optional, defaults to None
1210
+ Planned completion date in ISO 8601 string format.
1211
+ merge_update: bool, optional, defaults to False
1212
+ If True, then all the properties of the project will be replaced with the specified properties.
1213
+
1214
+ Returns
1215
+ -------
1216
+ str - the guid of the created project task
1217
+
1218
+ Raises
1219
+ ------
1220
+ PyegeriaInvalidParameterException
1221
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1222
+ PyegeriaAPIException
1223
+ Raised by the server when an issue arises in processing a valid request
1224
+ NotAuthorizedException
1225
+ The principle specified by the user_id does not have authorization for the requested action
1226
+ """
1227
+
1228
+ url = (
1229
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/{project_guid}/"
1230
+ f"update"
1231
+ )
1232
+
1233
+ await self._async_update_element_body_request(url, ["ProjectProperties"], body)
1234
+ logger.info(f"Updated digital subscription {project_guid}")
1235
+
1236
+ @dynamic_catch
1237
+ def update_project(
1238
+ self,
1239
+ project_guid: str,
1240
+ body: dict | UpdateElementRequestBody,
1241
+ ) -> None:
1242
+ """Update the properties of a project.
1243
+
1244
+ Parameters
1245
+ ----------
1246
+ project_guid: str
1247
+ Unique identifier for the project.
1248
+ qualified_name: str, optional, defaults to None
1249
+ The unique identifier of the project.
1250
+ identifier: str
1251
+ A project identifier.
1252
+ display_name: str
1253
+ The display name of the element. Will also be used as the basis of the qualified_name.
1254
+ description: str
1255
+ A description of the collection.
1256
+ project_status: str, optional
1257
+ The project status
1258
+ project_phase: str, optional
1259
+ Project phase as defined in valid values
1260
+ project_health: str, optional
1261
+ Project health as defined in valid values
1262
+ start_date: str, optional, defaults to None
1263
+ Start date of the project in ISO 8601 string format.
1264
+ planned_end_date: str, optional, defaults to None
1265
+ Planned completion date in ISO 8601 string format.
1266
+ merge_update: bool, optional, defaults to False
1267
+ If True, then all the properties of the project will be replaced with the specified properties.
1268
+
1269
+ Returns
1270
+ -------
1271
+ str - the guid of the created project task
1272
+
1273
+ Raises
1274
+ ------
1275
+ PyegeriaInvalidParameterException
1276
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1277
+ PyegeriaAPIException
1278
+ Raised by the server when an issue arises in processing a valid request
1279
+ NotAuthorizedException
1280
+ The principle specified by the user_id does not have authorization for the requested action
1281
+ """
1282
+ loop = asyncio.get_event_loop()
1283
+ loop.run_until_complete(
1284
+ self._async_update_project(project_guid, body))
1285
+
1286
+ @dynamic_catch
1287
+ async def _async_delete_project(
1288
+ self,
1289
+ project_guid: str, cascade: bool = False, body: Optional[dict | DeleteElementRequestBody] = None) -> None:
1290
+ """Delete a project. It is detected from all parent elements. Async version
1291
+
1292
+ Parameters
1293
+ ----------
1294
+ project_guid: str
1295
+ The guid of the project to update.
1296
+ cascade: bool, optional, defaults to False
1297
+ If true, then all anchored elements will be deleted.
1298
+
1299
+ Returns
1300
+ -------
1301
+ Nothing
1302
+
1303
+ Raises
1304
+ ------
1305
+ PyegeriaInvalidParameterException
1306
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1307
+ PyegeriaAPIException
1308
+ Raised by the server when an issue arises in processing a valid request
1309
+ NotAuthorizedException
1310
+ The principle specified by the user_id does not have authorization for the requested action
1311
+
1312
+ """
1313
+ cascade_s = str(cascade).lower()
1314
+ url = (
1315
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/"
1316
+ f"{project_guid}/delete"
1317
+ )
1318
+
1319
+ await self._async_delete_element_request(url, body, cascade)
1320
+ logger.info(f"Deleted project {project_guid} with cascade {cascade}")
1321
+
1322
+ @dynamic_catch
1323
+ def delete_project(
1324
+ self,
1325
+ project_guid: str, cascade: bool = False, body: Optional[dict | DeleteElementRequestBody] = None) -> None:
1326
+ """Delete a project. It is detected from all parent elements.
1327
+
1328
+ Parameters
1329
+ ----------
1330
+ project_guid: str
1331
+ The guid of the collection to update.
1332
+ cascade: bool, optional, defaults to False
1333
+ If true, then all anchored elements will be deleted.
1334
+
1335
+
1336
+ cascade: bool, optional, defaults to False
1337
+ If true, then all anchored elements will be deleted.
1338
+ Returns
1339
+ -------
1340
+ Nothing
1341
+
1342
+ Raises
1343
+ ------
1344
+
1345
+ PyegeriaInvalidParameterException
1346
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1347
+ PyegeriaAPIException
1348
+ Raised by the server when an issue arises in processing a valid request
1349
+ NotAuthorizedException
1350
+ The principle specified by the user_id does not have authorization for the requested action
1351
+
1352
+ """
1353
+ loop = asyncio.get_event_loop()
1354
+ loop.run_until_complete(self._async_delete_project(project_guid, cascade, body))
1355
+
1356
+ @dynamic_catch
1357
+ async def _async_set_project_dependency(self, project_guid: str,
1358
+ upstream_project_guid: str,
1359
+ body: Optional[dict | NewRelationshipRequestBody] = None):
1360
+ """ A project depends on an upstream project.
1361
+ Request body is optional. Async version.
1362
+
1363
+ Parameters
1364
+ ----------
1365
+ upstream_project_guid: str
1366
+ The guid of the project depended on.
1367
+ project_guid: str
1368
+ The guid of the dependent project
1369
+ body: dict | NewRelationshipRequestBody, optional, default = None
1370
+ A dict representing the details of the relationship.
1371
+
1372
+ Returns
1373
+ -------
1374
+ Nothing
1375
+
1376
+ Raises
1377
+ ------
1378
+ PyegeriaInvalidParameterException
1379
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1380
+ PyegeriaAPIException
1381
+ Raised by the server when an issue arises in processing a valid request
1382
+ NotAuthorizedException
1383
+ The principle specified by the user_id does not have authorization for the requested action
1384
+
1385
+ Notes
1386
+ -----
1387
+
1388
+ """
1389
+ url = (
1390
+ f"{self.project_command_base}/{project_guid}/project-dependencies/{upstream_project_guid}/attach"
1391
+ )
1392
+ await self._async_new_relationship_request(url, "ProjectDependencyProperties", body)
1393
+ logger.info(f"Project {project_guid} depends on -> {upstream_project_guid}")
1394
+
1395
+ @dynamic_catch
1396
+ def set_project_dependency(self, project_guid: str,
1397
+ upstream_project_guid: str,
1398
+ body: Optional[dict | NewRelationshipRequestBody] = None):
1399
+ """ Link two dependent digital products. The linked elements are of type DigitalProduct.
1400
+ Request body is optional.
1401
+
1402
+ Parameters
1403
+ ----------
1404
+ upstream_digital_prod_guid: str
1405
+ The guid of the first digital product
1406
+ downstream_digital_prod_guid: str
1407
+ The guid of the downstream digital product
1408
+ body: dict | NewRelationshipRequestBody, optional, default = None
1409
+ A structure representing the details of the relationship.
1410
+
1411
+ Returns
1412
+ -------
1413
+ Nothing
1414
+
1415
+ Raises
1416
+ ------
1417
+ PyegeriaInvalidParameterException
1418
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1419
+ PyegeriaAPIException
1420
+ Raised by the server when an issue arises in processing a valid request
1421
+ NotAuthorizedException
1422
+ The principle specified by the user_id does not have authorization for the requested action
1423
+
1424
+ Notes
1425
+ -----
1426
+
1427
+ """
1428
+ loop = asyncio.get_event_loop()
1429
+ loop.run_until_complete(
1430
+ self._async_set_project_dependency(project_guid, upstream_project_guid,
1431
+ body))
1432
+
1433
+ @dynamic_catch
1434
+ async def _async_clear_project_dependency(self, project_guid: str,
1435
+ upstream_project_guid: str,
1436
+ body: Optional[dict | DeleteRelationshipRequestBody] = None) -> None:
1437
+ """ Unlink two dependent projects. Request body is optional. Async version.
1438
+
1439
+ Parameters
1440
+ ----------
1441
+ project_guid: str
1442
+ The guid of the dependent project.
1443
+ upstream_project_guid: str
1444
+ The guid of the upstream digital project
1445
+ body: dict | DeleteRelationshipRequestBody, optional, default = None
1446
+ A structure representing the details of the relationship.
1447
+
1448
+ Returns
1449
+ -------
1450
+ Nothing
1451
+
1452
+ Raises
1453
+ ------
1454
+ PyegeriaInvalidParameterException
1455
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1456
+ PyegeriaAPIException
1457
+ Raised by the server when an issue arises in processing a valid request
1458
+ NotAuthorizedException
1459
+ The principle specified by the user_id does not have authorization for the requested action
1460
+
1461
+ Notes
1462
+ -----
1463
+ JSON Structure looks like:
1464
+ {
1465
+ "class": "DeleteRelationshipRequestBody",
1466
+ "externalSourceGUID": "add guid here",
1467
+ "externalSourceName": "add qualified name here",
1468
+ "effectiveTime": "{{$isoTimestamp}}",
1469
+ "forLineage": false,
1470
+ "forDuplicateProcessing": false
1471
+ }
1472
+
1473
+ """
1474
+
1475
+ url = "{self.project_command_base}/{project_guid}/project-dependencies/{upstream_project_guid}/detach"
1476
+
1477
+ await self._async_delete_relationship_request(url, body)
1478
+ logger.info(
1479
+ f"Detached project {project_guid} from -> {upstream_project_guid}")
1480
+
1481
+ @dynamic_catch
1482
+ def clear_project_dependency(self, project_guid: str, upstream_project_guid: str,
1483
+ body: Optional[dict | DeleteRelationshipRequestBody] = None):
1484
+ """ Unlink two dependent projects. Request body is optional.
1485
+
1486
+ Parameters
1487
+ ----------
1488
+ project_guid: str
1489
+ The guid of the dependent project.
1490
+ upstream_project_guid: str
1491
+ The guid of the upstream digital project
1492
+ body: dict | DeleteRelationshipRequestBody, optional, default = None
1493
+ A structure representing the details of the relationship.
1494
+
1495
+ Returns
1496
+ -------
1497
+ Nothing
1498
+
1499
+ Raises
1500
+ ------
1501
+ PyegeriaInvalidParameterException
1502
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1503
+ PyegeriaAPIException
1504
+ Raised by the server when an issue arises in processing a valid request
1505
+ NotAuthorizedException
1506
+ The principle specified by the user_id does not have authorization for the requested action
1507
+
1508
+ Notes
1509
+ -----
1510
+ JSON Structure looks like:
1511
+ {
1512
+ "class": "DeleteRelationshipRequestBody",
1513
+ "externalSourceGUID": "add guid here",
1514
+ "externalSourceName": "add qualified name here",
1515
+ "effectiveTime": "{{$isoTimestamp}}",
1516
+ "forLineage": false,
1517
+ "forDuplicateProcessing": false
1518
+ }
1519
+ """
1520
+ loop = asyncio.get_event_loop()
1521
+ loop.run_until_complete(
1522
+ self._async_clear_project_dependency(project_guid, upstream_project_guid, body))
1523
+
1524
+ @dynamic_catch
1525
+ async def _async_set_project_hierarchy(self, project_guid: str,
1526
+ parent_project_guid: str,
1527
+ body: Optional[dict | NewRelationshipRequestBody] = None):
1528
+ """ Set a hierarchy relationship between two projects.
1529
+ Request body is optional. Async version.
1530
+
1531
+
1532
+ Parameters
1533
+ ----------
1534
+ parent_project_guid: str
1535
+ The guid of the project depended on.
1536
+ project_guid: str
1537
+ The guid of the dependent project
1538
+ body: dict | NewRelationshipRequestBody, optional, default = None
1539
+ A dict representing the details of the relationship.
1540
+
1541
+ Returns
1542
+ -------
1543
+ Nothing
1544
+
1545
+ Raises
1546
+ ------
1547
+ PyegeriaInvalidParameterException
1548
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1549
+ PyegeriaAPIException
1550
+ Raised by the server when an issue arises in processing a valid request
1551
+ NotAuthorizedException
1552
+ The principle specified by the user_id does not have authorization for the requested action
1553
+
1554
+ Notes
1555
+ -----
1556
+
1557
+ """
1558
+ url = (
1559
+ f"{self.project_command_base}/{parent_project_guid}/project-dependencies/{project_guid}/attach"
1560
+ )
1561
+ await self._async_new_relationship_request(url, ["ProjectHierarchyProperties"], body)
1562
+ logger.info(f"Project {project_guid} managed by -> {parent_project_guid}")
1563
+
1564
+ @dynamic_catch
1565
+ def set_project_hierarchy(self, project_guid: str,
1566
+ parent_project_guid: str,
1567
+ body: Optional[dict | NewRelationshipRequestBody] = None):
1568
+ """ Link two dependent digital products. The linked elements are of type DigitalProduct.
1569
+ Request body is optional.
1570
+
1571
+ Parameters
1572
+ ----------
1573
+ upstream_digital_prod_guid: str
1574
+ The guid of the first digital product
1575
+ downstream_digital_prod_guid: str
1576
+ The guid of the downstream digital product
1577
+ body: dict | NewRelationshipRequestBody, optional, default = None
1578
+ A structure representing the details of the relationship.
1579
+
1580
+ Returns
1581
+ -------
1582
+ Nothing
1583
+
1584
+ Raises
1585
+ ------
1586
+ PyegeriaInvalidParameterException
1587
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1588
+ PyegeriaAPIException
1589
+ Raised by the server when an issue arises in processing a valid request
1590
+ NotAuthorizedException
1591
+ The principle specified by the user_id does not have authorization for the requested action
1592
+
1593
+ Notes
1594
+ -----
1595
+
1596
+ """
1597
+ loop = asyncio.get_event_loop()
1598
+ loop.run_until_complete(
1599
+ self._async_set_project_hierarchy(project_guid, parent_project_guid,
1600
+ body))
1601
+
1602
+ @dynamic_catch
1603
+ async def _async_clear_project_hierarchy(self, project_guid: str,
1604
+ parent_project_guid: str,
1605
+ body: Optional[dict | DeleteRelationshipRequestBody] = None) -> None:
1606
+ """ Unlink hierarchy relationship. Request body is optional. Async version.
1607
+
1608
+ Parameters
1609
+ ----------
1610
+ project_guid: str
1611
+ The guid of the dependent project.
1612
+ parent_project_guid: str
1613
+ The guid of the upstream digital project
1614
+ body: dict | DeleteRelationshipRequestBody, optional, default = None
1615
+ A structure representing the details of the relationship.
1616
+
1617
+ Returns
1618
+ -------
1619
+ Nothing
1620
+
1621
+ Raises
1622
+ ------
1623
+ PyegeriaInvalidParameterException
1624
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1625
+ PyegeriaAPIException
1626
+ Raised by the server when an issue arises in processing a valid request
1627
+ NotAuthorizedException
1628
+ The principle specified by the user_id does not have authorization for the requested action
1629
+
1630
+ Notes
1631
+ -----
1632
+ JSON Structure looks like:
1633
+ {
1634
+ "class": "DeleteRelationshipRequestBody",
1635
+ "externalSourceGUID": "add guid here",
1636
+ "externalSourceName": "add qualified name here",
1637
+ "effectiveTime": "{{$isoTimestamp}}",
1638
+ "forLineage": false,
1639
+ "forDuplicateProcessing": false
1640
+ }
1641
+
1642
+ """
1643
+
1644
+ url = "{self.project_command_base}/{parent_project_guid}/project-dependencies/{project_guid}/detach"
1645
+
1646
+ await self._async_delete_relationship_request(url, body)
1647
+ logger.info(
1648
+ f"Detached project {project_guid} from -> {parent_project_guid}")
1649
+
1650
+ @dynamic_catch
1651
+ def clear_project_hierarchy(self, project_guid: str, parent_project_guid: str,
1652
+ body: Optional[dict | DeleteRelationshipRequestBody] = None):
1653
+ """ Unlink two dependent projects. Request body is optional.
1654
+
1655
+ Parameters
1656
+ ----------
1657
+ project_guid: str
1658
+ The guid of the dependent project.
1659
+ parent_project_guid: str
1660
+ The guid of the upstream digital project
1661
+ body: dict | DeleteRelationshipRequestBody, optional, default = None
1662
+ A structure representing the details of the relationship.
1663
+
1664
+ Returns
1665
+ -------
1666
+ Nothing
1667
+
1668
+ Raises
1669
+ ------
1670
+ PyegeriaInvalidParameterException
1671
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1672
+ PyegeriaAPIException
1673
+ Raised by the server when an issue arises in processing a valid request
1674
+ NotAuthorizedException
1675
+ The principle specified by the user_id does not have authorization for the requested action
1676
+
1677
+ Notes
1678
+ -----
1679
+ JSON Structure looks like:
1680
+ {
1681
+ "class": "DeleteRelationshipRequestBody",
1682
+ "externalSourceGUID": "add guid here",
1683
+ "externalSourceName": "add qualified name here",
1684
+ "effectiveTime": "{{$isoTimestamp}}",
1685
+ "forLineage": false,
1686
+ "forDuplicateProcessing": false
1687
+ }
1688
+ """
1689
+ loop = asyncio.get_event_loop()
1690
+ loop.run_until_complete(
1691
+ self._async_clear_project_hierarchy(project_guid, parent_project_guid, body))
1692
+
1693
+ @dynamic_catch
1694
+ async def _async_add_to_project_team(
1695
+ self,
1696
+ project_guid: str,
1697
+ actor_guid: str,
1698
+ assignment_type: Optional[str] = None,
1699
+ description: Optional[str] = None,
1700
+ body: Optional[dict | NewRelationshipRequestBody] = None
1701
+ ) -> None:
1702
+ """Add an actor to a project. The request body is optional. If supplied, it contains the name of the perspective that
1703
+ the actor plays in the project. Async version.
1704
+
1705
+ Parameters
1706
+ ----------
1707
+ project_guid: str
1708
+ identity of the project to update.
1709
+ actor_guid: str
1710
+ identity of the actor to add.
1711
+ team_role: str, optional, defaults to None
1712
+ Name of the perspective the actor plays in the project.
1713
+ effective_from: str, optional, defaults to None
1714
+ Date at which the actor becomes active in the project. Date format is ISO 8601 string format.
1715
+ effective_to: str, optional, defaults to None
1716
+ Date at which the actor is no longer active in the project. Date format is ISO 8601 string format.
1717
+
1718
+ Returns
1719
+ -------
1720
+ None
1721
+
1722
+ Raises
1723
+ ------
1724
+
1725
+ PyegeriaInvalidParameterException
1726
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1727
+ PyegeriaAPIException
1728
+ Raised by the server when an issue arises in processing a valid request
1729
+ NotAuthorizedException
1730
+ The principle specified by the user_id does not have authorization for the requested action
1731
+
1732
+ """
1733
+
1734
+ url = (
1735
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/{project_guid}/"
1736
+ f"members/{actor_guid}/attach"
1737
+ )
1738
+ if body is None:
1739
+ body = {
1740
+ "class": "NewRelationshipRequestBody",
1741
+ "properties": {
1742
+ "class": "AssignmentScopeProperties",
1743
+ "description": description,
1744
+ "assignmentType": assignment_type,
1745
+ }
1746
+ }
1747
+ body_s = body_slimmer(body)
1748
+
1749
+ await self._async_new_relationship_request(url, ["AssignmentScopeProperties"], body)
1750
+ logger.info(f"Added member {actor_guid} to project {project_guid}")
1751
+
1752
+ @dynamic_catch
1753
+ def add_to_project_team(
1754
+ self,
1755
+ project_guid: str,
1756
+ actor_guid: str,
1757
+ assignment_type: Optional[str] = None,
1758
+ description: Optional[str] = None,
1759
+ body: Optional[dict | NewRelationshipRequestBody] = None
1760
+ ) -> None:
1761
+ """Add an actor to a project. The request body is optional. If supplied, it contains the name of the perspective that
1762
+ the actor plays in the project.
1763
+
1764
+ Parameters
1765
+ ----------
1766
+ project_guid: str
1767
+ identity of the project to update.
1768
+ actor_guid: str
1769
+ identity of the actor to add.
1770
+ team_role: str, optional, defaults to None
1771
+ Name of the perspective the actor plays in the project.
1772
+ effective_from: str, optional, defaults to None
1773
+ Date at which the actor becomes active in the project. Date format is ISO 8601 string format.
1774
+ effective_to: str, optional, defaults to None
1775
+ Date at which the actor is no longer active in the project. Date format is ISO 8601 string format.
1776
+
1777
+ Returns
1778
+ -------
1779
+ None
1780
+
1781
+ Raises
1782
+ ------
1783
+
1784
+ PyegeriaInvalidParameterException
1785
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1786
+ PyegeriaAPIException
1787
+ Raised by the server when an issue arises in processing a valid request
1788
+ NotAuthorizedException
1789
+ The principle specified by the user_id does not have authorization for the requested action
1790
+
1791
+ """
1792
+ loop = asyncio.get_event_loop()
1793
+ loop.run_until_complete(
1794
+ self._async_add_to_project_team(
1795
+ project_guid,
1796
+ actor_guid,
1797
+ assignment_type,
1798
+ description,
1799
+ body,
1800
+ )
1801
+ )
1802
+
1803
+ @dynamic_catch
1804
+ async def _async_remove_from_project_team(
1805
+ self,
1806
+ project_guid: str,
1807
+ actor_guid: str,
1808
+ body: Optional[dict | DeleteRelationshipRequestBody] = None
1809
+ ) -> None:
1810
+ """Remove an actor from a project. Async version.
1811
+
1812
+ Parameters
1813
+ ----------
1814
+ project_guid: str
1815
+ identity of the project to remove members from.
1816
+ actor_guid: str
1817
+ identity of the actor to remove.
1818
+
1819
+ Returns
1820
+ -------
1821
+ None
1822
+
1823
+ Raises
1824
+ ------
1825
+
1826
+ PyegeriaInvalidParameterException
1827
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1828
+ PyegeriaAPIException
1829
+ Raised by the server when an issue arises in processing a valid request
1830
+ NotAuthorizedException
1831
+ The principle specified by the user_id does not have authorization for the requested action
1832
+
1833
+ """
1834
+
1835
+ url = (
1836
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/project-manager/projects/{project_guid}/"
1837
+ f"members/{actor_guid}/detach"
1838
+ )
1839
+
1840
+ await self._async_delete_relationship_request(url, body)
1841
+ logger.info(f"Removed member {actor_guid} from project {project_guid}")
1842
+
1843
+ @dynamic_catch
1844
+ def remove_from_project_team(
1845
+ self,
1846
+ project_guid: str,
1847
+ actor_guid: str,
1848
+ body: Optional[dict | DeleteRelationshipRequestBody] = None
1849
+ ) -> None:
1850
+ """Remove an actor from a project.
1851
+
1852
+ Parameters
1853
+ ----------
1854
+ project_guid: str
1855
+ identity of the project.
1856
+ actor_guid: str
1857
+ identity of the actor to remove.
1858
+
1859
+ Returns
1860
+ -------
1861
+ None
1862
+
1863
+ Raises
1864
+ ------
1865
+
1866
+ PyegeriaInvalidParameterException
1867
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1868
+ PyegeriaAPIException
1869
+ Raised by the server when an issue arises in processing a valid request
1870
+ NotAuthorizedException
1871
+ The principle specified by the user_id does not have authorization for the requested action
1872
+
1873
+ """
1874
+ loop = asyncio.get_event_loop()
1875
+ loop.run_until_complete(
1876
+ self._async_remove_from_project_team(project_guid, actor_guid, body)
1877
+ )
1878
+
1879
+ @dynamic_catch
1880
+ async def _async_create_task_for_project(
1881
+ self,
1882
+ project_guid: str,
1883
+ body: dict | NewElementRequestBody
1884
+ ) -> str:
1885
+ """Create a new task for a project. Async version."""
1886
+
1887
+ url = f"{self.project_command_base}/{project_guid}/task"
1888
+ response = await self._async_new_element_request(url, body)
1889
+ logger.info(f"Created task for project {project_guid}")
1890
+ return response
1891
+
1892
+ @dynamic_catch
1893
+ def create_task_for_project(
1894
+ self,
1895
+ project_guid: str,
1896
+ body: dict | NewElementRequestBody
1897
+ ) -> str:
1898
+ """Create a new task for a project. """
1899
+ loop = asyncio.get_event_loop()
1900
+ resp = loop.run_until_complete(
1901
+ self._async_create_task_for_project(project_guid, body)
1902
+ )
1903
+ return resp
1904
+
1905
+
1906
+ if __name__ == "__main__":
1907
+ print("Main-Project Manager")