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
@@ -4,39 +4,42 @@ This file contains general utility functions for processing Egeria Markdown
4
4
  import json
5
5
  import os
6
6
  import sys
7
- from typing import List, Optional
7
+ import re
8
+ from typing import Optional
8
9
 
9
10
  from loguru import logger
11
+ from pydantic import ValidationError
10
12
  from rich import print
11
13
  from rich.markdown import Markdown
12
14
  from rich.console import Console
13
-
14
- from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, get_element_dictionary,
15
- update_element_dictionary,
16
- split_tb_string, str_to_bool, )
15
+ from pyegeria.core.utils import parse_to_dict
16
+ from pyegeria.core.config import settings
17
+ from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, split_tb_string, str_to_bool, )
17
18
  from md_processing.md_processing_utils.extraction_utils import (process_simple_attribute, extract_attribute,
18
19
  get_element_by_name)
19
- from md_processing.md_processing_utils.common_md_utils import (update_element_dictionary, set_gov_prop_body, \
20
- set_update_body, set_create_body,
21
- set_peer_gov_def_request_body, set_rel_request_body,
22
- set_delete_request_body,set_rel_request_body,
23
- set_filter_request_body, setup_log,
24
- ALL_GOVERNANCE_DEFINITIONS, set_find_body)
25
- from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
26
- from md_processing.md_processing_utils.md_processing_constants import (get_command_spec)
27
- from md_processing.md_processing_utils.message_constants import (ERROR, INFO, WARNING, ALWAYS, EXISTS_REQUIRED)
28
- from pyegeria import EgeriaTech, select_output_format_set
20
+ from md_processing.md_processing_utils.common_md_utils import (update_element_dictionary, set_find_body)
21
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus)
22
+ from md_processing.md_processing_utils.md_processing_constants import (get_command_spec, add_default_upsert_attributes,
23
+ add_default_link_attributes)
24
+ from md_processing.md_processing_utils.message_constants import (ERROR, INFO, WARNING, EXISTS_REQUIRED)
25
+ from pyegeria import EgeriaTech, PyegeriaException
26
+ from pyegeria.view.base_report_formats import select_report_spec
27
+ from pyegeria.core._exceptions import print_basic_exception, print_validation_error, print_basic_exception
28
+ from pyegeria.core._globals import DEBUG_LEVEL
29
29
 
30
- from pyegeria._globals import DEBUG_LEVEL
30
+ debug_level = DEBUG_LEVEL
31
+ global COMMAND_DEFINITIONS
31
32
 
33
+ user_config = settings.User_Profile
32
34
 
33
35
  # Constants
34
36
  EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "200"))
35
- EGERIA_USAGE_LEVEL = os.environ.get("EGERIA_USAGE_LEVEL", "Basic")
37
+ EGERIA_USAGE_LEVEL = os.environ.get("EGERIA_USAGE_LEVEL", user_config.egeria_usage_level)
38
+ LOCAL_QUALIFIER = os.environ.get("EGERIA_LOCAL_QUALIFIER", None)
36
39
  console = Console(width=EGERIA_WIDTH)
37
40
 
38
- debug_level = DEBUG_LEVEL
39
- global COMMAND_DEFINITIONS
41
+
42
+
40
43
 
41
44
 
42
45
  @logger.catch
@@ -59,7 +62,7 @@ def process_provenance_command(file_path: str, txt: [str]) -> str:
59
62
 
60
63
  @logger.catch
61
64
  def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
62
- directive: str = "display") -> dict:
65
+ directive: str = "display", body_type: str = None) -> dict:
63
66
  parsed_attributes, parsed_output = {}, {}
64
67
 
65
68
  parsed_output['valid'] = True
@@ -68,8 +71,12 @@ def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_act
68
71
  display_name = ""
69
72
  labels = {}
70
73
 
71
- command_spec = get_command_spec(f"Create {object_type}")
72
- attributes = command_spec.get('Attributes', [])
74
+ command_spec = get_command_spec(f"Create {object_type}", body_type = body_type)
75
+ if command_spec is None:
76
+ logger.error("Command not found in command spec")
77
+ raise Exception("Command not found in command spec")
78
+ distinguished_attributes = command_spec.get('Attributes', [])
79
+ attributes = add_default_upsert_attributes(distinguished_attributes)
73
80
  command_display_name = command_spec.get('display_name', None)
74
81
  command_qn_prefix = command_spec.get('qn_prefix', None)
75
82
 
@@ -89,131 +96,160 @@ def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_act
89
96
 
