pyegeria 5.3.10__py3-none-any.whl → 5.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. commands/cat/debug_log +2806 -0
  2. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  3. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  4. commands/cat/dr_egeria_command_help.py +273 -0
  5. commands/cat/dr_egeria_md.py +90 -20
  6. commands/cat/glossary_actions.py +2 -2
  7. commands/cat/list_collections.py +24 -10
  8. commands/cat/list_data_designer.py +183 -0
  9. md_processing/__init__.py +28 -5
  10. md_processing/data/commands.json +31474 -1096
  11. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
  12. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
  13. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
  14. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
  15. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
  16. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  17. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  18. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  19. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  20. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
  21. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
  22. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
  23. md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
  24. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
  25. md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
  26. md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
  27. md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
  28. md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
  29. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
  30. md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
  31. md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
  32. md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
  33. md_processing/family_docs/Data Designer.md +842 -0
  34. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
  35. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
  36. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
  37. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
  38. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
  39. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
  40. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
  41. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
  42. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
  43. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
  44. md_processing/family_docs/Digital Product Manager.md +668 -0
  45. md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
  46. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
  47. md_processing/family_docs/Glossary/Create_Category.md +38 -0
  48. md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
  49. md_processing/family_docs/Glossary/Create_Term.md +70 -0
  50. md_processing/family_docs/Glossary.md +206 -0
  51. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
  52. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
  53. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
  54. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
  55. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
  56. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
  57. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
  58. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
  59. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
  60. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
  61. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
  62. md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
  63. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
  64. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
  65. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
  66. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
  67. md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
  68. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
  69. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
  70. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
  71. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
  72. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
  73. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
  74. md_processing/family_docs/Governance Officer.md +2412 -0
  75. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
  76. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
  77. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
  78. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
  79. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
  80. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
  81. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
  82. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
  83. md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
  84. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
  85. md_processing/family_docs/Solution Architect.md +490 -0
  86. md_processing/md_commands/data_designer_commands.py +1192 -710
  87. md_processing/md_commands/glossary_commands.py +19 -32
  88. md_processing/md_commands/governance_officer_commands.py +420 -0
  89. md_processing/md_commands/product_manager_commands.py +1180 -0
  90. md_processing/md_commands/project_commands.py +5 -2
  91. md_processing/md_commands/solution_architect_commands.py +1140 -0
  92. md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
  93. md_processing/md_processing_utils/common_md_utils.py +205 -6
  94. md_processing/md_processing_utils/debug_log +574 -0
  95. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
  96. md_processing/md_processing_utils/extraction_utils.py +1 -1
  97. md_processing/md_processing_utils/generate_dr_help.py +165 -0
  98. md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
  99. md_processing/md_processing_utils/generate_md_templates.py +92 -0
  100. md_processing/md_processing_utils/generated_help_terms.md +842 -0
  101. md_processing/md_processing_utils/md_processing_constants.py +94 -17
  102. pyegeria/__init__.py +1 -0
  103. pyegeria/_client.py +39 -1
  104. pyegeria/classification_manager_omvs.py +1 -1
  105. pyegeria/collection_manager_omvs.py +4667 -1178
  106. pyegeria/data_designer_omvs.py +348 -31
  107. pyegeria/egeria_tech_client.py +9 -25
  108. pyegeria/glossary_browser_omvs.py +5 -6
  109. pyegeria/glossary_manager_omvs.py +2 -2
  110. pyegeria/governance_officer_omvs.py +2367 -0
  111. pyegeria/output_formatter.py +157 -32
  112. pyegeria/solution_architect_omvs.py +5063 -1110
  113. pyegeria/utils.py +22 -2
  114. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
  115. pyegeria-5.4.0.dist-info/RECORD +243 -0
  116. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
  117. commands/cat/.DS_Store +0 -0
  118. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
  119. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
  120. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
  121. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
  122. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
  123. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
  124. md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
  125. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
  126. md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
  127. md_processing/dr_egeria_inbox/cat_test.md +0 -100
  128. md_processing/dr_egeria_inbox/data_field.md +0 -54
  129. md_processing/dr_egeria_inbox/data_spec.md +0 -77
  130. md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
  131. md_processing/dr_egeria_inbox/data_test.md +0 -86
  132. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
  133. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
  134. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
  135. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
  136. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
  137. md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
  138. md_processing/dr_egeria_inbox/rel.md +0 -8
  139. md_processing/dr_egeria_inbox/sb.md +0 -119
  140. md_processing/dr_egeria_inbox/search_test.md +0 -39
  141. md_processing/dr_egeria_inbox/solution-components.md +0 -154
  142. md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
  143. md_processing/dr_egeria_inbox/synonym_test.md +0 -42
  144. md_processing/dr_egeria_inbox/t1.md +0 -0
  145. md_processing/dr_egeria_inbox/t2.md +0 -268
  146. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
  147. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
  148. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
  149. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
  150. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
  151. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
  152. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
  153. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
  154. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
  155. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
  156. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
  157. md_processing/md_commands/blueprint_commands.py +0 -303
  158. pyegeria/.DS_Store +0 -0
  159. pyegeria/m_test.py +0 -118
  160. pyegeria-5.3.10.dist-info/RECORD +0 -196
  161. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  162. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
  163. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -12,7 +12,8 @@ from rich.console import Console
