pyegeria 5.3.9.9.7__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.9.9.7.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.9.9.7.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.9.9.7.dist-info/RECORD +0 -196
  161. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  162. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
  163. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -5,13 +5,12 @@ import os
5
5
  import sys
6
6
  from typing import List
7
7
 
8
- from rich.console import Console
8
+ from loguru import logger
9
9
  from rich import print
10
+ from rich.console import Console
10
11
 
11
-
12
-
13
- from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, print_msg,
14
- get_element_dictionary, update_element_dictionary,
12
+ from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, get_element_dictionary,
13
+ update_element_dictionary,
15
14
  split_tb_string, str_to_bool, )
16
15
  from md_processing.md_processing_utils.extraction_utils import (process_simple_attribute, extract_attribute,
17
16
  get_element_by_name)
@@ -20,6 +19,11 @@ from md_processing.md_processing_utils.message_constants import (ERROR, INFO, WA
20
19
  from pyegeria import EgeriaTech
21
20
  from pyegeria._globals import DEBUG_LEVEL
22
21
 
22
+ log_format = "P {time} | {level} | {function} | {line} | {message} | {extra}"
23
+ logger.remove()
24
+ logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
25
+ logger.add("debug_log.log", rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
26
+ colorize=True)
23
27
  # Constants
24
28
  EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "200"))
25
29
  EGERIA_USAGE_LEVEL = os.environ.get("EGERIA_USAGE_LEVEL", "Basic")
@@ -29,6 +33,7 @@ debug_level = DEBUG_LEVEL
29
33
  global COMMAND_DEFINITIONS
30
34
 
31
35
 
36
+ @logger.catch
32
37
  def process_provenance_command(file_path: str, txt: [str]) -> str:
33
38
  """
34
39
  Processes a provenance object_action by extracting the file path and current datetime.
@@ -46,7 +51,8 @@ def process_provenance_command(file_path: str, txt: [str]) -> str:
46
51
  return provenance
47
52
 
48
53
 
49
- def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
54
+ @logger.catch
55
+ def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
50
56
  directive: str = "display") -> dict:
51
57
  parsed_attributes, parsed_output = {}, {}
52
58
 
@@ -56,7 +62,7 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
56
62
  display_name = ""
57
63
  labels = {}
58
64
 
59
- command_spec = get_command_spec(object_type)
65
+ command_spec = get_command_spec(f"Create {object_type}")
60
66
  attributes = command_spec.get('Attributes', [])
61
67
  command_display_name = command_spec.get('display_name', None)
62
68
  command_qn_prefix = command_spec.get('qn_prefix', None)
@@ -69,7 +75,7 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
69
75
  parsed_output['reason'] = ""
70
76
 
71
77
  msg = f"\tProcessing {object_action} on a {object_type} \n"
72
- print_msg(ALWAYS, msg, debug_level)
78
+ logger.info(msg)
73
79
 
74
80
  # get the version early because we may need it to construct qualified names.
75
81
  version = process_simple_attribute(txt, {'Version', "Version Identifier", "Published Version"}, INFO)
@@ -81,29 +87,32 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
81
87
  for_update = attr[key].get('inUpdate', True)
82
88
  level = attr[key].get('level', 'Basic')
83
89
  msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
84
- f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` and attribute level `{level}` and for_update `{for_update}`\n")
85
- print_msg(INFO, msg, debug_level)
90
+ f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` and attribute level `{level}` and for_update `"
91
+ f"{for_update}`\n")
92
+ logger.trace(msg)
86
93
  if for_update is False and object_action == "Update":
87
- console.print(f"Attribute `{key}`is not allowed for `Update`", highlight=True)
94
+ logger.trace(f"Attribute `{key}`is not allowed for `Update`", highlight=True)
88
95
  continue
89
96
  if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
90
- console.print(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.", highlight=True)
97
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
98
+ highlight=True)
91
99
  continue
92
- if EGERIA_USAGE_LEVEL == "Advanced" and level in [ "Expert", "Invisible"]:
93
- console.print(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.", highlight=True)
100
+ if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
101
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
102
+ highlight=True)
94
103
  continue
95
104
  if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
96
- console.print(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.", highlight=True)
105
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
106
+ highlight=True)
97
107
  continue
98
108
 
99
-
100
109
  if attr[key].get('input_required', False) is True:
101
110
  if_missing = ERROR
102
111
  else:
103
112
  if_missing = INFO
104
113
 
105
114
  # lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
106
- lab =split_tb_string(attr[key]['attr_labels'] )
115
+ lab = split_tb_string(attr[key]['attr_labels'])
107
116
  labels: set = set()
108
117
  labels.add(key.strip())
109
118
  if key == 'Display Name':
@@ -111,7 +120,6 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
111
120
  if lab is not None and lab != [""]:
112
121
  labels.update(lab)
113
122
 
114
-
115
123
  default_value = attr[key].get('default_value', None)
116
124
 
117
125
  style = attr[key]['style']
@@ -124,7 +132,8 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
124
132
  elif style == 'QN':
125
133
  parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
126
134
  object_action, version, if_missing)
127
- if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key]['exists'] is False:
135
+ if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
136
+ 'exists'] is False:
128
137
  parsed_output['exists'] = False
129
138
  elif style == 'ID':
130
139
  parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
@@ -139,19 +148,22 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
139
148
 
140
149
  elif style == 'Reference Name':
141
150
  parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
142
- if ((if_missing==ERROR) and parsed_attributes[key].get("value", None) and
143
- parsed_attributes[key]['exists'] is False):
151
+ if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) and parsed_attributes[key][
152
+ 'exists'] is False):
144
153
  msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
145
- print_msg(ERROR, msg, debug_level)
154
+ logger.error(msg)
146
155
  parsed_output['valid'] = False
147
156
  parsed_output['reason'] += msg
157
+ elif parsed_attributes[key]['valid'] is False:
158
+ parsed_output['valid'] = False
159
+ parsed_output['reason'] += parsed_attributes[key]['reason']
148
160
 
149
161
  elif style == 'GUID':
150
162
  parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
151
163
  elif style == 'Ordered Int':
152
164
  parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
153
165
  elif style == 'Simple Int':
154
- parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
166
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
155
167
  elif style == 'Simple List':
156
168
  parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
157
169
  name_list = parsed_attributes[key]['value']
@@ -167,65 +179,239 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
167
179
 
168
180
  elif style == 'Reference Name List':
169
181
  parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
170
-
182
+ if (parsed_attributes[key].get("value", None) and (
183
+ parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
184
+ msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
185
+ f"does not exist")
186
+ logger.error(msg)
187
+ parsed_output['valid'] = False
188
+ parsed_output['reason'] += msg
171
189
  else:
172
- msg = f"Unknown attribute style: {style}"
173
- print_msg(ERROR, msg, debug_level)
190
+ msg = f"Unknown attribute style: {style} for key `{key}`"
191
+ logger.error(msg)
174
192
  sys.exit(1)
175
193
  parsed_attributes[key]['valid'] = False
176
194
  parsed_attributes[key]['value'] = None
177
195
  if key == "Display Name":
178
196
  display_name = parsed_attributes[key]['value']
179
197
 
180
-
181
-
182
- value = parsed_attributes[key].get('value',None)
198
+ value = parsed_attributes[key].get('value', None)
183
199
 
184
200
  if value is not None:
185
201
  # if the value is a dict, get the flattened name list
186
- value = parsed_attributes[key].get('name_list', None) if isinstance(value,(dict, list)) else value
187
-
202
+ value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
188
203
  parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
189
204
 
190
205
 
206
+ parsed_output['attributes'] = parsed_attributes
207
+
208
+ if display_name is None:
209
+ msg = f"No display name or name identifier found"
210
+ logger.error(msg)
211
+ parsed_output['valid'] = False
212
+ parsed_output['reason'] = msg
213
+ return parsed_output
214
+
215
+
191
216
  if parsed_attributes.get('Parent ID', {}).get('value', None) is not None:
192
217
  if (parsed_attributes['Parent Relationship Type Name']['value'] is None) or (
193
218
  parsed_attributes['Parent at End1']['value'] is None):
194
219
  msg = "Parent ID was found but either Parent `Relationship Type Name` or `Parent at End1` are missing"
195
- print_msg(ERROR, msg, debug_level)
220
+ logger.error(msg)
196
221
  parsed_output['valid'] = False
197
222
  parsed_output['reason'] = msg
198
223
  if parsed_attributes['Parent Relationship Type Name'].get('exists', False) is False:
199
224
  msg = "Parent ID was found but does not exist"
200
- print_msg(ERROR, msg, debug_level)
225
+ logger.error(msg)
201
226
  parsed_output['valid'] = False
202
227
  parsed_output['reason'] = msg
203
228
 
204
229
  if directive in ["validate", "process"] and object_action == "Update" and not parsed_output[
205
230
  'exists']: # check to see if provided information exists and is consistent with existing info
206
- msg = f"Update request invalid, Term {display_name} does not exist\n"
207
- print_msg(ERROR, msg, debug_level)
231
+ msg = f"Update request invalid, element `{display_name}` does not exist\n"
232
+ logger.error(msg)
208
233
  parsed_output['valid'] = False
209
234
  if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
210
235
  msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
211
- print_msg(ERROR, msg, debug_level)
236
+ logger.error(msg)
212
237
 
213
238
  elif directive in ["validate",
214
239
  "process"] and object_action == 'Create': # if the object_action is create, check that it
215
240
  # doesn't already exist
216
241
  if parsed_output['exists']:
217
242
  msg = f"Element `{display_name}` cannot be created since it already exists\n"
218
- print_msg(ERROR, msg, debug_level)
243
+ logger.error(msg)
219
244
  parsed_output['valid'] = False
220
245
  else:
221
- msg = f"It is valid to create Element `{display_name}`"
222
- print_msg(ALWAYS, msg, debug_level)
246
+ msg = f"Element `{display_name}` does not exist so it can be created\n"
247
+ logger.info(msg)
248
+
249
+
250
+ if parsed_output.get('qualified_name',None) and "* Qualified Name" not in parsed_output['display']:
251
+ parsed_output['display'] += f"\n\t* Qualified Name: `{parsed_output['qualified_name']}`\n\t"
252
+ if parsed_output.get('guid',None):
253
+ parsed_output['display'] += f"\n\t* GUID: `{parsed_output['guid']}`\n\t"
254
+
255
+ return parsed_output
256
+
257
+
258
+ @logger.catch
259
+ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
260
+ directive: str = "display") -> dict:
261
+ parsed_attributes, parsed_output = {}, {}
262
+
263
+ parsed_output['valid'] = True
264
+ parsed_output['exists'] = False
265
+
266
+ labels = {}
267
+ if object_action in ["Unlink","Detach"]:
268
+ command_spec = get_command_spec(f"Link {object_type}")
269
+ else:
270
+ command_spec = get_command_spec(f"{object_action} {object_type}")
271
+ attributes = command_spec.get('Attributes', [])
272
+ command_display_name = command_spec.get('display_name', None)
273
+
274
+ parsed_output['reason'] = ""
275
+ parsed_output['display'] = ""
276
+
277
+ msg = f"\tProcessing {object_action} on {object_type} \n"
278
+ logger.info(msg)
279
+
280
+ # get the version early because we may need it to construct qualified names.
281
+
282
+ for attr in attributes:
283
+ for key in attr:
284
+ # Run some checks to see if the attribute is appropriate to the operation and usage level
285
+
286
+ level = attr[key].get('level', 'Basic')
287
+ msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
288
+ f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` ")
289
+ logger.trace(msg)
290
+
291
+ if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
292
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
293
+ highlight=True)
294
+ continue
295
+ if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
296
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
297
+ highlight=True)
298
+ continue
299
+ if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
300
+ logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
301
+ highlight=True)
302
+ continue
303
+
304
+ if attr[key].get('input_required', False) is True:
305
+ if_missing = ERROR
306
+ else:
307
+ if_missing = INFO
308
+
309
+ # lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
310
+ lab = split_tb_string(attr[key]['attr_labels'])
311
+ labels: set = set()
312
+ labels.add(key.strip())
313
+
314
+ if lab is not None and lab != [""]:
315
+ labels.update(lab)
316
+
317
+ # set these to none since not needed for view commands
318
+ version = None
319
+ command_qn_prefix = None
320
+
321
+ default_value = attr[key].get('default_value', None)
322
+
323
+ style = attr[key]['style']
324
+ if style in ['Simple', 'Dictionary', 'Comment']:
325
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
326
+ elif style == 'Valid Value':
327
+ parsed_attributes[key] = proc_valid_value(txt, object_action, labels,
328
+ attr[key].get('valid_values', None), if_missing,
329
+ default_value)
330
+ elif style == 'QN':
331
+ parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
332
+ object_action, version, if_missing)
333
+ if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
334
+ 'exists'] is False:
335
+ parsed_output['exists'] = False
336
+ elif style == 'ID':
337
+ parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
338
+ object_action, version, if_missing)
339
+
340
+ parsed_output['guid'] = parsed_attributes[key].get('guid', None)
341
+ parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
342
+ parsed_output['exists'] = parsed_attributes[key]['exists']
343
+ if parsed_attributes[key]['valid'] is False:
344
+ parsed_output['valid'] = False
345
+ parsed_output['reason'] += parsed_attributes[key]['reason']
346
+
347
+ elif style == 'Reference Name':
348
+ parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
349
+ if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) is None):
350
+ msg = f"Required parameter `{parsed_attributes[key]['value']}` is missing"
351
+ logger.error(msg)
352
+ parsed_output['valid'] = False
353
+ parsed_output['reason'] += msg
354
+ elif parsed_attributes[key]['value'] and parsed_attributes[key]['exists'] is False:
355
+ msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
356
+ logger.error(msg)
357
+ parsed_output['valid'] = False
358
+ parsed_output['reason'] += msg
359
+
360
+ elif style == 'GUID':
361
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
362
+ elif style == 'Ordered Int':
363
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
364
+ elif style == 'Simple Int':
365
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
366
+ elif style == 'Simple List':
367
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
368
+ name_list = parsed_attributes[key]['value']
369
+ # attribute = re.split(r'[;,\n]+', name_list) if name_list is not None else None
370
+ attribute = split_tb_string(name_list)
371
+ parsed_attributes[key]['value'] = attribute
372
+ parsed_attributes[key]['name_list'] = name_list
373
+ elif style == 'Parent':
374
+ parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
375
+ elif style == 'Bool':
376
+ parsed_attributes[key] = proc_bool_attribute(txt, object_action, labels, if_missing, default_value)
377
+
378
+ elif style == 'Reference Name List':
379
+ parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
380
+ if (parsed_attributes[key].get("value", None) and (
381
+ parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
382
+ msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
383
+ f"does not exist")
384
+ logger.error(msg)
385
+ parsed_output['valid'] = False
386
+ parsed_output['reason'] += msg
387
+ else:
388
+ msg = f"Unknown attribute style: {style}"
389
+ logger.error(msg)
390
+ sys.exit(1)
391
+ parsed_attributes[key]['valid'] = False
392
+ parsed_attributes[key]['value'] = None
393
+
394
+ value = parsed_attributes[key].get('value', None)
395
+
396
+ if value is not None:
397
+ # if the value is a dict, get the flattened name list
398
+ value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
399
+ parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
223
400
 
224
401
  parsed_output['attributes'] = parsed_attributes
402
+
403
+
404
+ if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
405
+ msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
406
+ logger.error(msg)
407
+
408
+
225
409
  return parsed_output
226
410
 
227
411
 
228
- def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None) -> dict:
412
+ @logger.catch
413
+ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None,
414
+ simp_type: str = None) -> dict:
229
415
  """Process a simple attribute based on the provided labels and if_missing value.