90
97
  for attr in attributes:
91
98
  for key in attr:
92
- # Run some checks to see if the attribute is appropriate to the operation and usage level
93
- for_update = attr[key].get('inUpdate', True)
94
- level = attr[key].get('level', 'Basic')
95
- msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
96
- f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` and attribute level `{level}` and for_update `"
97
- f"{for_update}`\n")
98
- logger.trace(msg)
99
- if for_update is False and object_action == "Update":
100
- logger.trace(f"Attribute `{key}`is not allowed for `Update`", highlight=True)
101
- continue
102
- if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
103
- logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
104
- highlight=True)
105
- continue
106
- if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
107
- logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
108
- highlight=True)
109
- continue
110
- if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
111
- logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
112
- highlight=True)
113
- continue
114
-
115
- if attr[key].get('input_required', False) is True:
116
- if_missing = ERROR
117
- else:
118
- if_missing = INFO
119
-
120
- # lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
121
- lab = split_tb_string(attr[key]['attr_labels'])
122
- labels: set = set()
123
- labels.add(key.strip())
124
- if key == 'Display Name':
125
- labels.add(object_type.strip())
126
- if lab is not None and lab != [""]:
127
- labels.update(lab)
128
-
129
- default_value = attr[key].get('default_value', None)
130
-
131
- style = attr[key]['style']
132
- if style in ['Simple', 'Comment']:
133
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
134
- elif style == 'Dictionary':
135
- parsed_attributes[key] = proc_dictionary_attribute(txt, object_action, labels, if_missing, default_value)
136
- parsed_attributes[key]['name_list'] = json.dumps(parsed_attributes[key]['value'], indent=2)
137
-
138
- elif style == 'Valid Value':
139
- parsed_attributes[key] = proc_valid_value(txt, object_action, labels,
140
- attr[key].get('valid_values', None), if_missing,
141
- default_value)
142
- elif style == 'QN':
143
- parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
144
- object_action, version, if_missing)
145
- if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
146
- 'exists'] is False:
147
- parsed_output['exists'] = False
148
- elif style == 'ID':
149
- parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
150
- object_action, version, if_missing)
151
-
152
- parsed_output['guid'] = parsed_attributes[key].get('guid', None)
153
- parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
154
- parsed_output['exists'] = parsed_attributes[key]['exists']
155
- if parsed_attributes[key]['valid'] is False:
156
- parsed_output['valid'] = False
157
- parsed_output['reason'] += parsed_attributes[key]['reason']
158
-
159
- elif style == 'Reference Name':
160
- parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
161
- if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) and parsed_attributes[key][
162
- 'exists'] is False):
163
- msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
164
- logger.error(msg)
165
- parsed_output['valid'] = False
166
- parsed_output['reason'] += msg
167
- elif parsed_attributes[key]['valid'] is False:
168
- parsed_output['valid'] = False
169
- parsed_output['reason'] += parsed_attributes[key]['reason']
170
-
171
- elif style == 'GUID':
172
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
173
- elif style == 'Ordered Int':
174
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
175
- elif style == 'Simple Int':
176
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
177
- elif style == 'Simple List':
178
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
179
- name_list = parsed_attributes[key]['value']
180
- # attribute = re.split(r'[;,\n]+', name_list) if name_list is not None else None
181
- attribute = split_tb_string(name_list)
182
- parsed_attributes[key]['value'] = attribute
183
- parsed_attributes[key]['name_list'] = name_list
184
- elif style == 'Parent':
185
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
186
- elif style == 'Bool':
187
- parsed_attributes[key] = proc_bool_attribute(txt, object_action, labels, if_missing, default_value)
188
- elif style == "Dictionary List":
189
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
190
- parsed_attributes[key]['list'] = json.loads(parsed_attributes[key]['value'])
191
-
99
+ try:
100
+ # Run some checks to see if the attribute is appropriate to the operation and usage level
101
+ for_update = attr[key].get('inUpdate', True)
102
+ level = attr[key].get('level', 'Basic')
103
+ msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
104
+ f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` and attribute level `{level}` and for_update `"
105
+ f"{for_update}`\n")
106
+ logger.trace(msg)
107
+ if for_update is False and object_action == "Update":
108
+ logger.trace(f"Attribute `{key}`is not allowed for `Update`", highlight=True)
109
+ continue
110
+ if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
111
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
112
+ highlight=True)
113
+ continue
114
+ if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
115
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
116
+ highlight=True)
117
+ continue
118
+ if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
119
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
120
+ highlight=True)
121
+ continue
192
122
 