12
12
  from rich.markdown import Markdown
13
13
 
14
14
  from md_processing.md_processing_utils.common_md_utils import (debug_level, print_msg, set_debug_level,
15
- get_element_dictionary, update_element_dictionary)
15
+ get_element_dictionary, update_element_dictionary,
16
+ setup_log)
16
17
  from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, extract_command,
17
18
  process_simple_attribute, process_element_identifiers,
18
19
  update_a_command, extract_attribute,
@@ -29,7 +30,7 @@ from pyegeria.egeria_tech_client import EgeriaTech
29
30
 
30
31
  EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "170"))
31
32
  console = Console(width=EGERIA_WIDTH)
32
-
33
+ setup_log()
33
34
 
34
35
  def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories_exist: bool,
35
36
  categories_list: List[str]) -> None:
@@ -95,36 +96,6 @@ def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories
95
96
  print_msg("DEBUG-INFO", msg, debug_level)
96
97
 
97
98
 
98
- # def update_term_categories(egeria_client: EgeriaTech, term_guid: str, current_categories: List[str],
99
- # new_categories: List[str]) -> None:
100
- # """
101
- # Updates the categories of a term.
102
- #
103
- # Args:
104
- # egeria_client: The Egeria client to use for the update.
105
- # term_guid: The GUID of the term to update.
106
- # current_categories: The current categories of the term.
107
- # new_categories: The new categories of the term.
108
- # """
109
- # if new_categories: # If categories are specified, add them
110
- # for cat in new_categories:
111
- # if cat not in current_categories:
112
- # egeria_client.add_term_to_category(term_guid, cat)
113
- # msg = f"Added term {term_guid} to category {cat}"
114
- # print_msg("DEBUG-INFO", msg, debug_level)
115
- # # Remove any categories that are not in the new list
116
- # for cat in current_categories:
117
- # if cat not in new_categories:
118
- # egeria_client.remove_term_from_category(term_guid, cat)
119
- # msg = f"Removed term {term_guid} from category {cat}"
120
- # print_msg("DEBUG-INFO", msg, debug_level)
121
- # else: # No categories specified - so remove any categories a term is in
122
- # for cat in current_categories:
123
- # egeria_client.remove_term_from_category(term_guid, cat)
124
- # msg = f"Removed term {term_guid} from category {cat}"
125
- # print_msg("DEBUG-INFO", msg, debug_level)
126
-
127
-
128
99
  def process_glossary_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
129
100
  """
130
101
  Processes a glossary create or update object_action by extracting key attributes such as
@@ -137,6 +108,7 @@ def process_glossary_upsert_command(egeria_client: EgeriaTech, txt: str, directi
137
108
  """
138
109
 
139
110
  command, object_type, object_action = extract_command_plus(txt)
111
+ print(Markdown(f"# {command}\n"))
140
112
  set_debug_level(directive)
141
113
 
142
114
  glossary_name = process_simple_attribute(txt, GLOSSARY_NAME_LABELS, ERROR)
