pyegeria 5.3.9.9.3__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 (272) hide show
  1. commands/__init__.py +24 -0
  2. commands/cat/Dr-Egeria_md-orig.py +2 -2
  3. commands/cat/__init__.py +1 -17
  4. commands/cat/collection_actions.py +197 -0
  5. commands/cat/dr_egeria_command_help.py +372 -0
  6. commands/cat/dr_egeria_jupyter.py +7 -7
  7. commands/cat/dr_egeria_md.py +27 -182
  8. commands/cat/exp_list_glossaries.py +11 -14
  9. commands/cat/get_asset_graph.py +37 -267
  10. commands/cat/{get_collection.py → get_collection_tree.py} +10 -18
  11. commands/cat/get_project_dependencies.py +14 -14
  12. commands/cat/get_project_structure.py +15 -14
  13. commands/cat/get_tech_type_elements.py +16 -116
  14. commands/cat/glossary_actions.py +145 -298
  15. commands/cat/list_assets.py +3 -11
  16. commands/cat/list_cert_types.py +17 -63
  17. commands/cat/list_collections.py +46 -138
  18. commands/cat/list_deployed_catalogs.py +15 -27
  19. commands/cat/list_deployed_database_schemas.py +27 -43
  20. commands/cat/list_deployed_databases.py +16 -31
  21. commands/cat/list_deployed_servers.py +35 -54
  22. commands/cat/list_glossaries.py +18 -17
  23. commands/cat/list_projects.py +10 -12
  24. commands/cat/list_tech_type_elements.py +21 -37
  25. commands/cat/list_tech_types.py +13 -25
  26. commands/cat/list_terms.py +38 -79
  27. commands/cat/list_todos.py +4 -11
  28. commands/cat/list_user_ids.py +3 -10
  29. commands/cat/my_reports.py +559 -0
  30. commands/cat/run_report.py +394 -0
  31. commands/cat/run_report_orig.py +528 -0
  32. commands/cli/egeria.py +222 -247
  33. commands/cli/egeria_cat.py +68 -81
  34. commands/cli/egeria_my.py +13 -0
  35. commands/cli/egeria_ops.py +69 -74
  36. commands/cli/egeria_tech.py +17 -93
  37. commands/cli/ops_config.py +3 -6
  38. commands/{cat/list_categories.py → deprecated/list_data_designer.py} +53 -64
  39. commands/{cat/list_data_structures.py → deprecated/list_data_structures_full.py} +3 -6
  40. commands/deprecated/old_get_asset_graph.py +315 -0
  41. commands/my/__init__.py +0 -2
  42. commands/my/list_my_profile.py +27 -34
  43. commands/my/list_my_roles.py +1 -7
  44. commands/my/monitor_my_todos.py +1 -7
  45. commands/my/monitor_open_todos.py +6 -7
  46. commands/my/todo_actions.py +4 -5
  47. commands/ops/__init__.py +0 -2
  48. commands/ops/gov_server_actions.py +17 -21
  49. commands/ops/list_archives.py +17 -38
  50. commands/ops/list_catalog_targets.py +33 -40
  51. commands/ops/load_archive.py +35 -26
  52. commands/ops/{monitor_engine_activity_c.py → monitor_active_engine_activity.py} +51 -82
  53. commands/ops/{monitor_integ_daemon_status.py → monitor_daemon_status.py} +35 -55
  54. commands/ops/monitor_engine_activity.py +79 -77
  55. commands/ops/{monitor_gov_eng_status.py → monitor_engine_status.py} +10 -7
  56. commands/ops/monitor_platform_status.py +38 -50
  57. commands/ops/monitor_server_startup.py +6 -11
  58. commands/ops/monitor_server_status.py +7 -11
  59. commands/ops/orig_monitor_server_list.py +8 -8
  60. commands/ops/orig_monitor_server_status.py +1 -5
  61. commands/ops/refresh_integration_daemon.py +5 -5
  62. commands/ops/restart_integration_daemon.py +5 -5
  63. commands/ops/table_integ_daemon_status.py +6 -6
  64. commands/ops/x_engine_actions.py +7 -7
  65. commands/tech/__init__.py +0 -2
  66. commands/tech/{generic_actions.py → element_actions.py} +6 -11
  67. commands/tech/get_element_info.py +20 -29
  68. commands/tech/get_guid_info.py +23 -42
  69. commands/tech/get_tech_details.py +20 -35
  70. commands/tech/get_tech_type_template.py +28 -39
  71. commands/tech/list_all_om_type_elements.py +24 -30
  72. commands/tech/list_all_om_type_elements_x.py +22 -28
  73. commands/tech/list_all_related_elements.py +19 -28
  74. commands/tech/list_anchored_elements.py +22 -30
  75. commands/tech/list_asset_types.py +19 -24
  76. commands/tech/list_elements_by_classification_by_property_value.py +26 -32
  77. commands/tech/list_elements_by_property_value.py +19 -25
  78. commands/tech/list_elements_by_property_value_x.py +20 -28
  79. commands/tech/list_elements_for_classification.py +28 -41
  80. commands/tech/list_gov_action_processes.py +16 -27
  81. commands/tech/list_information_supply_chains.py +22 -30
  82. commands/tech/list_registered_services.py +14 -26
  83. commands/tech/list_related_elements_with_prop_value.py +15 -25
  84. commands/tech/list_related_specification.py +1 -4
  85. commands/tech/list_relationship_types.py +15 -25
  86. commands/tech/list_relationships.py +20 -36
  87. commands/tech/list_solution_blueprints.py +28 -33
  88. commands/tech/list_solution_components.py +23 -29
  89. commands/tech/list_solution_roles.py +21 -32
  90. commands/tech/list_tech_templates.py +51 -54
  91. commands/tech/list_valid_metadata_values.py +5 -9
  92. commands/tech/table_tech_templates.py +2 -6
  93. commands/tech/x_list_related_elements.py +1 -4
  94. examples/GeoSpatial Products Example.py +524 -0
  95. examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
  96. examples/Jupyter Notebooks/README.md +2 -0
  97. examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
  98. examples/Jupyter Notebooks/common/__init__.py +14 -0
  99. examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
  100. examples/Jupyter Notebooks/common/environment-check.ipynb +52 -0
  101. examples/Jupyter Notebooks/common/globals.ipynb +184 -0
  102. examples/Jupyter Notebooks/common/globals.py +154 -0
  103. examples/Jupyter Notebooks/common/orig_globals.py +152 -0
  104. examples/format_sets/all_format_sets.json +910 -0
  105. examples/format_sets/custom_format_sets.json +268 -0
  106. examples/format_sets/subset_format_sets.json +187 -0
  107. examples/format_sets_save_load_example.py +291 -0
  108. examples/jacquard_data_sets.py +129 -0
  109. examples/output_formats_example.py +193 -0
  110. examples/test_jacquard_data_sets.py +54 -0
  111. examples/test_jacquard_data_sets_scenarios.py +94 -0
  112. md_processing/__init__.py +90 -0
  113. md_processing/command_dispatcher.py +33 -0
  114. md_processing/command_mapping.py +221 -0
  115. md_processing/data/commands/commands_data_designer.json +537 -0
  116. md_processing/data/commands/commands_external_reference.json +733 -0
  117. md_processing/data/commands/commands_feedback.json +155 -0
  118. md_processing/data/commands/commands_general.json +204 -0
  119. md_processing/data/commands/commands_glossary.json +218 -0
  120. md_processing/data/commands/commands_governance.json +3678 -0
  121. md_processing/data/commands/commands_product_manager.json +865 -0
  122. md_processing/data/commands/commands_project.json +642 -0
  123. md_processing/data/commands/commands_solution_architect.json +366 -0
  124. md_processing/data/commands.json +17568 -0
  125. md_processing/data/commands_working.json +30641 -0
  126. md_processing/data/gened_report_specs.py +6584 -0
  127. md_processing/data/generated_format_sets.json +6533 -0
  128. md_processing/data/generated_format_sets_old.json +4137 -0
  129. md_processing/data/generated_format_sets_old.py +45 -0
  130. md_processing/dr_egeria.py +182 -0
  131. md_processing/md_commands/__init__.py +3 -0
  132. md_processing/md_commands/data_designer_commands.py +1276 -0
  133. md_processing/md_commands/ext_ref_commands.py +530 -0
  134. md_processing/md_commands/feedback_commands.py +726 -0
  135. md_processing/md_commands/glossary_commands.py +684 -0
  136. md_processing/md_commands/governance_officer_commands.py +600 -0
  137. md_processing/md_commands/product_manager_commands.py +1266 -0
  138. md_processing/md_commands/project_commands.py +383 -0
  139. md_processing/md_commands/solution_architect_commands.py +1184 -0
  140. md_processing/md_commands/view_commands.py +295 -0
  141. md_processing/md_processing_utils/__init__.py +4 -0
  142. md_processing/md_processing_utils/common_md_proc_utils.py +1249 -0
  143. md_processing/md_processing_utils/common_md_utils.py +578 -0
  144. md_processing/md_processing_utils/determine_width.py +103 -0
  145. md_processing/md_processing_utils/extraction_utils.py +547 -0
  146. md_processing/md_processing_utils/gen_report_specs.py +643 -0
  147. md_processing/md_processing_utils/generate_dr_help.py +193 -0
  148. md_processing/md_processing_utils/generate_md_cmd_templates.py +144 -0
  149. md_processing/md_processing_utils/generate_md_templates.py +83 -0
  150. md_processing/md_processing_utils/md_processing_constants.py +1228 -0
  151. md_processing/md_processing_utils/message_constants.py +19 -0
  152. pyegeria/__init__.py +201 -443
  153. pyegeria/core/__init__.py +40 -0
  154. pyegeria/core/_base_platform_client.py +574 -0
  155. pyegeria/core/_base_server_client.py +573 -0
  156. pyegeria/core/_exceptions.py +457 -0
  157. pyegeria/core/_globals.py +60 -0
  158. pyegeria/core/_server_client.py +6073 -0
  159. pyegeria/core/_validators.py +257 -0
  160. pyegeria/core/config.py +654 -0
  161. pyegeria/{create_tech_guid_lists.py → core/create_tech_guid_lists.py} +0 -1
  162. pyegeria/core/load_config.py +37 -0
  163. pyegeria/core/logging_configuration.py +207 -0
  164. pyegeria/core/mcp_adapter.py +144 -0
  165. pyegeria/core/mcp_server.py +212 -0
  166. pyegeria/core/utils.py +405 -0
  167. pyegeria/deprecated/__init__.py +0 -0
  168. pyegeria/{_client.py → deprecated/_client.py} +62 -24
  169. pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
  170. pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1988 -1878
  171. pyegeria/deprecated/output_formatter_with_machine_keys.py +1127 -0
  172. pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +216 -229
  173. pyegeria/{valid_metadata_omvs.py → deprecated/valid_metadata_omvs.py} +93 -93
  174. pyegeria/{x_action_author_omvs.py → deprecated/x_action_author_omvs.py} +2 -3
  175. pyegeria/egeria_cat_client.py +25 -51
  176. pyegeria/egeria_client.py +140 -98
  177. pyegeria/egeria_config_client.py +48 -24
  178. pyegeria/egeria_tech_client.py +170 -83
  179. pyegeria/models/__init__.py +150 -0
  180. pyegeria/models/collection_models.py +168 -0
  181. pyegeria/models/models.py +654 -0
  182. pyegeria/omvs/__init__.py +84 -0
  183. pyegeria/omvs/action_author.py +342 -0
  184. pyegeria/omvs/actor_manager.py +5980 -0
  185. pyegeria/omvs/asset_catalog.py +842 -0
  186. pyegeria/omvs/asset_maker.py +2736 -0
  187. pyegeria/omvs/automated_curation.py +4403 -0
  188. pyegeria/omvs/classification_manager.py +11213 -0
  189. pyegeria/omvs/collection_manager.py +5780 -0
  190. pyegeria/omvs/community_matters_omvs.py +468 -0
  191. pyegeria/{core_omag_server_config.py → omvs/core_omag_server_config.py} +157 -157
  192. pyegeria/{data_designer_omvs.py → omvs/data_designer.py} +1991 -1691
  193. pyegeria/omvs/data_discovery.py +869 -0
  194. pyegeria/omvs/data_engineer.py +372 -0
  195. pyegeria/omvs/digital_business.py +1133 -0
  196. pyegeria/omvs/external_links.py +1752 -0
  197. pyegeria/omvs/feedback_manager.py +834 -0
  198. pyegeria/{full_omag_server_config.py → omvs/full_omag_server_config.py} +73 -69
  199. pyegeria/omvs/glossary_manager.py +3231 -0
  200. pyegeria/omvs/governance_officer.py +3009 -0
  201. pyegeria/omvs/lineage_linker.py +314 -0
  202. pyegeria/omvs/location_arena.py +1525 -0
  203. pyegeria/omvs/metadata_expert.py +668 -0
  204. pyegeria/omvs/metadata_explorer_omvs.py +2943 -0
  205. pyegeria/omvs/my_profile.py +1042 -0
  206. pyegeria/omvs/notification_manager.py +358 -0
  207. pyegeria/omvs/people_organizer.py +394 -0
  208. pyegeria/{platform_services.py → omvs/platform_services.py} +113 -193
  209. pyegeria/omvs/product_manager.py +1825 -0
  210. pyegeria/omvs/project_manager.py +1907 -0
  211. pyegeria/omvs/reference_data.py +1140 -0
  212. pyegeria/omvs/registered_info.py +334 -0
  213. pyegeria/omvs/runtime_manager.py +2817 -0
  214. pyegeria/omvs/schema_maker.py +446 -0
  215. pyegeria/{server_operations.py → omvs/server_operations.py} +27 -26
  216. pyegeria/omvs/solution_architect.py +6490 -0
  217. pyegeria/omvs/specification_properties.py +37 -0
  218. pyegeria/omvs/subject_area.py +1042 -0
  219. pyegeria/omvs/template_manager_omvs.py +236 -0
  220. pyegeria/omvs/time_keeper.py +1761 -0
  221. pyegeria/omvs/valid_metadata.py +3221 -0
  222. pyegeria/omvs/valid_metadata_lists.py +37 -0
  223. pyegeria/omvs/valid_type_lists.py +37 -0
  224. pyegeria/view/__init__.py +28 -0
  225. pyegeria/view/_output_format_models.py +514 -0
  226. pyegeria/view/_output_formats.py +14 -0
  227. pyegeria/view/base_report_formats.py +2719 -0
  228. pyegeria/view/dr_egeria_reports.py +56 -0
  229. pyegeria/view/format_set_executor.py +397 -0
  230. pyegeria/{md_processing_utils.py → view/md_processing_utils.py} +5 -5
  231. pyegeria/{mermaid_utilities.py → view/mermaid_utilities.py} +2 -154
  232. pyegeria/view/output_formatter.py +1297 -0
  233. pyegeria-5.5.3.3.dist-info/METADATA +218 -0
  234. pyegeria-5.5.3.3.dist-info/RECORD +241 -0
  235. {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info}/WHEEL +2 -1
  236. pyegeria-5.5.3.3.dist-info/entry_points.txt +103 -0
  237. pyegeria-5.5.3.3.dist-info/top_level.txt +4 -0
  238. commands/cat/.DS_Store +0 -0
  239. commands/cat/README.md +0 -16
  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/monitor_asset_events.py +0 -108
  244. commands/tech/README.md +0 -24
  245. pyegeria/.DS_Store +0 -0
  246. pyegeria/README.md +0 -35
  247. pyegeria/_globals.py +0 -47
  248. pyegeria/_validators.py +0 -385
  249. pyegeria/asset_catalog_omvs.py +0 -864
  250. pyegeria/automated_curation_omvs.py +0 -3765
  251. pyegeria/collection_manager_omvs.py +0 -2744
  252. pyegeria/dr.egeria spec.md +0 -9
  253. pyegeria/egeria_my_client.py +0 -56
  254. pyegeria/feedback_manager_omvs.py +0 -4573
  255. pyegeria/glossary_browser_omvs.py +0 -3728
  256. pyegeria/glossary_manager_omvs.py +0 -2440
  257. pyegeria/m_test.py +0 -118
  258. pyegeria/md_processing_helpers.py +0 -58
  259. pyegeria/md_processing_utils_orig.py +0 -1103
  260. pyegeria/metadata_explorer_omvs.py +0 -2326
  261. pyegeria/my_profile_omvs.py +0 -1022
  262. pyegeria/output_formatter.py +0 -389
  263. pyegeria/project_manager_omvs.py +0 -1933
  264. pyegeria/registered_info.py +0 -167
  265. pyegeria/solution_architect_omvs.py +0 -2156
  266. pyegeria/template_manager_omvs.py +0 -1414
  267. pyegeria/utils.py +0 -197
  268. pyegeria-5.3.9.9.3.dist-info/METADATA +0 -72
  269. pyegeria-5.3.9.9.3.dist-info/RECORD +0 -143
  270. pyegeria-5.3.9.9.3.dist-info/entry_points.txt +0 -99
  271. /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
  272. {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,684 @@
1
+ """
2
+ This file contains glossary-related object_action functions for processing Egeria Markdown
3
+ """
4
+
5
+ import json
6
+ from typing import List, Optional
7
+ from loguru import logger
8
+ from rich import print
9
+ from rich.markdown import Markdown
10
+
11
+ from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command,
12
+ sync_collection_memberships)
13
+ from md_processing.md_processing_utils.common_md_utils import set_update_body, \
14
+ set_element_prop_body, set_rel_request_body, set_create_body, set_object_classifications, set_rel_prop_body
15
+
16
+ from pyegeria import PyegeriaException, print_basic_exception
17
+
18
+ from md_processing.md_processing_utils.common_md_utils import (debug_level, print_msg, get_element_dictionary, update_element_dictionary,
19
+ )
20
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
21
+
22
+ from pyegeria.egeria_tech_client import EgeriaTech
23
+ from pyegeria.core.utils import make_format_set_name_from_type, body_slimmer
24
+
25
+
26
+ # EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "170"))
27
+ # console = Console(width=EGERIA_WIDTH)
28
+
29
+ def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories_exist: bool,
30
+ categories_list: List[str]) -> None:
31
+ """
32
+
33
+ Adds or removes a term to/from specified categories in a glossary.
34
+
35
+ This function associates a term, identified by its GUID, with one or more
36
+ categories. It uses the provided EgeriaTech client to assign the term
37
+ to the categories. If the GUID of a category is not readily available, it
38
+ is retrieved either from a pre-loaded dictionary or through a client lookup.
39
+
40
+ Args:
41
+ egeria_client (EgeriaTech): The client to interact with the glossary.
42
+ term_guid (str): The GUID of the term to be associated with categories.
43
+ categories_exist (bool): Flag indicating whether the categories already
44
+ exist.
45
+ categories_list (List[str]): A list of category names to associate with
46
+ the term.
47
+
48
+ Returns:
49
+ None
50
+ """
51
+ to_be_cat_guids: list[str] = []
52
+ # find the categories a term is currently in.
53
+ existing_categories = egeria_client.get_categories_for_term(term_guid)
54
+ if type(existing_categories) is str:
55
+ current_categories = []
56
+ else:
57
+ current_categories = [cat['elementHeader']['guid'] for cat in existing_categories]
58
+
59
+ if categories_exist is True and categories_list is not None:
60
+ if type(categories_list) is str:
61
+ categories_list = categories_list.split(",").trim()
62
+ for category in categories_list:
63
+ cat_guid = None
64
+ cat_el = category.strip()
65
+ element_dict = get_element_dictionary()
66
+ if cat_el in element_dict:
67
+ cat = element_dict.get(cat_el, None)
68
+ cat_guid = cat.get('guid', None) if cat else None
69
+ if cat_guid is None:
70
+ cat_guid = egeria_client.__get_guid__(qualified_name=cat_el)
71
+ update_element_dictionary(cat_el, {'guid': cat_guid})
72
+ to_be_cat_guids.append(cat_guid)
73
+
74
+ for cat in to_be_cat_guids:
75
+ if cat not in current_categories:
76
+ egeria_client.add_term_to_category(term_guid, cat)
77
+ current_categories.append(cat)
78
+ msg = f"Added term {term_guid} to category {cat}"
79
+ print_msg("DEBUG-INFO", msg, debug_level)
80
+
81
+ for cat in current_categories:
82
+ if cat not in to_be_cat_guids:
83
+ egeria_client.remove_term_from_category(term_guid, cat)
84
+ msg = f"Removed term {term_guid} from category {cat}"
85
+ print_msg("DEBUG-INFO", msg, debug_level)
86
+ else: # No categories specified - so remove any categories a term is in
87
+ for cat in current_categories:
88
+ egeria_client.remove_term_from_category(term_guid, cat)
89
+ msg = f"Removed term {term_guid} from category {cat}"
90
+ print_msg("DEBUG-INFO", msg, debug_level)
91
+
92
+
93
+ def process_glossary_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
94
+ """
95
+ Processes a glossary create or update object_action by extracting key attributes such as
96
+ glossary name, language, description, and usage from the given text.
97
+
98
+ :param txt: A string representing the input cell to be processed for
99
+ extracting glossary-related attributes.
100
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
101
+ :return: A string summarizing the outcome of the processing.
102
+ """
103
+
104
+ command, object_type, object_action = extract_command_plus(txt)
105
+ print(Markdown(f"# {command}\n"))
106
+
107
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
108
+ if not parsed_output:
109
+ logger.error(f"No output for `{object_action}`")
110
+ return None
111
+
112
+ valid = parsed_output['valid']
113
+ exists = parsed_output['exists']
114
+
115
+ qualified_name = parsed_output.get('qualified_name', None)
116
+ guid = parsed_output.get('guid', None)
117
+
118
+ print(Markdown(parsed_output['display']))
119
+
120
+ logger.debug(json.dumps(parsed_output, indent=4))
121
+
122
+ attributes = parsed_output['attributes']
123
+
124
+ display_name = attributes['Display Name'].get('value', None)
125
+ status = attributes.get('Status', {}).get('value', None)
126
+ #
127
+
128
+ if directive == "display":
129
+ return None
130
+ elif directive == "validate":
131
+ if valid:
132
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
133
+ else:
134
+ msg = f"Validation failed for object_action `{command}`\n"
135
+ return valid
136
+
137
+ elif directive == "process":
138
+ try:
139
+ obj = "Glossary"
140
+ # Set the property body for a glossary collection
141
+ #
142
+ prop_body = set_element_prop_body(obj, qualified_name, attributes)
143
+ prop_body["languager"] = attributes.get('Language', {}).get('value', None)
144
+ prop_body["usage"] = attributes.get('Usage', {}).get('value', None)
145
+
146
+ if object_action == "Update":
147
+ if not exists:
148
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
149
+ f"{object_action}\n")
150
+ logger.error(msg)
151
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
152
+ elif not valid:
153
+ return None
154
+ else:
155
+ print(Markdown(
156
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
157
+
158
+
159
+ body = set_update_body(obj, attributes)
160
+ body['properties'] = prop_body
161
+
162
+ egeria_client.update_collection(guid, body)
163
+ if status:
164
+ egeria_client.update_collection_status(guid, status)
165
+
166
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
167
+ update_element_dictionary(qualified_name, {
168
+ 'guid': guid, 'display_name': display_name
169
+ })
170
+ return egeria_client.get_collection_by_guid(guid, element_type='Glossary',
171
+ output_format='MD', report_spec = "DrE-Glossary")
172
+
173
+
174
+ elif object_action == "Create":
175
+ if valid is False and exists:
176
+ msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
177
+ f"`Create` to `Update` in processed output\n\n___")
178
+ logger.error(msg)
179
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
180
+
181
+ else:
182
+ body = set_create_body(object_type,attributes)
183
+
184
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
185
+ body["initialClassifications"] = set_object_classifications(object_type, attributes, ["Taxonomy", "CanonicalVocabulary"])
186
+ if object_type == "Taxonomy":
187
+ body["initialClassifications"]['Taxonomy']['organizingPrinciple'] = attributes.get('Organizing Principle', {}).get('value', None)
188
+ elif object_type == "CanonicalVocabulary":
189
+ body["initialClassifications"]['CanonicalVocabulary']['usage'] = attributes.get('Usage', {}).get('value', None)
190
+
191
+ body["properties"] = prop_body
192
+
193
+ guid = egeria_client.create_collection(body = body)
194
+ if guid:
195
+ update_element_dictionary(qualified_name, {
196
+ 'guid': guid, 'display_name': display_name
197
+ })
198
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
199
+ logger.success(msg)
200
+ return egeria_client.get_collection_by_guid(guid, obj, output_format='MD')
201
+ else:
202
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
203
+ logger.error(msg)
204
+ return None
205
+
206
+ except PyegeriaException as e:
207
+ logger.error(f"Pyegeria error performing {command}: {e}")
208
+ print_basic_exception(e)
209
+ return None
210
+ except Exception as e:
211
+ logger.error(f"Error performing {command}: {e}")
212
+ else:
213
+ return None
214
+
215
+
216
+ def process_category_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
217
+ pass
218
+ # """
219
+ # Processes a glossary category create or update object_action by extracting key attributes such as
220
+ # category name, qualified, description, and anchor glossary from the given txt..
221
+ #
222
+ # :param txt: A string representing the input cell to be processed for
223
+ # extracting category-related attributes.
224
+ # :param directive: an optional string indicating the directive to be used - display, validate or execute
225
+ # :return: A string summarizing the outcome of the processing.
226
+ # """
227
+ # valid = True
228
+ # set_debug_level(directive)
229
+ #
230
+ # command, object_type, object_action = extract_command_plus(txt)
231
+ # print(Markdown(f"# {command}\n"))
232
+ #
233
+ # category_name = process_simple_attribute(txt, ['Category Name', 'category_name', 'Cat'])
234
+ # print(Markdown(f"{pre_command} `{command}` for category: `\'{category_name}\'` with directive: `{directive}` "))
235
+ #
236
+ # owning_glossary_name = extract_attribute(txt, ['Owning Glossary', 'In Glossary'])
237
+ # description = process_simple_attribute(txt, ['Description'])
238
+ # q_name = process_simple_attribute(txt, ['Qualified Name'])
239
+ #
240
+ # parent_category_name = process_simple_attribute(txt, PARENT_CATEGORY_LABELS, "INFO")
241
+ #
242
+ # element_labels = CATEGORY_NAME_LABELS
243
+ # element_labels.append('Display Name')
244
+ # # Check if category exists (and get qname and guid)
245
+ # if category_name is None:
246
+ # valid = False
247
+ # known_q_name, known_guid, category_exists = None
248
+ # else:
249
+ # element_labels = CATEGORY_NAME_LABELS
250
+ # element_labels.append('Display Name')
251
+ # known_q_name, known_guid, valid, category_exists = process_element_identifiers(egeria_client, object_type,
252
+ # element_labels, txt,
253
+ # object_action, None)
254
+ #
255
+ # # Check if owning glossary exists (and get qname)
256
+ # if owning_glossary_name is None:
257
+ # valid = False
258
+ # known_glossary_q_name, known_glossary__guid, glossary_exists = None
259
+ #
260
+ # else:
261
+ # known_glossary_q_name, known_glossary_guid, valid, owning_glossary_exists = process_element_identifiers(
262
+ # egeria_client, "Glossary", GLOSSARY_NAME_LABELS, txt, EXISTS_REQUIRED, None)
263
+ #
264
+ # if parent_category_name:
265
+ # _, parent_guid, parent_valid, parent_exists = get_element_by_name(egeria_client, 'Glossary Categories',
266
+ # parent_category_name)
267
+ # else:
268
+ # parent_guid = None
269
+ # parent_exists = False
270
+ # parent_valid = False
271
+ #
272
+ # category_display = (
273
+ # f"\n* Command: {command}\n\t* Category: {category_name}\n\t* In Glossary: {owning_glossary_name}\n\t"
274
+ # f"* Description:\n{description}\n\t* Parent Category: {parent_category_name}\n\t"
275
+ # f"* Qualified Name: {q_name}\n\t")
276
+ #
277
+ # if object_action == 'Update':
278
+ # guid = process_simple_attribute(txt, ['GUID', 'guid', 'Guid'])
279
+ #
280
+ # category_display += (f"* GUID: {guid}\n\n")
281
+ # if not category_exists:
282
+ # msg = f"Category {category_name} can't be updated; {category_name} not found."
283
+ # print_msg(ERROR, msg, debug_level)
284
+ # valid = False
285
+ # else:
286
+ # msg = f"Glossary can be updated; {category_name} found"
287
+ # print_msg(ALWAYS, msg, debug_level)
288
+ #
289
+ # elif object_action == "Create":
290
+ # if category_exists:
291
+ # msg = f"Category {category_name} can't be created because it already exists.\n"
292
+ # print_msg("ERROR", msg, debug_level)
293
+ # valid = False
294
+ # elif valid:
295
+ # msg = f"It is valid to create Category `{category_name}` with:\n"
296
+ # print_msg("ALWAYS", msg, debug_level)
297
+ #
298
+ # if directive == "display":
299
+ # print(Markdown(category_display))
300
+ # return None
301
+ #
302
+ # elif directive == "validate":
303
+ # if valid:
304
+ # print(Markdown(category_display))
305
+ # else:
306
+ # msg = f"Validation failed for {object_type} `{category_name}`\n"
307
+ # print_msg(ERROR, msg, debug_level)
308
+ # print(Markdown(category_display))
309
+ # return valid
310
+ #
311
+ # elif directive == "process":
312
+ # if valid:
313
+ # print(Markdown(category_display))
314
+ # else:
315
+ # if category_exists and object_action == "Create":
316
+ # msg = (f"Create failed because category `{category_name}` exists - changing `Create` to `Update` in "
317
+ # f"processed output \n")
318
+ # print_msg(ERROR, msg, debug_level)
319
+ # print(Markdown(category_display))
320
+ # return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
321
+ # else:
322
+ # return None
323
+ #
324
+ # if object_action == "Update":
325
+ # if not category_exists:
326
+ # print(f"\n{ERROR}category `{category_name}` does not exist! Updating result document with Create "
327
+ # f"object_action\n")
328
+ # return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
329
+ #
330
+ # # Update the basic category properties
331
+ # egeria_client.update_category(known_guid, category_name, description, known_q_name, None)
332
+ # msg = f"->Updated category `{category_name}`with GUID {known_guid}"
333
+ # print_msg(ALWAYS, msg, debug_level)
334
+ #
335
+ # # Update parent-child relationships
336
+ #
337
+ # update_element_dictionary(known_q_name, {
338
+ # 'guid': known_guid, 'display_name': category_name
339
+ # })
340
+ #
341
+ # category_sync = update_category_parent(egeria_client, known_guid, parent_category_name)
342
+ # print_msg(ALWAYS, f"Updated Category hierarchy for `{category_name}` with outcome {category_sync}",
343
+ # debug_level)
344
+ # return egeria_client.get_category_by_guid(known_guid, output_format='FORM')
345
+ #
346
+ # elif object_action == "Create":
347
+ # is_root = True
348
+ #
349
+ # if category_exists:
350
+ # msg = (f"Cannot create`{category_name}` because it already exists; result document written for "
351
+ # f"category update\n")
352
+ # print_msg(WARNING, msg, debug_level)
353
+ # return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
354
+ # else:
355
+ # category_guid = egeria_client.create_category(known_glossary_guid, category_name, description, is_root)
356
+ # category_details = egeria_client.get_category_by_guid(category_guid)
357
+ #
358
+ # if category_details == NO_CATEGORIES_FOUND:
359
+ # msg = f"Just created category with GUID {category_guid} but category not found"
360
+ # print_msg(ERROR, msg, debug_level)
361
+ # return None
362
+ #
363
+ # qualified_name = category_details['glossaryCategoryProperties']["qualifiedName"]
364
+ # update_element_dictionary(qualified_name, {
365
+ # 'guid': category_guid, 'display_name': category_name
366
+ # })
367
+ # print_msg(ALWAYS, f"Created Category `{category_name}` with GUID {category_guid}", debug_level)
368
+ # if parent_valid and parent_guid:
369
+ # egeria_client.set_parent_category(parent_guid, category_guid)
370
+ # print_msg(ALWAYS, f"Set parent category for `{category_name}` to `{parent_category_name}`",
371
+ # debug_level)
372
+ # else:
373
+ # print_msg(ERROR,
374
+ # f"Parent category `{parent_category_name}` not found or invalid for `{category_name}`",
375
+ # debug_level)
376
+ # return egeria_client.get_category_by_guid(category_guid, output_format='FORM')
377
+ # return None
378
+ # return None
379
+ #
380
+ #
381
+ def update_category_parent(egeria_client, category_guid: str, parent_category_name: str = None) -> bool:
382
+ pass
383
+ # """
384
+ # Updates the parent relationship for a category.
385
+ #
386
+ # If a parent category is specified, it will check if a parent is currently set.
387
+ # If a parent category was set and is the same as the parent category specified, no change is needed.
388
+ # If a parent category was set and is different from the parent_category_name, the parent category is updated.
389
+ # If parent_category_name is None or empty and an existing parent category was set, the parent category is removed.
390
+ #
391
+ # Parameters
392
+ # ----------
393
+ # egeria_client: EgeriaTech
394
+ # The Egeria client to use for API calls
395
+ # category_guid: str
396
+ # The GUID of the category to update
397
+ # parent_category_name: str, optional
398
+ # The name of the parent category to set, or None to remove the parent
399
+ #
400
+ # Returns
401
+ # -------
402
+ #
403
+ # True if successful, False otherwise.
404
+ #
405
+ # """
406
+ # outcome = True
407
+ # # Handle parent category updates
408
+ # if parent_category_name:
409
+ # # Check if a parent is currently set
410
+ # current_parent = egeria_client.get_category_parent(category_guid)
411
+ #
412
+ # if isinstance(current_parent, str) and "No Parent Category found" in current_parent:
413
+ # # No parent currently set, need to set it
414
+ # _, parent_guid, _, parent_exists = get_element_by_name(egeria_client, 'Glossary Categories',
415
+ # parent_category_name)
416
+ #
417
+ # if parent_exists and parent_guid:
418
+ # egeria_client.set_parent_category(parent_guid, category_guid)
419
+ # print_msg(ALWAYS, f"Set parent category of category to `{parent_category_name}`", debug_level)
420
+ # else:
421
+ # print_msg(ERROR, f"Parent category `{parent_category_name}` not found", debug_level)
422
+ # outcome = False
423
+ # else:
424
+ # # Parent is set, check if it's the same
425
+ # current_parent_name = current_parent.get('glossaryCategoryProperties', {}).get('qualifiedName', '')
426
+ #
427
+ # if current_parent_name != parent_category_name:
428
+ # # Different parent, need to update
429
+ # # First remove the current parent
430
+ # current_parent_guid = current_parent.get('elementHeader', {}).get('guid', '')
431
+ # if current_parent_guid:
432
+ # egeria_client.remove_parent_category(current_parent_guid, category_guid)
433
+ #
434
+ # # Then set the new parent
435
+ # _, parent_guid, _, parent_exists = get_element_by_name(egeria_client, 'Glossary Categories',
436
+ # parent_category_name)
437
+ #
438
+ # if parent_exists and parent_guid:
439
+ # egeria_client.set_parent_category(parent_guid, category_guid)
440
+ # print_msg(ALWAYS,
441
+ # f"Updated parent category from `{current_parent_name}` to `{parent_category_name}`",
442
+ # debug_level)
443
+ # else:
444
+ # print_msg(ERROR, f"Parent category `{parent_category_name}` not found", debug_level)
445
+ # outcome = False
446
+ # elif parent_category_name is None or parent_category_name == '':
447
+ # # Check if a parent is currently set and remove it if needed
448
+ # current_parent = egeria_client.get_category_parent(category_guid)
449
+ #
450
+ # if not isinstance(current_parent, str) or "No Parent Category found" not in current_parent:
451
+ # # Parent is set, need to remove it
452
+ # current_parent_guid = current_parent.get('elementHeader', {}).get('guid', '')
453
+ # current_parent_name = current_parent.get('glossaryCategoryProperties', {}).get('qualifiedName', '')
454
+ #
455
+ # if current_parent_guid:
456
+ # egeria_client.remove_parent_category(current_parent_guid, category_guid)
457
+ # print_msg(ALWAYS, f"Removed parent category `{current_parent_name}`", debug_level)
458
+ #
459
+ # return outcome
460
+
461
+
462
+ def process_term_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
463
+ pass
464
+ """
465
+ Processes a term create or update object_action by extracting key attributes such as
466
+ term name, summary, description, abbreviation, examples, usage, version, and status from the given cell.
467
+
468
+ :param txt: A string representing the input cell to be processed for
469
+ extracting glossary-related attributes.
470
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
471
+ :return: A string summarizing the outcome of the processing.
472
+ """
473
+
474
+ command, object_type, object_action = extract_command_plus(txt)
475
+ print(Markdown(f"# {command}\n"))
476
+
477
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
478
+ if not parsed_output:
479
+ logger.error(f"No output for `{object_action}`")
480
+ return None
481
+
482
+ valid = parsed_output['valid']
483
+ exists = parsed_output['exists']
484
+
485
+ qualified_name = parsed_output.get('qualified_name', None)
486
+ guid = parsed_output.get('guid', None)
487
+
488
+ print(Markdown(parsed_output['display']))
489
+
490
+ logger.debug(json.dumps(parsed_output, indent=4))
491
+
492
+ attributes = parsed_output['attributes']
493
+
494
+ display_name = attributes['Display Name'].get('value', None)
495
+ status = attributes.get('Status', {}).get('value', None)
496
+ merge_update = attributes.get('Merge Update', {}).get('value', True)
497
+ #
498
+
499
+ if directive == "display":
500
+ return None
501
+ elif directive == "validate":
502
+ if valid:
503
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
504
+ else:
505
+ msg = f"Validation failed for object_action `{command}`\n"
506
+ return valid
507
+
508
+ elif directive == "process":
509
+ try:
510
+ obj = "GlossaryTerm"
511
+ # Set the property body for a glossary collection
512
+ #
513
+ prop_body = set_element_prop_body(obj, qualified_name, attributes)
514
+ prop_body["aliases"] = attributes.get('Aliases', {}).get('value', None)
515
+ prop_body["summary"] = attributes.get('Summary', {}).get('value', None)
516
+ prop_body["examples"] = attributes.get('Examples', {}).get('value', None)
517
+ prop_body["abbreviation"] = attributes.get('Abbreviation', {}).get('value', None)
518
+ prop_body["usage"] = attributes.get('Usage', {}).get('value', None)
519
+ prop_body["user_defined_status"] = attributes.get('UserDefinedStatus', {}).get('value', None)
520
+ to_be_collection_guids = [attributes.get("Glossary", {}).get("guid", {}),
521
+ attributes.get("Folder", {}).get("guid_list", {})]
522
+ glossary_guid = attributes.get("Glossary", {}).get('guid', None)
523
+ anchor_scope_guid = attributes.get("Anchor Scope", {}).get('guid', None)
524
+
525
+
526
+ get_method = egeria_client.get_term_by_guid
527
+ collection_types = ["Glossary", "Folder"]
528
+
529
+ output_set = make_format_set_name_from_type(object_type)
530
+
531
+ if object_action == "Update":
532
+ if not exists:
533
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
534
+ f"{object_action}\n")
535
+ logger.error(msg)
536
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
537
+ elif not valid:
538
+ return None
539
+ else:
540
+ print(Markdown(
541
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
542
+
543
+ body = set_update_body(obj, attributes)
544
+ body['properties'] = prop_body
545
+
546
+ egeria_client.update_glossary_term(guid, body)
547
+ if status:
548
+ egeria_client.update_term_status(guid, status)
549
+ get_method = egeria_client.get_term_by_guid
550
+ collection_types = ["Glossary", "Folder"]
551
+
552
+ sync_collection_memberships(egeria_client, guid, get_method, collection_types,
553
+ to_be_collection_guids, merge_update)
554
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
555
+ update_element_dictionary(qualified_name, {
556
+ 'guid': guid, 'display_name': display_name
557
+ })
558
+ return egeria_client.get_term_by_guid(guid, element_type='GlossaryTerm',
559
+ output_format='MD', report_spec=output_set)
560
+
561
+
562
+ elif object_action == "Create":
563
+ if valid is False and exists:
564
+ msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
565
+ f"`Create` to `Update` in processed output\n\n___")
566
+ logger.error(msg)
567
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
568
+
569
+ else:
570
+ body = set_create_body(obj,attributes)
571
+
572
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
573
+
574
+ body["properties"] = prop_body
575
+ # If the anchor scope is not already set and a glossary is specified
576
+ if anchor_scope_guid is None and glossary_guid:
577
+ body["anchorScopeGUID"] = glossary_guid
578
+
579
+ guid = egeria_client.create_glossary_term(body = body)
580
+ if guid:
581
+ sync_collection_memberships(egeria_client, guid, get_method,
582
+ collection_types, to_be_collection_guids, True)
583
+ update_element_dictionary(qualified_name, {
584
+ 'guid': guid, 'display_name': display_name
585
+ })
586
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
587
+ logger.success(msg)
588
+ return egeria_client.get_term_by_guid(guid, obj, output_format='MD', report_spec=output_set)
589
+ else:
590
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
591
+ logger.error(msg)
592
+ return None
593
+
594
+ except PyegeriaException as e:
595
+ logger.error(f"Pyegeria error performing {command}: {e}")
596
+ print_basic_exception(e)
597
+ return None
598
+ except Exception as e:
599
+ logger.error(f"Error performing {command}: {e}")
600
+ else:
601
+ return None
602
+
603
+ def process_link_term_term_relationship_command(egeria_client: EgeriaTech, txt: str,
604
+ directive: str = "display") -> Optional[str]:
605
+ """ Relate two terms through the specified relationship. ."""
606
+ command, object_type, object_action = extract_command_plus(txt)
607
+ print(Markdown(f"# {command}\n"))
608
+
609
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
610
+
611
+ print(Markdown(parsed_output['display']))
612
+
613
+ logger.debug(json.dumps(parsed_output, indent=4))
614
+
615
+ attributes = parsed_output['attributes']
616
+ term1_guid = attributes.get('Term 1', {}).get('guid', None)
617
+ term1_qname = attributes.get('Term 1', {}).get('qualified_name', None)
618
+ term2_guid = attributes.get('Term 2', {}).get('guid', None)
619
+ term2_qname = attributes.get('Term 2', {}).get('qualified_name', None)
620
+ relationship = attributes.get('Relationship', {}).get('value', None)
621
+ expression = attributes.get('Expression', {}).get('value', None)
622
+ confidence = attributes.get('Confidence', {}).get('value', None)
623
+ status = attributes.get('Status', {}).get('value', None)
624
+ steward = attributes.get('Steward', {}).get('value', None)
625
+ source = attributes.get('Source', {}).get('value', None)
626
+
627
+
628
+
629
+ valid = parsed_output['valid']
630
+ exists = term1_guid is not None and term2_guid is not None
631
+
632
+ if not (valid and exists):
633
+ valid = False
634
+
635
+ if directive == "display":
636
+ return None
637
+ elif directive == "validate":
638
+ if valid:
639
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
640
+ else:
641
+ msg = f"Validation failed for object_action `{command}`\n"
642
+ return valid
643
+
644
+ elif directive == "process":
645
+ prop_body = set_rel_prop_body("GlossaryTerm", attributes)
646
+ prop_body['expression'] = expression
647
+ prop_body['confidence'] = confidence
648
+ prop_body['status'] = status
649
+ prop_body['steward'] = steward
650
+ prop_body['source'] = source
651
+
652
+ try:
653
+
654
+ if not valid: # First validate the term before we process it
655
+ return None
656
+
657
+ if object_action == "Link":
658
+ if not exists:
659
+ msg = f" Term `{term1_guid}` or {term2_guid} does not exist! "
660
+ logger.error(msg)
661
+ return None
662
+ else:
663
+ print(Markdown(
664
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
665
+ body = set_rel_request_body(relationship, prop_body)
666
+ body['properties'] = prop_body
667
+ body = body_slimmer(body)
668
+ # todo removing body for now since don't know relationship properties class
669
+ egeria_client.add_relationship_between_terms(term1_guid, term2_guid, relationship)
670
+ logger.success(f"Created `{relationship}` relationship between `{term1_qname}` and `{term2_qname}`\n\n___")
671
+ update_md = (f"\n\n# Update Term-Term Relationship\n\n## Term 1 Name:\n\n{term1_qname}"
672
+ f"\n\n## Term 2 Name\n\n{term2_qname}\n\n## Term Relationship:\n\n{relationship}")
673
+ return update_md
674
+
675
+
676
+ except Exception as e:
677
+ print(f"Error performing {command}: {e}")
678
+ print_basic_exception(e)
679
+ return None
680
+ return None
681
+ else:
682
+ return None
683
+
684
+