193
- elif style == 'Reference Name List':
194
- parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
195
- if (parsed_attributes[key].get("value", None) and (
196
- parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
197
- msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
198
- f"does not exist")
123
+ if attr[key].get('input_required', False) is True:
124
+ if_missing = ERROR
125
+ else:
126
+ if_missing = INFO
127
+
128
+ # lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
129
+ lab = split_tb_string(attr[key]['attr_labels'])
130
+ labels: set = set()
131
+ labels.add(key.strip())
132
+ if key == 'Display Name':
133
+ labels.add(object_type.strip())
134
+ if lab is not None and lab != [""]:
135
+ labels.update(lab)
136
+
137
+ default_value = attr[key].get('default_value', None)
138
+
139
+ style = attr[key]['style']
140
+ if style in ['Simple', 'Comment']:
141
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
142
+ elif style in ['Dictionary', "Named DICT"]:
143
+ parsed_attributes[key] = proc_dictionary_attribute(txt, object_action, labels, if_missing, default_value)
144
+ if key in parsed_attributes and parsed_attributes[key] is not None:
145
+ if parsed_attributes[key].get('value', None) is not None:
146
+ if isinstance(parsed_attributes[key]['value'], dict):
147
+ parsed_attributes[key]['dict'] = json.dumps(parsed_attributes[key]['value'], indent=2)
148
+ else:
149
+ continue
150
+ else:
151
+ continue
152
+
153
+ elif style == 'Valid Value':
154
+ parsed_attributes[key] = proc_valid_value(txt, object_action, labels,
155
+ attr[key].get('valid_values', None), if_missing,
156
+ default_value)
157
+ elif style == 'QN':
158
+ parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
159
+ object_action, version, if_missing)
160
+ if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
161
+ 'exists'] is False:
162
+ parsed_output['exists'] = False
163
+ elif style == 'ID':
164
+ parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
165
+ object_action, version, if_missing)
166
+
167
+ parsed_output['guid'] = parsed_attributes[key].get('guid', None)
168
+ parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
169
+ parsed_output['exists'] = parsed_attributes[key]['exists']
170
+ if parsed_attributes[key]['valid'] is False:
171
+ parsed_output['valid'] = False
172
+ parsed_output['reason'] += parsed_attributes[key]['reason']
173
+
174
+ elif style == 'Reference Name':
175
+ parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
176
+ if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) and parsed_attributes[key][
177
+ 'exists'] is False):
178
+ msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
179
+ logger.error(msg)
180
+ parsed_output['valid'] = False
181
+ parsed_output['reason'] += msg
182
+ elif parsed_attributes[key]['valid'] is False:
183
+ parsed_output['valid'] = False
184
+ parsed_output['reason'] += parsed_attributes[key]['reason']
185
+
186
+ elif style == 'GUID':
187
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
188
+ g = parsed_attributes[key].get('value', None)
189
+ if g and ("___" not in g and "---" not in g):
190
+ parsed_output['guid'] = parsed_attributes[key]['value']
191
+ elif style == 'Ordered Int':
192
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
193
+ elif style == 'Simple Int':
194
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
195
+ elif style == 'Simple List':
196
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "list")
197
+ name_list = parsed_attributes[key]['value']
198
+ # attribute = re.split(r'[;,\n]+', name_list) if name_list is not None else None
199
+ attribute = split_tb_string(name_list)
200
+ parsed_attributes[key]['value'] = attribute
201
+ parsed_attributes[key]['name_list'] = name_list
202
+ elif style == 'Parent':
203
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
204
+ elif style == 'Bool':
205
+ parsed_attributes[key] = proc_bool_attribute(txt, object_action, labels, if_missing, default_value)
206
+ elif style == "Dictionary List":
207
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
208
+ parsed_attributes[key]['list'] = json.loads(parsed_attributes[key]['value'])
209
+
210
+
211
+ elif style == 'Reference Name List':
212
+ parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
213
+ if (parsed_attributes[key].get("value", None) and (
214
+ parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
215
+ msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
216
+ f"does not exist")
217
+ logger.error(msg)
218
+ parsed_output['valid'] = False
219
+ parsed_output['reason'] += msg
220
+ else:
221
+ msg = f"Unknown attribute style: {style} for key `{key}`"
199
222
  logger.error(msg)
200
- parsed_output['valid'] = False
201
- parsed_output['reason'] += msg
202
- else:
203
- msg = f"Unknown attribute style: {style} for key `{key}`"
204
- logger.error(msg)
205
- sys.exit(1)
223
+ sys.exit(1)
224
+ parsed_attributes[key]['valid'] = False
225
+ parsed_attributes[key]['value'] = None
226
+ if key == "Display Name":
227
+ display_name = parsed_attributes[key]['value']
228
+
229
+ value = parsed_attributes[key].get('value', None)
230
+
231
+ if value is not None:
232
+ if isinstance(value, list):
233
+ list_out = f"\n\t* {key}:\n\n"
234
+ for item in value:
235
+ list_out += f"\t{item}\n"
236
+ parsed_output['display'] += list_out
237
+ elif isinstance(value, dict):
238
+ list_out = f"\n\t* {key}:\n\n"
239
+ for k, v in value.items():
240
+ list_out += f"\t{k}: \n\t\t{v}\n"
241
+ parsed_output['display'] += list_out
242
+ else:
243
+ parsed_output['display'] += f"\n\t* {key}: \n`{value}`\n\t"
244
+ except PyegeriaException as e:
245
+ logger.error(f"PyegeriaException occurred: {e}")
246
+
247
+ print_basic_exception(e)
248
+
249
+ except ValidationError as e:
206
250
  parsed_attributes[key]['valid'] = False
207
251
  parsed_attributes[key]['value'] = None
208
- if key == "Display Name":
209
- display_name = parsed_attributes[key]['value']
210
-
211
- value = parsed_attributes[key].get('value', None)
212
-
213
- if value is not None:
214
- # if the value is a dict, get the flattened name list
215
- value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
216
- parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
252
+ print_validation_error(e)
217
253
 
218
254
 
219
255
  parsed_output['attributes'] = parsed_attributes
@@ -227,8 +263,8 @@ def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_act
227
263
 
228
264
 
229
265
  if parsed_attributes.get('Parent ID', {}).get('value', None) is not None:
230
- if (parsed_attributes['Parent Relationship Type Name']['value'] is None) or (
231
- parsed_attributes['Parent at End1']['value'] is None):
266
+ if (parsed_attributes.get('Parent Relationship Type Name',{}).get('value', None) is None) or (
267
+ parsed_attributes.get('Parent at End1',{}).get('value',None) is None):
232
268
  msg = "Parent ID was found but either Parent `Relationship Type Name` or `Parent at End1` are missing"
233
269
  logger.error(msg)
234
270
  parsed_output['valid'] = False
@@ -277,11 +313,21 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
277
313
  parsed_output['exists'] = False
278
314
 
279
315
  labels = {}
280
- if object_action in ["Unlink","Detach"]:
316
+ if object_action in ["Link", "Attach", "Unlink", "Detach"]:
281
317
  command_spec = get_command_spec(f"Link {object_type}")
318
+ if command_spec is None:
319
+ logger.error(f"Command specification not found for 'Link {object_type}'")
320
+ return None
321
+ distinguished_attributes = command_spec.get('distinguished_attributes', None)
322
+ if distinguished_attributes:
323
+ attributes = add_default_link_attributes(distinguished_attributes)
282
324
  else:
283
325
  command_spec = get_command_spec(f"{object_action} {object_type}")
284
- attributes = command_spec.get('Attributes', [])
326
+ if command_spec is None:
327
+ logger.error(f"Command specification not found for '{object_action} {object_type}'")
328
+ return None
329
+ attributes = command_spec.get('Attributes', None)
330
+
285
331
  command_display_name = command_spec.get('display_name', None)
286
332
 
287
333
  parsed_output['reason'] = ""
@@ -290,6 +336,17 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
290
336
  msg = f"\tProcessing {object_action} on {object_type} \n"
291
337
  logger.info(msg)
292
338
 
339
+ # Helper: convert label to snake_case
340
+ def _to_snake_case(name: str) -> str:
341
+ name = name.strip()
342
+ # Replace non-alphanumeric with space, then collapse spaces to underscores
343
+ name = re.sub(r"[^0-9A-Za-z]+", "_", name)
344
+ # Lowercase and trim possible leading/trailing underscores
345
+ return name.strip("_").lower()
346
+
347
+ # Build known labels set from command spec
348
+ known_labels: set[str] = set()
349
+
293
350
  # get the version early because we may need it to construct qualified names.
294
351
 
295
352
  for attr in attributes:
@@ -327,6 +384,11 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
327
384
  if lab is not None and lab != [""]:
328
385
  labels.update(lab)
329
386
 
387
+ # Keep track of all known labels for later filtering of kwargs
388
+ for lab_entry in labels:
389
+ if lab_entry is not None and lab_entry != "":
390
+ known_labels.add(lab_entry.strip())
391
+
330
392
  # set these to none since not needed for view commands
331
393
  version = None
332
394
  command_qn_prefix = None
@@ -356,20 +418,20 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
356
418
 
357
419
  parsed_output['guid'] = parsed_attributes[key].get('guid', None)
358
420
  parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
359
- parsed_output['exists'] = parsed_attributes[key]['exists']
360
- if parsed_attributes[key]['valid'] is False:
421
+ parsed_output['exists'] = parsed_attributes.get(key,{}).get('exists',None)
422
+ if parsed_attributes.get(key,{}).get('valid',None) is False:
361
423
  parsed_output['valid'] = False
362
- parsed_output['reason'] += parsed_attributes[key]['reason']
424
+ parsed_output['reason'] += parsed_attributes.get(key,{}).get('reason',None)
363
425
 
364
426
  elif style == 'Reference Name':
365
427
  parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
366
428
  if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) is None):