@@ -269,6 +241,7 @@ def process_category_upsert_command(egeria_client: EgeriaTech, txt: str, directi
269
241
  set_debug_level(directive)
270
242
 
271
243
  command, object_type, object_action = extract_command_plus(txt)
244
+ print(Markdown(f"# {command}\n"))
272
245
 
273
246
  category_name = process_simple_attribute(txt, ['Category Name', 'category_name', 'Cat'])
274
247
  print(Markdown(f"{pre_command} `{command}` for category: `\'{category_name}\'` with directive: `{directive}` "))
@@ -514,6 +487,8 @@ def process_term_upsert_command(egeria_client: EgeriaTech, txt: str, directive:
514
487
  set_debug_level(directive)
515
488
  known_q_name = None
516
489
  command = extract_command(txt)
490
+ print(Markdown(f"# {command}\n"))
491
+
517
492
  object_type = command.split(' ')[1].strip()
518
493
  object_action = command.split(' ')[0].strip()
519
494
 
@@ -557,6 +532,9 @@ def process_term_upsert_command(egeria_client: EgeriaTech, txt: str, directive:
557
532
  else:
558
533
  known_glossary_q_name, known_glossary_guid, glossary_valid, glossary_exists = process_element_identifiers(
559
534
  egeria_client, "Glossary", GLOSSARY_NAME_LABELS, txt, EXISTS_REQUIRED, None)
535
+ if not glossary_exists or known_glossary_guid is None:
536
+ glossary_valid = False
537
+ valid = False
560
538
 
561
539
  # process categories, if present
562
540
  categories = process_simple_attribute(txt, ['Glossary Categories', 'Glossary Category', 'Category', 'Categories'])
@@ -705,6 +683,8 @@ Optional[str]:
705
683
  set_debug_level(directive)
706
684
  valid = True
707
685
  command = extract_command(txt)
686
+ print(Markdown(f"# {command}\n"))
687
+
708
688
  object_type = command.split(' ')[1].strip()
709
689
  object_action = command.split(' ')[0].strip()
710
690
  term1_guid = None
@@ -762,6 +742,7 @@ def process_term_list_command(egeria_client: EgeriaTech, txt: str, directive: st
762
742
  set_debug_level(directive)
763
743
  valid = True
764
744
  command = extract_command(txt)
745
+ print(Markdown(f"# {command}\n"))
765
746
 
766
747
  search_string = process_simple_attribute(txt, SEARCH_LABELS)
767
748
  if search_string is None:
@@ -829,6 +810,7 @@ def process_category_list_command(egeria_client: EgeriaTech, txt: str, directive
829
810
  set_debug_level(directive)
830
811
  valid = True
831
812
  command = extract_command(txt)
813
+ print(Markdown(f"# {command}\n"))
832
814
 
833
815
  search_string = process_simple_attribute(txt, SEARCH_LABELS, "INFO")
834
816
  if search_string is None:
@@ -881,6 +863,7 @@ def process_glossary_structure_command(egeria_client: EgeriaTech, txt: str, dire
881
863
  set_debug_level(directive)
882
864
  valid = True
883
865
  command = extract_command(txt)
866
+ print(Markdown(f"# {command}\n"))
884
867
 
885
868
  known_glossary_guid = ""
886
869
 
@@ -936,6 +919,7 @@ def process_glossary_list_command(egeria_client: EgeriaTech, txt: str, directive
936
919
  set_debug_level(directive)
937
920
  valid = True
938
921
  command = extract_command(txt)
922
+ print(Markdown(f"# {command}\n"))
939
923
 
940
924
  search_string = process_simple_attribute(txt, SEARCH_LABELS, "INFO")
941
925
  if search_string is None:
@@ -988,6 +972,7 @@ def process_term_details_command(egeria_client: EgeriaTech, txt: str, directive:
988
972
  set_debug_level(directive)
989
973
  valid = True
990
974
  command = extract_command(txt)
975
+ print(Markdown(f"# {command}\n"))
991
976
  object_type = command.split(' ')[1].strip()
992
977
  object_action = command.split(' ')[0].strip()
993
978
 
@@ -1038,6 +1023,7 @@ def process_term_history_command(egeria_client: EgeriaTech, txt: str, directive:
1038
1023
  set_debug_level(directive)
1039
1024
  valid = True
1040
1025
  command = extract_command(txt)
1026
+ print(Markdown(f"# {command}\n"))
1041
1027
  object_type = command.split(' ')[1].strip()
1042
1028
  object_action = command.split(' ')[0].strip()
1043
1029
 
@@ -1095,6 +1081,7 @@ def process_term_revision_history_command(egeria_client: EgeriaTech, txt: str, d
1095
1081
  set_debug_level(directive)
1096
1082
  valid = True
1097
1083
  command = extract_command(txt)
1084
+ print(Markdown(f"# {command}\n"))
1098
1085
  object_type = command.split(' ')[1].strip()
1099
1086
  object_action = command.split(' ')[0].strip()
1100
1087
  known_q_name = None
@@ -0,0 +1,420 @@
1
+ """
2
+ This file contains term-related object_action functions for processing Egeria Markdown
3
+ """
4
+ import json
5
+ import os
6
+ import sys
7
+
8
+ from typing import Optional
9
+
10
+ from loguru import logger
11
+ from rich import print
12
+ from rich.console import Console
13
+ from rich.markdown import Markdown
14
+
15
+ from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
16
+ from md_processing.md_processing_utils.common_md_utils import (update_element_dictionary, set_gov_prop_body, \
17
+ set_update_body, set_create_body, set_peer_gov_def_request_body, set_rel_request_body,
18
+ set_metadata_source_request_body, set_filter_request_body, setup_log)
19
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
20
+ from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
21
+ from pyegeria import DEBUG_LEVEL, body_slimmer
22
+ from pyegeria.egeria_tech_client import EgeriaTech
23
+
24
+ GERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
25
+ EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
26
+ EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
27
+ EGERIA_VIEW_SERVER = os.environ.get("EGERIA_VIEW_SERVER", "view-server")
28
+ EGERIA_VIEW_SERVER_URL = os.environ.get("EGERIA_VIEW_SERVER_URL", "https://localhost:9443")
29
+ EGERIA_INTEGRATION_DAEMON = os.environ.get("EGERIA_INTEGRATION_DAEMON", "integration-daemon")
30
+ EGERIA_INTEGRATION_DAEMON_URL = os.environ.get("EGERIA_INTEGRATION_DAEMON_URL", "https://localhost:9443")
31
+ EGERIA_ADMIN_USER = os.environ.get("ADMIN_USER", "garygeeke")
32
+ EGERIA_ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "secret")
33
+ EGERIA_USER = os.environ.get("EGERIA_USER", "erinoverview")
34
+ EGERIA_USER_PASSWORD = os.environ.get("EGERIA_USER_PASSWORD", "secret")
35
+ EGERIA_WIDTH = os.environ.get("EGERIA_WIDTH", 220)
36
+ EGERIA_JUPYTER = os.environ.get("EGERIA_JUPYTER", False)
37
+ EGERIA_HOME_GLOSSARY_GUID = os.environ.get("EGERIA_HOME_GLOSSARY_GUID", None)
38
+ EGERIA_GLOSSARY_PATH = os.environ.get("EGERIA_GLOSSARY_PATH", None)
39
+ EGERIA_ROOT_PATH = os.environ.get("EGERIA_ROOT_PATH", "../../")
40
+ EGERIA_INBOX_PATH = os.environ.get("EGERIA_INBOX_PATH", "md_processing/dr_egeria_inbox")
41
+ EGERIA_OUTBOX_PATH = os.environ.get("EGERIA_OUTBOX_PATH", "md_processing/dr_egeria_outbox")
42
+
43
+ GENERAL_GOVERNANCE_DEFINITIONS = ["Business Imperative", "Regulation Article", "Threat", "Governance Principle",
44
+ "Governance Obligation", "Governance Approach", "Governance Processing Purpose"]
45
+
46
+ GOVERNANCE_CONTROLS = ["Governance Rule", "Service Level Objective", "Governance Process",
47
+ "Governance Responsibility", "Governance Procedure", "Security Access Control"]
48
+
49
+ load_commands('commands.json')
50
+ debug_level = DEBUG_LEVEL
51
+
52
+ console = Console(width=int(200))
53
+ setup_log()
54
+
55
+ #
56
+ # Helper functions for the governance officer commands
57
+ #
58
+
59
+ @logger.catch
60
+ def sync_gov_rel_elements(egeria_client: EgeriaTech, object_action:str, object_type:str, guid:str, qualified_name:str, attributes: dict):
61
+ # TODO: when the next release is available, I should be able to more easily get the asis elements - so will
62
+ # TODO: hold off on implementing replace all
63
+ try:
64
+ merge_update = attributes.get("Merge Update", {}).get("value",True)
65
+ to_be_supports_policies = attributes.get("Supports Policies", {}).get("guid_list",None)
66
+ to_be_governance_drivers = attributes.get("Governance Drivers", {}).get("guid_list",None)
67
+
68
+ if merge_update or object_action == "Create":
69
+ if to_be_supports_policies:
70
+ for policy in to_be_supports_policies:
71
+ egeria_client.attach_supporting_definitions(policy, "GovernanceImplementation",guid)
72
+ print(f"Added `{policy}` to `{guid}`")
73
+ elif to_be_governance_drivers:
74
+ for policy in to_be_governance_drivers:
75
+ egeria_client.attach_supporting_definitions(policy, "GovernanceResponse",guid)
76
+ print(f"Added `{policy}` to `{guid}`")
77
+ except Exception as ex:
78
+ print(ex)
79
+
80
+ @logger.catch
81
+ def process_gov_definition_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
82
+ """
83
+ Processes a data specification create or update object_action by extracting key attributes such as
84
+ spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
85
+
86
+ :param txt: A string representing the input cell to be processed for
87
+ extracting glossary-related attributes.
88
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
89
+ :return: A string summarizing the outcome of the processing.
90
+ """
91
+
92
+ command, object_type, object_action = extract_command_plus(txt)
93
+ print(Markdown(f"# {command}\n"))
94
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
95
+
96
+
97
+ valid = parsed_output['valid']
98
+ exists = parsed_output['exists']
99
+ qualified_name = parsed_output.get('qualified_name', None)
100
+ display_name = parsed_output.get('display_name', None)
101
+ guid = parsed_output.get('guid', None)
102
+
103
+ print(Markdown(parsed_output['display']))
104
+
105
+ logger.debug(json.dumps(parsed_output, indent=4))
106
+
107
+ attributes = parsed_output['attributes']
108
+
109
+ display_name = attributes['Display Name'].get('value', None)
110
+
111
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
112
+
113
+
114
+ if directive == "display":
115
+
116
+ return None
117
+ elif directive == "validate":
118
+ if valid:
119
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
120
+ else:
121
+ msg = f"Validation failed for object_action `{command}`\n"
122
+ return valid
123
+
124
+ elif directive == "process":
125
+
126
+ try:
127
+ if object_action == "Update":
128
+ if not exists:
129
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
130
+ f"object_action\n")
131
+ logger.error(msg)
132
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
133
+ elif not valid:
134
+ return None
135
+ else:
136
+ print(Markdown(
137
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
138
+ update_body = set_update_body(object_type, attributes)
139
+ update_body['properties'] = set_gov_prop_body(object_type, qualified_name, attributes)
140
+
141
+ egeria_client.update_governance_definition(guid, update_body, replace_all_props)
142
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
143
+ update_element_dictionary(qualified_name, {
144
+ 'guid': guid, 'display_name': display_name
145
+ })
146
+ sync_gov_rel_elements(egeria_client,object_type, object_type,guid, qualified_name, attributes)
147
+ return egeria_client.get_governance_definition_by_guid(guid, output_format='MD')
148
+
149
+
150
+ elif object_action == "Create":
151
+ if valid is False and exists:
152
+ msg = (f" Data Specification `{display_name}` already exists and result document updated changing "
153
+ f"`Create` to `Update` in processed output\n\n___")
154
+ logger.error(msg)
155
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
156
+ # elif valid is False and in_data_spec_valid is False:
157
+ # msg = (f" Invalid data specification(s) `{in_data_spec_list}` "
158
+ # f" invalid data? - Correct and try again\n\n___")
159
+ # logger.error(msg)
160
+ # return None
161
+ else:
162
+ create_body = set_create_body(object_type, attributes)
163
+ create_body['properties'] = set_gov_prop_body(object_type, qualified_name,attributes)
164
+ guid = egeria_client.create_governance_definition(create_body)
165
+ if guid:
166
+ update_element_dictionary(qualified_name, {
167
+ 'guid': guid, 'display_name': display_name
168
+ })
169
+ sync_gov_rel_elements(egeria_client, object_action,
170
+ object_type, guid, qualified_name,
171
+ attributes)
172
+
173
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
174
+ logger.success(msg)
175
+ return egeria_client.get_governance_definition_by_guid(guid, output_format='MD')
176
+ else:
177
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
178
+ logger.error(msg)
179
+ return None
180
+
181
+ except Exception as e:
182
+ logger.error(f"Error performing {command}: {e}")
183
+ return None
184
+ else:
185
+ return None
186
+
187
+
188
+
189
+ @logger.catch
190
+ def process_gov_def_link_detach_command(egeria_client: EgeriaTech, txt: str,
191
+ directive: str = "display") -> Optional[str]:
192
+ """
193
+ Processes a link or unlink command to associate or break up peer governance definitions.
194
+
195
+ :param txt: A string representing the input cell to be processed for
196
+ extracting blueprint-related attributes.
197
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
198
+ :return: A string summarizing the outcome of the processing.
199
+ """
200
+ command, object_type, object_action = extract_command_plus(txt)
201
+ print(Markdown(f"# {command}\n"))
202
+
203
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
204
+
205
+ print(Markdown(parsed_output['display']))
206
+
207
+ logger.debug(json.dumps(parsed_output, indent=4))
208
+
209
+ attributes = parsed_output['attributes']
210
+
211
+ definition1 = attributes.get('Definition 1', {}).get('guid', None)
212
+ definition2 = attributes.get('Definition 2', {}).get('guid', None)
213
+ label = attributes.get('Link Label', {}).get('value', None)
214
+ description = attributes.get('Description', {}).get('value', None)
215
+
216
+ valid = parsed_output['valid']
217
+ exists = definition1 is not None and definition2 is not None
218
+
219
+
220
+ if directive == "display":
221
+
222
+ return None
223
+ elif directive == "validate":
224
+ if valid:
225
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
226
+ else:
227
+ msg = f"Validation failed for object_action `{command}`\n"
228
+ return valid
229
+
230
+ elif directive == "process":
231
+ gov_peer_relationship_type = object_type[:-1].replace(" ","") + "Link"
232
+
233
+ try:
234
+ if object_action == "Detach":
235
+ if not exists:
236
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
237
+ f"object_action\n")
238
+ logger.error(msg)
239
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
240
+ return out
241
+ elif not valid:
242
+ return None
243
+ else:
244
+ print(Markdown(
245
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
246
+ body = set_metadata_source_request_body(object_type, attributes)
247
+
248
+ egeria_client._async_detach_peer_definitions(definition1, gov_peer_relationship_type,
249
+ definition2,body)
250
+
251
+ logger.success(f"===> Detached segment with {label} from `{definition1}`to {definition2}\n")
252
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
253
+
254
+ return (out)
255
+
256
+
257
+ elif object_action == "Link":
258
+ if valid is False and exists:
259
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
260
+ f"`Link` to `Detach` in processed output\n")
261
+ logger.error(msg)
262
+
263
+ elif valid is False:
264
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
265
+ logger.error(msg)
266
+ return
267
+
268
+ else:
269
+ body = set_peer_gov_def_request_body(object_type, attributes)
270
+
271
+ egeria_client.link_peer_definitions(definition1, gov_peer_relationship_type,
272
+ definition2, body)
273
+ msg = f"==>Created {object_type} link named `{label}`\n"
274
+ logger.success(msg)
275
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
276
+ return out
277
+
278
+
279
+ except Exception as e:
280
+ logger.error(f"Error performing {command}: {e}")
281
+ return None
282
+ else:
283
+ return None
284
+
285
+
286
+ @logger.catch
287
+ def process_gov_definition_list_command(egeria_client: EgeriaTech, txt: str,
288
+ directive: str = "display") -> Optional[str]:
289
+ """
290
+ Processes a Governance Definition list object_action by extracting key attributes such as
291
+ search string from the given text.
292
+
293
+ :param txt: A string representing the input cell to be processed for
294
+ extracting term-related attributes.
295
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
296
+ :return: A string summarizing the outcome of the processing.
297
+ """
298
+ command, object_type, object_action = extract_command_plus(txt)
299
+ print(Markdown(f"# {command}\n"))
300
+
301
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
302
+
303
+
304
+
305
+ valid = parsed_output['valid']
306
+ print(Markdown(f"Performing {command}"))
307
+ print(Markdown(parsed_output['display']))
308
+
309
+ attr = parsed_output.get('attributes',{})
310
+
311
+ search_string = attr.get('Search String', {}).get('value', '*')
312
+ output_format = attr.get('Output Format', {}).get('value', 'LIST')
313
+ detailed = attr.get('Detailed', {}).get('value', False)
314
+
315
+
316
+ if directive == "display":
317
+ return None
318
+ elif directive == "validate":
319
+ if valid:
320
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
321
+ else:
322
+ msg = f"Validation failed for object_action `{command}`\n"
323
+ logger.error(msg)
324
+ return valid
325
+
326
+ elif directive == "process":
327
+ try:
328
+ if not valid: # First validate the command before we process it
329
+ msg = f"Validation failed for {object_action} `{object_type}`\n"
330
+ logger.error(msg)
331
+ return None
332
+
333
+ list_md = f"\n# `{object_type}` with filter: `{search_string}`\n\n"
334
+ body = set_update_body(object_type, attr)
335
+
336
+ struct = egeria_client.find_governance_definitions(search_string,
337
+ body = body,
338
+ output_format=output_format)
339
+ if output_format.upper() == "DICT":
340
+ list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
341
+ else:
342
+ list_md += struct
343
+ logger.info(f"Wrote `{object_type}` for search string: `{search_string}`")
344
+
345
+ return list_md
346
+
347
+ except Exception as e:
348
+ logger.error(f"Error performing {command}: {e}")
349
+ console.print_exception(show_locals=True)
350
+ return None
351
+ else:
352
+ return None
353
+
354
+ @logger.catch
355
+ def process_gov_def_context_command(egeria_client: EgeriaTech, txt: str,
356
+ directive: str = "display") -> Optional[str]:
357
+ """
358
+ Retrieves the context graph for a governance definition.
359
+
360
+ :param txt: A string representing the input cell to be processed for
361
+ extracting term-related attributes.
362
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
363
+ :return: A string summarizing the outcome of the processing.
364
+ """
365
+ command, object_type, object_action = extract_command_plus(txt)
366
+ print(Markdown(f"# {command}\n"))
367
+
368
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
369
+
370
+ valid = parsed_output['valid']
371
+ exists = parsed_output['exists']
372
+ qualified_name = parsed_output.get('qualified_name', None)
373
+ display_name = parsed_output.get('display_name', None)
374
+ guid = parsed_output.get('guid', None)
375
+
376
+ print(Markdown(parsed_output['display']))
377
+
378
+ attr = parsed_output.get('attributes',{})
379
+
380
+ output_format = attr.get('Output Format', {}).get('value', 'LIST')
381
+ detailed = attr.get('Detailed', {}).get('value', False)
382
+
383
+
384
+ if directive == "display":
385
+ return None
386
+ elif directive == "validate":
387
+ if valid:
388
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
389
+ else:
390
+ msg = f"Validation failed for object_action `{command}`\n"
391
+ logger.error(msg)
392
+ return valid
393
+
394
+ elif directive == "process":
395
+ try:
396
+ if not valid: # First validate the command before we process it
397
+ msg = f"Validation failed for {object_action} `{object_type}`\n"
398
+ logger.error(msg)
399
+ return None
400
+
401
+ list_md = f"\n# `{object_type}` with Qualified Name: `{qualified_name}`\n\n"
402
+ body = set_update_body(object_type, attr)
403
+
404
+ struct = egeria_client.get_gov_def_in_context(guid, body = body, output_format=output_format)
405
+ if output_format.upper() == "DICT":
406
+ list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
407
+ else:
408
+ list_md += struct
409
+ logger.info(f"Wrote `{object_type}` graph for : `{qualified_name}`")
410
+
411
+ return list_md
412
+
413
+ except Exception as e:
414
+ logger.error(f"Error performing {command}: {e}")
415
+ console.print_exception(show_locals=True)
416
+ return None
417
+ else:
418
+ return None
419
+
420
+