230
416
  Extract the attribute value from the text and store it in a dictionary along with valid.
231
417
  If it doesn`t exist, mark the dictionary entry as invalid and print an error message with severity of if_missing.
@@ -245,27 +431,34 @@ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str =
245
431
 
246
432
  if if_missing not in ["WARNING", "ERROR", "INFO"]:
247
433
  msg = "Invalid severity for missing attribute"
248
- print_msg("ERROR", msg, debug_level)
434
+ logger.error(msg)
249
435
  return {"status": ERROR, "reason": msg, "value": None, "valid": False}
250
436
 
251
- attribute = extract_attribute(txt, labels)
252
437
  if default_value == "":
253
438
  default_value = None
254
- attribute = default_value if attribute is None else attribute
255
439
 
256
- if attribute is None:
440
+ attribute = extract_attribute(txt, labels)
441
+
442
+ attribute = default_value if attribute is None else attribute.replace('\n', '')
257
443
 
444
+ if attribute is None:
258
445
  if if_missing == INFO or if_missing == WARNING:
259
446
  msg = f"Optional attribute with labels: `{labels}` missing"
260
447
  valid = True
448
+ logger.info(msg)
261
449
  else:
262
450
  msg = f"Missing attribute with labels `{labels}` "
263
451
  valid = False
264
- print_msg(if_missing, msg, debug_level)
452
+ logger.error(msg)
265
453
  return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
454
+
455
+ if attribute and simp_type == "int" :
456
+ attribute = int(attribute)
457
+
266
458
  return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
267
459
 
268
460
 
461
+ @logger.catch
269
462
  def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_missing: str = INFO,
270
463
  default_value=None) -> dict:
271
464
  """Process a string attribute to check that it is a member of the associated value values list.
@@ -288,22 +481,22 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
288
481
 
289
482
  if if_missing not in ["WARNING", "ERROR", "INFO"]:
290
483
  msg = "Invalid severity for missing attribute"
291
- print_msg("ERROR", msg, debug_level)
484
+ logger.error(msg)
292
485
  return {"status": ERROR, "reason": msg, "value": None, "valid": False}
293
486
  if valid_values is None:
294
487
  msg = "Missing valid values list"
295
- print_msg("ERROR", msg, debug_level)
488
+ logger.error(msg)
296
489
  return {"status": WARNING, "reason": msg, "value": None, "valid": False}
297
490
  if isinstance(valid_values, str):
298
491
  # v_values = [item.strip() for item in re.split(r'[;,\n]+', valid_values)]
299
492
  v_values = split_tb_string(valid_values)
300
493
  if not isinstance(v_values, list):
301
494
  msg = "Valid values list is not a list"
302
- print_msg("ERROR", msg, debug_level)
495
+ logger.error(msg)
303
496
  return {"status": WARNING, "reason": msg, "value": None, "valid": False}
304
497
  if len(v_values) == 0:
305
498
  msg = "Valid values list is empty"
306
- print_msg("ERROR", msg, debug_level)
499
+ logger.error(msg)
307
500
  return {"status": WARNING, "reason": msg, "value": None, "valid": False}
308
501
 
309
502
  attribute = extract_attribute(txt, labels)
@@ -314,21 +507,23 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
314
507
  if attribute is None:
315
508
  if if_missing == INFO or if_missing == WARNING:
316
509
  msg = f"Optional attribute with labels: `{labels}` missing"
510
+ logger.info(msg)
317
511
  valid = True
318
512
  else:
319
513
  msg = f"Missing attribute with labels `{labels}` "
320
514
  valid = False
321
- print_msg(if_missing, msg, debug_level)
515
+ logger.error(msg)
322
516
  return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
323
517
  else:
324
518
  if attribute not in v_values:
325
519
  msg = f"Invalid value for attribute `{labels}`"
326
- print_msg(WARNING, msg, debug_level)
520
+ logger.warning(msg)
327
521
  return {"status": WARNING, "reason": msg, "value": attribute, "valid": False, "exists": True}
328
522
 
329
523
  return {"status": INFO, "OK": "OK", "value": attribute, "valid": valid, "exists": True}
330
524
 
331
525
 
526
+ @logger.catch
332
527
  def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None) -> dict:
333
528
  """Process a boolean attribute based on the provided labels and if_missing value.
334
529
  Extract the attribute value from the text and store it in a dictionary along with valid.
@@ -349,7 +544,7 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
349
544
 
350
545
  if if_missing not in ["WARNING", "ERROR", "INFO"]:
351
546
  msg = "Invalid severity for missing attribute"
352
- print_msg("ERROR", msg, debug_level)
547
+ logger.error(msg)
353
548
  return {"status": ERROR, "reason": msg, "value": None, "valid": False}
354
549
 
355
550
  attribute = extract_attribute(txt, labels)
@@ -362,11 +557,12 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
362
557
  if attribute is None:
363
558
  if if_missing == INFO or if_missing == WARNING:
364
559
  msg = f"Optional attribute with labels: `{labels}` missing"
560
+ logger.info(msg)
365
561
  valid = True
366
562
  else:
367
563
  msg = f"Missing attribute with labels `{labels}` "
368
564
  valid = False
369
- print_msg(if_missing, msg, debug_level)
565
+ logger.error(msg)
370
566
  return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
371
567
 
372
568
  if isinstance(attribute, str):
@@ -377,12 +573,13 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
377
573
  attribute = False
378
574
  else:
379
575
  msg = f"Invalid value for boolean attribute `{labels}`"
380
- print_msg("ERROR", msg, debug_level)
576
+ logger.error(msg)
381
577
  return {"status": ERROR, "reason": msg, "value": attribute, "valid": False, "exists": True}
382
578
 
383
579
  return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
384
580
 
385
581
 
582
+ @logger.catch
386
583
  def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, element_labels: list[str], txt: str,
387
584
  action: str, version: str = None, if_missing: str = INFO) -> dict:
388
585
  """
@@ -422,7 +619,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
422
619
 
423
620
  if element_name is None:
424
621
  msg = f"Optional attribute with label`{element_type}` missing"
425
- print_msg("INFO", msg, debug_level)
622
+ logger.info(msg)
426
623
  identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": False, "exists": False, }
427
624
  return identifier_output
428
625
 
@@ -436,18 +633,18 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
436
633
 
437
634
  if unique is False:
438
635
  msg = f"Multiple elements named {element_name} found"
439
- print_msg("DEBUG-ERROR", msg, debug_level)
636
+ logger.error(msg)
440
637
  identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
441
638
  valid = False
442
639
 
443
640
  if action == "Update" and not exists:
444
641
  msg = f"Element {element_name} does not exist"
445
- print_msg("DEBUG-ERROR", msg, debug_level)
642
+ logger.error(msg)
446
643
  identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
447
644
 
448
- elif action == "Update" and exists:
645
+ elif action in ["Update", "View"] and exists:
449
646
  msg = f"Element {element_name} exists"
450
- print_msg("DEBUG-INFO", msg, debug_level)
647
+ logger.info(msg)
451
648
  identifier_output = {
452
649
  "status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
453
650
  'qualified_name': q_name, 'guid': guid
@@ -455,7 +652,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
455
652
 
456
653
  elif action == "Create" and exists:
457
654
  msg = f"Element {element_name} already exists"
458
- print_msg("DEBUG-ERROR", msg, debug_level)
655
+ logger.error(msg)
459
656
  identifier_output = {
460
657
  "status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True,
461
658
  'qualified_name': qualified_name, 'guid': guid,
@@ -463,7 +660,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
463
660
 
464
661
  elif action == "Create" and not exists and valid:
465
662
  msg = f"{element_type} `{element_name}` does not exist"
466
- print_msg("DEBUG-INFO", msg, debug_level)
663
+ logger.info(msg)
467
664
 
468
665
  if q_name is None and qualified_name is None:
469
666
  q_name = egeria_client.__create_qualified_name__(qn_prefix, element_name, version_identifier=version)
@@ -481,11 +678,13 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
481
678
  return identifier_output
482
679
 
483
680
 
681
+ @logger.catch
484
682
  def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set, txt: str, action: str,
485
683
  if_missing: str = INFO, version: str = None) -> dict:
486
684
  """
487
685
  Processes element identifiers from the input text using the labels supplied,
488
686
  checking if the element exists in Egeria, and validating the information.
687
+ Only a single element is allowed.
489
688
 
490
689
  Parameters
491
690
  ----------
@@ -519,7 +718,12 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
519
718
  value = None
520
719
 
521
720
  element_name = extract_attribute(txt, element_labels)
721
+
522
722
  if element_name:
723
+ if '\n' in element_name or ',' in element_name:
724
+ msg = f"Element name `{element_name}` appears to be a list rather than a single element"
725
+ logger.error(msg)
726
+ return {"status": ERROR, "reason": msg, "value": None, "valid": False, "exists": False, }
523
727
  q_name, guid, unique, exists = get_element_by_name(egeria_client, element_type, element_name)
524
728
  value = element_name
525
729
  else:
@@ -530,30 +734,30 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
530
734
  if exists is True and unique is False:
531
735
  # Multiple elements found - so need to respecify with qualified name
532
736
  msg = f"Multiple elements named {element_name} found"
533
- print_msg("DEBUG-ERROR", msg, debug_level)
737
+ logger.error(msg)
534
738
  identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
535
739
 
536
740
 
537
741
  elif action == EXISTS_REQUIRED or if_missing == ERROR and not exists:
538
742
  # a required identifier doesn't exist
539
743
  msg = f"Required {element_type} `{element_name}` does not exist"
540
- print_msg("DEBUG-ERROR", msg, debug_level)
744
+ logger.error(msg)
541
745
  identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
542
- elif value is None and if_missing == INFO:
746
+ elif value is None and if_missing == INFO:
543
747
  # an optional identifier is empty
544
748
  msg = f"Optional attribute with label`{element_type}` missing"
545
- print_msg("INFO", msg, debug_level)
749
+ logger.info(msg)
546
750
  identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": True, "exists": False, }
547
751
  elif value and exists is False:
548
752
  # optional identifier specified but doesn't exist
549
753
  msg = f"Optional attribute with label`{element_type}` specified but doesn't exist"
550
- print_msg("ERROR", msg, debug_level)
754
+ logger.error(msg)
551
755
  identifier_output = {"status": ERROR, "reason": msg, "value": value, "valid": False, "exists": False, }
552
756
 
553
757
  else:
554
758
  # all good.
555
759
  msg = f"Element {element_type} `{element_name}` exists"
556
- print_msg("DEBUG-INFO", msg, debug_level)
760
+ logger.info(msg)
557
761
  identifier_output = {
558
762
  "status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
559
763
  "qualified_name": q_name, 'guid': guid
@@ -562,6 +766,7 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
562
766
  return identifier_output
563
767
 
564
768
 
769
+ @logger.catch
565
770
  def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, element_labels: set,
566
771
  if_missing: str = INFO) -> dict:
567
772
  """
@@ -595,12 +800,12 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
595
800
  id_list_output = {}
596
801
  elements = ""
597
802
  new_element_list = []
598
-
803
+ guid_list = []
599
804
  elements_txt = extract_attribute(txt, element_labels)
600
805
 
601
806
  if elements_txt is None:
602
807
  msg = f"Attribute with labels `{{element_type}}` missing"
603
- print_msg("DEBUG-INFO", msg, debug_level)
808
+ logger.debug(msg)
604
809
  return {"status": if_missing, "reason": msg, "value": None, "valid": False, "exists": False, }
605
810
  else:
606
811
  # element_list = re.split(r'[;,\n]+', elements_txt)
@@ -610,13 +815,14 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
610
815
  # Get the element using the generalized function
611
816
  known_q_name, known_guid, el_valid, el_exists = get_element_by_name(egeria_client, element_type, element)
612
817
  details = {"known_q_name": known_q_name, "known_guid": known_guid, "el_valid": el_valid}
613
- elements = f"{element} {elements}" # list of the input names
818
+ elements += element + ", " # list of the input names
614
819
 
615
820
  if el_exists and el_valid:
616
821
  new_element_list.append(known_q_name) # list of qualified names
822
+ guid_list.append(known_guid)
617
823
  elif not el_exists:
618
824
  msg = f"No {element_type} `{element}` found"
619
- print_msg("DEBUG-INFO", msg, debug_level)
825
+ logger.debug(msg)
620
826
  valid = False
621
827
  valid = valid if el_valid is None else (valid and el_valid)
622
828
  exists = exists and el_exists
@@ -624,19 +830,22 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
624
830
 
625
831
  if elements:
626
832
  msg = f"Found {element_type}: {elements}"
627
- print_msg("DEBUG-INFO", msg, debug_level)
833
+ logger.debug(msg)
628
834
  id_list_output = {
629
835
  "status": INFO, "reason": msg, "value": element_details, "valid": valid, "exists": exists,
630
- "name_list": new_element_list,
836
+ "name_list": new_element_list, "guid_list": guid_list,
631
837
  }
632
838
  else:
633
839
  msg = f" Name list contains one or more invalid qualified names."
634
- print_msg("DEBUG-INFO", msg, debug_level)
635
- id_list_output = {"status": if_missing, "reason": msg, "value": elements, "valid": valid,
636
- "exists": exists, "dict_list" : element_details}
840
+ logger.debug(msg)
841
+ id_list_output = {
842
+ "status": if_missing, "reason": msg, "value": elements, "valid": valid, "exists": exists,
843
+ "dict_list": element_details, "guid_list": guid_list
844
+ }
637
845
  return id_list_output
638
846
 
639
847
 
848
+ @logger.catch
640
849
  def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories_exist: bool,
641
850
  categories_list: List[str]) -> None:
642
851
  """
@@ -689,36 +898,19 @@ def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories
689
898
  egeria_client.add_term_to_category(term_guid, cat)
690
899
  current_categories.append(cat)
691
900
  msg = f"Added term {term_guid} to category {cat}"
692
- print_msg("DEBUG-INFO", msg, debug_level)
901
+ logger.info(msg)
693
902
 
694
903
  for cat in current_categories:
695
904
  if cat not in to_be_cat_guids:
696
905
  egeria_client.remove_term_from_category(term_guid, cat)
697
906
  msg = f"Removed term {term_guid} from category {cat}"
698
- print_msg("DEBUG-INFO", msg, debug_level)
907
+ logger.info(msg)
699
908
  else: # No categories specified - so remove any categories a term is in
700
909
  for cat in current_categories:
701
910
  egeria_client.remove_term_from_category(term_guid, cat)
702
911
  msg = f"Removed term {term_guid} from category {cat}"
703
- print_msg("DEBUG-INFO", msg, debug_level)
704
-
705
- def sync_data_dict_membership(egeria_client: EgeriaTech, in_data_dictionary_names: list , in_data_dictionary: dict,
706
- guid:str, object_type:str)->dict:
707
- pass
708
-
709
- def sync_data_structure_membership(egeria_client: EgeriaTech, in_data_structure_names: list , in_data_structure: dict,
710
- guid:str, object_type:str)->dict:
912
+ logger.info(msg)
711
913
 
712
- pass
713
914
 
714
- def sync_data_spec_membership(egeria_client: EgeriaTech, in_data_spec_names: list , in_data_spec: dict,
715
- guid:str, object_type:str)->dict:
716
- pass
717
915
 
718
- def sync_term_links(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
719
- links_list: List[str]) -> None:
720
- pass
721
916
 
722
- def sync_parent_data_field(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
723
- links_list: List[str]) -> None:
724
- pass