367
- msg = f"Required parameter `{parsed_attributes[key]['value']}` is missing"
429
+ msg = f"Required parameter `{parsed_attributes.get(key,{}).get('value',None)}` is missing"
368
430
  logger.error(msg)
369
431
  parsed_output['valid'] = False
370
432
  parsed_output['reason'] += msg
371
- elif parsed_attributes[key]['value'] and parsed_attributes[key]['exists'] is False:
372
- msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
433
+ elif parsed_attributes.get(key,{}).get('value',None) and parsed_attributes.get(key,{}).get('exists',None) is False:
434
+ msg = f"Reference Name `{parsed_attributes.get(key,{}).get('value',None)}` is specified but does not exist"
373
435
  logger.error(msg)
374
436
  parsed_output['valid'] = False
375
437
  parsed_output['reason'] += msg
@@ -420,6 +482,26 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
420
482
 
421
483
  parsed_output['attributes'] = parsed_attributes
422
484
 
485
+ # Now, collect any unrecognized commands into kwargs
486
+ # Find all level-2 headings in the text
487
+ all_headings = set(re.findall(r"^\s*##\s*([^\n#]+)", txt, flags=re.MULTILINE))
488
+
489
+ kwargs: dict = {}
490
+ for heading in all_headings:
491
+ h = heading.strip()
492
+ if not h:
493
+ continue
494
+ if h in known_labels:
495
+ continue # already known/processed
496
+ # Parse this unknown attribute using the simple attribute logic
497
+ parsed = proc_simple_attribute(txt, object_action, {h}, INFO, None)
498
+ value = parsed.get('value', None)
499
+ if value is not None:
500
+ kwargs[_to_snake_case(h)] = value.replace('\n', '') if isinstance(value, str) else value
501
+
502
+ if kwargs:
503
+ parsed_output['kwargs'] = kwargs
504
+
423
505
 
424
506
  if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
425
507
  msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
@@ -459,7 +541,12 @@ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str =
459
541
 
460
542
  attribute = extract_attribute(txt, labels)
461
543
 
462
- attribute = default_value if attribute is None else attribute.replace('\n', '')
544
+ # attribute = default_value if attribute is None else attribute.replace('\n', '')
545
+ attribute = default_value if attribute is None else attribute
546
+ if isinstance(attribute, str):
547
+ attribute = re.sub(r'\n+', '\n', attribute)
548
+ attribute = None if attribute.startswith('___') or attribute.startswith('---') else attribute
549
+
463
550
 
464
551
  if attribute is None:
465
552
  if if_missing == INFO or if_missing == WARNING:
@@ -474,8 +561,10 @@ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str =
474
561
 
475
562
  if attribute and simp_type == "int" :
476
563
  attribute = int(attribute)
477
- elif attribute and simp_type == "list":
478
- attribute = list(attribute)
564
+ # elif attribute and simp_type == "list":
565
+ # if isinstance(attribute, str):
566
+ # attribute = [piece.strip() for piece in re.split(r'[,\n]', attribute) if piece.strip()]
567
+
479
568
 
480
569
 
481
570
  return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
@@ -509,8 +598,8 @@ def proc_dictionary_attribute(txt: str, action: str, labels: set, if_missing: st
509
598
  default_value = None
510
599
 
511
600
  attr = extract_attribute(txt, labels)
512
- attribute = json.loads(attr) if attr is not None else default_value
513
-
601
+ # attribute = json.loads(attr) if attr is not None else default_value
602
+ attribute = parse_to_dict(attr)
514
603
 
515
604
  if attribute is None:
516
605
  if if_missing == INFO or if_missing == WARNING:
@@ -735,7 +824,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
735
824
  logger.info(msg)
736
825
 
737
826
  if q_name is None and qualified_name is None:
738
- q_name = egeria_client.__create_qualified_name__(qn_prefix, element_name, version_identifier=version)
827
+ q_name = egeria_client.__create_qualified_name__(qn_prefix, element_name, LOCAL_QUALIFIER, version)
739
828
  update_element_dictionary(q_name, {'display_name': element_name})
740
829
 
741
830
  elif qualified_name:
@@ -792,6 +881,9 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
792
881
  element_name = extract_attribute(txt, element_labels)
793
882
 
794
883
  if element_name:
884
+ if element_type == "Tag ID": # Special case for informal tags
885
+ element_type = "InformalTag"
886
+
795
887
  if '\n' in element_name or ',' in element_name:
796
888
  msg = f"Element name `{element_name}` appears to be a list rather than a single element"
797
889
  logger.error(msg)
@@ -1063,7 +1155,7 @@ def process_output_command(egeria_client: EgeriaTech, txt: str, directive: str =
1063
1155
  """
1064
1156
  Processes a generic output request by extracting attributes (including Output Format and
1065
1157
  Output Format Set) and dynamically invoking the find function specified by the
1066
- output_format_set, following the approach used in commands/cat/list_format_set.
1158
+ report_spec, following the approach used in commands/cat/list_format_set.
1067
1159
 
1068
1160
  This is modeled on process_gov_definition_list_command but uses the dynamic
1069
1161
  dispatch via the output format set rather than directly calling a specific
@@ -1087,13 +1179,13 @@ def process_output_command(egeria_client: EgeriaTech, txt: str, directive: str =
1087
1179
 
1088
1180
  search_string = attr.get('Search String', {}).get('value', '*')
1089
1181
  output_format = attr.get('Output Format', {}).get('value', 'LIST')
1090
- output_format_set = attr.get('Output Format Set', {}).get('value', object_type)
1182
+ report_spec = attr.get('Output Format Set', {}).get('value', object_type)
1091
1183
 
1092
1184
  if directive == "display":
1093
1185
  return None
1094
1186
  elif directive == "validate":
1095
1187
  # Validate that the format set exists and has an action
1096
- fmt = select_output_format_set(output_format_set, "ANY") if valid else None
1188
+ fmt = select_report_spec(report_spec, "ANY") if valid else None
1097
1189
  if valid and fmt and fmt.get("action"):
1098
1190
  print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1099
1191
  return True
@@ -1110,9 +1202,9 @@ def process_output_command(egeria_client: EgeriaTech, txt: str, directive: str =
1110
1202
  return None
1111
1203
 
1112
1204
  # Resolve the find function from the output format set
1113
- fmt = select_output_format_set(output_format_set, output_format)
1205
+ fmt = select_report_spec(report_spec, output_format)
1114
1206
  if not fmt:
1115
- logger.error(f"Output format set '{output_format_set}' not found or not compatible with '{output_format}'.")
1207
+ logger.error(f"Output format set '{report_spec}' not found or not compatible with '{output_format}'.")
1116
1208
  return None
1117
1209
  action = fmt.get("action", {})
1118
1210
  func_spec = action.get("function")
@@ -1135,7 +1227,7 @@ def process_output_command(egeria_client: EgeriaTech, txt: str, directive: str =
1135
1227
  'search_string': search_string,
1136
1228
  'body': body,
1137
1229
  'output_format': output_format,
1138
- 'output_format_set': output_format_set,
1230
+ 'report_spec': report_spec,
1139
1231
  }
1140
1232
 
1141
1233
  # Call the resolved method
@@ -1145,7 +1237,7 @@ def process_output_command(egeria_client: EgeriaTech, txt: str, directive: str =
1145
1237
  list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
1146
1238
  else:
1147
1239
  list_md += struct
1148
- logger.info(f"Wrote `{object_type}` for search string: `{search_string}` using format set '{output_format_set}'")
1240
+ logger.info(f"Wrote `{object_type}` for search string: `{search_string}` using format set '{report_spec}'")
1149
1241
 
1150
1242
  return list_md
1151
1243