pyegeria 5.4.0.23__py3-none-any.whl → 5.4.0.25__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 (54) hide show
  1. commands/cat/debug_log +7967 -465
  2. commands/cat/debug_log.2025-08-15_09-14-07_444802.zip +0 -0
  3. commands/cat/debug_log.2025-08-16_10-21-59_388912.zip +0 -0
  4. commands/cat/debug_log.2025-08-17_11-34-27_981852.zip +0 -0
  5. commands/cat/dr_egeria_md.py +36 -6
  6. commands/cat/logs/pyegeria.log +3 -135
  7. md_processing/.DS_Store +0 -0
  8. md_processing/__init__.py +12 -6
  9. md_processing/data/commands.json +8523 -2234
  10. md_processing/dr_egeria_inbox/gov_def.md +76 -18
  11. md_processing/dr_egeria_inbox/img.png +0 -0
  12. md_processing/dr_egeria_inbox/product.md +185 -24
  13. md_processing/dr_egeria_outbox/.obsidian/workspace.json +5 -5
  14. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +426 -0
  15. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +212 -0
  16. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +201 -0
  17. md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +209 -0
  18. md_processing/md_commands/governance_officer_commands.py +247 -178
  19. md_processing/md_commands/product_manager_commands.py +730 -580
  20. md_processing/md_processing_utils/common_md_proc_utils.py +170 -12
  21. md_processing/md_processing_utils/common_md_utils.py +126 -28
  22. md_processing/md_processing_utils/extraction_utils.py +2 -2
  23. md_processing/md_processing_utils/md_processing_constants.py +14 -10
  24. pyegeria/.DS_Store +0 -0
  25. pyegeria/__init__.py +1 -1
  26. pyegeria/_client_new.py +61 -12
  27. pyegeria/_exceptions_new.py +6 -0
  28. pyegeria/_output_formats.py +42 -2
  29. pyegeria/collection_manager.py +79 -14
  30. pyegeria/{data_designer_omvs.py → data_designer.py} +1171 -1675
  31. pyegeria/glossary_browser.py +1259 -0
  32. pyegeria/{glossary_manager_omvs.py → glossary_manager.py} +1181 -1099
  33. pyegeria/governance_officer.py +1 -3
  34. pyegeria/load_config.py +1 -1
  35. pyegeria/models.py +37 -4
  36. pyegeria/output_formatter.py +2 -1
  37. pyegeria/project_manager.py +1952 -0
  38. pyegeria/utils.py +5 -2
  39. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/METADATA +1 -1
  40. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/RECORD +43 -44
  41. md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:00-product.md +0 -62
  42. md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:13-product.md +0 -62
  43. md_processing/dr_egeria_outbox/friday/processed-2025-07-20 13:23-product.md +0 -47
  44. md_processing/dr_egeria_outbox/friday/processed-2025-08-01 11:55-data_test3.md +0 -503
  45. md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  46. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +0 -2744
  47. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +0 -62
  48. md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +0 -444
  49. md_processing/dr_egeria_outbox/processed-2025-08-03 16:05-glossary_list.md +0 -37
  50. pyegeria/glossary_browser_omvs.py +0 -3840
  51. pyegeria/governance_officer_omvs.py +0 -2367
  52. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/LICENSE +0 -0
  53. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/WHEEL +0 -0
  54. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/entry_points.txt +0 -0
@@ -3,24 +3,28 @@ This file contains term-related object_action functions for processing Egeria Ma
3
3
  """
4
4
  import json
5
5
  import os
6
- import sys
7
-
8
6
  from typing import Optional
9
7
 
8
+ from inflect import engine
9
+ from jsonschema import ValidationError
10
10
  from loguru import logger
11
+ from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command,
12
+ process_output_command)
13
+ from md_processing.md_processing_utils.common_md_utils import (set_gov_prop_body,
14
+ set_update_body, set_create_body,
15
+ set_peer_gov_def_request_body, setup_log,
16
+ ALL_GOVERNANCE_DEFINITIONS, GOVERNANCE_POLICIES,
17
+ GOVERNANCE_CONTROLS, GOVERNANCE_DRIVERS,
18
+ set_find_body,
19
+ set_delete_request_body)
20
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
21
+ from md_processing.md_processing_utils.md_processing_constants import (load_commands)
22
+ from pyegeria import DEBUG_LEVEL, body_slimmer, PyegeriaException, print_basic_exception, print_validation_error
23
+ from pyegeria.egeria_tech_client import EgeriaTech
11
24
  from rich import print
12
25
  from rich.console import Console
13
26
  from rich.markdown import Markdown
14
27
 
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
28
  GERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
25
29
  EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
26
30
  EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
@@ -49,141 +53,142 @@ GOVERNANCE_CONTROLS = ["Governance Rule", "Service Level Objective", "Governance
49
53
  load_commands('commands.json')
50
54
  debug_level = DEBUG_LEVEL
51
55
 
52
- console = Console(width=int(200))
56
+ console = Console(width=int(250))
53
57
  setup_log()
54
58
 
59
+
55
60
  #
56
61
  # Helper functions for the governance officer commands
57
62
  #
58
63
 
59
64
  @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
65
+ def sync_gov_rel_elements(egeria_client: EgeriaTech, object_action: str, object_type: str, guid: str,
66
+ qualified_name: str, attributes: dict):
67
+ # TODO: when the next release is available, I should be able to more easily get the asis elements - so will
68
+ # TODO: hold off on implementing replace all
63
69
  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)
70
+ merge_update = attributes.get("Merge Update", {}).get("value", True)
71
+ to_be_supports_policies = attributes.get("Supports Policies", {}).get("guid_list", None)
72
+ to_be_governance_drivers = attributes.get("Governance Drivers", {}).get("guid_list", None)
67
73
 
68
74
  if merge_update or object_action == "Create":
69
75
  if to_be_supports_policies:
70
76
  for policy in to_be_supports_policies:
71
- egeria_client.attach_supporting_definitions(policy, "GovernanceImplementation",guid)
77
+ egeria_client.attach_supporting_definitions(policy, "GovernanceImplementation", guid)
72
78
  print(f"Added `{policy}` to `{guid}`")
73
79
  elif to_be_governance_drivers:
74
80
  for policy in to_be_governance_drivers:
75
- egeria_client.attach_supporting_definitions(policy, "GovernanceResponse",guid)
81
+ egeria_client.attach_supporting_definitions(policy, "GovernanceResponse", guid)
76
82
  print(f"Added `{policy}` to `{guid}`")
77
83
  except Exception as ex:
78
84
  print(ex)
79
85
 
86
+
80
87
  @logger.catch
81
- def process_gov_definition_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
88
+ def process_gov_definition_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
89
+ str]:
82
90
  """
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, category
91
+ Processes a data specification create or update object_action by extracting key attributes.
85
92
 
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.
93
+ :param txt: Command details in text format.
94
+ :param directive: An optional string indicating the directive - display, validate, or process.
95
+ :return: A string summarizing the outcome, or None if no processing is needed.
90
96
  """
97
+ try:
98
+ # Extract basic command information
99
+ command, object_type, object_action = extract_command_plus(txt)
100
+ if not (command and object_type and object_action):
101
+ logger.error("Failed to parse `command`, `object_type`, or `object_action` from input text.")
102
+ return None
103
+ if object_type not in ALL_GOVERNANCE_DEFINITIONS:
104
+ logger.error(f"Invalid object type: {object_type}")
105
+ return None
106
+ # Log command details
107
+ print(Markdown(f"# {command}\n"))
91
108
 
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)
109
+ # Parse command attributes
110
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
111
+ if not parsed_output or 'valid' not in parsed_output:
112
+ logger.error(f"Unable to parse command properly: {txt}")
113
+ return None
112
114
 
115
+ valid = parsed_output['valid']
116
+ exists = parsed_output['exists']
117
+ qualified_name = parsed_output.get('qualified_name')
118
+ display_name = parsed_output.get('attributes', {}).get('Display Name', {}).get('value')
119
+ guid = parsed_output.get('guid')
113
120
 
114
- if directive == "display":
121
+ print(Markdown(parsed_output.get('display', '')))
122
+ logger.debug(json.dumps(parsed_output, indent=4))
115
123
 
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
124
+ if directive == "display":
125
+ logger.info("Directive set to display. No processing required.")
126
+ return None
123
127
 
124
- elif directive == "process":
128
+ elif directive == "validate":
129
+ if valid:
130
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
131
+ else:
132
+ logger.error(f"Validation failed for `{command}`.")
133
+ return valid
125
134
 
126
- try:
135
+ elif directive == "process":
127
136
  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")
137
+ if not guid:
138
+ msg = (f"The `{object_type}` '{display_name}' does not yet exist.\n The result document has been "
139
+ f"updated to change `Update` to `Create` in processed output\n{'-' * 80}\n ")
131
140
  logger.error(msg)
141
+ # print(msg)
132
142
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
133
- elif not valid:
143
+
144
+ if not valid:
145
+ logger.error("Invalid data for update action.")
134
146
  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
147
 
148
+ # Proceed with the update
149
+ update_body = set_update_body(object_type, parsed_output['attributes'])
150
+ update_body['properties'] = set_gov_prop_body(object_type, qualified_name, parsed_output['attributes'])
151
+ egeria_client.update_governance_definition(guid, body_slimmer(update_body))
152
+ if status := parsed_output['attributes'].get('Status', {}).get('value', None):
153
+ egeria_client.update_governance_definition_status(guid, status)
154
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}")
155
+ return egeria_client.get_governance_definition_by_guid(guid, output_format='MD')
149
156
 
150
157
  elif object_action == "Create":
151
158
  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___")
159
+ msg = (f"Failed to create `{object_type}` named `{display_name}` because it already exists.\n "
160
+ f"Result document has been updated to change `Create` to `Update` in processed o"
161
+ f"utput\n{'-' * 80}\n")
154
162
  logger.error(msg)
155
163
  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
164
+ elif valid is False:
165
+ msg = f" invalid data? - Correct and try again\n\n___"
166
+ logger.error(msg)
167
+ return None
161
168
  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)
169
+ create_body = set_create_body(object_type, parsed_output['attributes'])
170
+ create_body['properties'] = set_gov_prop_body(object_type, qualified_name,
171
+ parsed_output['attributes'])
172
+ guid = egeria_client.create_governance_definition(body_slimmer(create_body))
165
173
  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)
174
+ logger.success(f"Created {object_type} `{display_name}` with GUID {guid}")
175
175
  return egeria_client.get_governance_definition_by_guid(guid, output_format='MD')
176
176
  else:
177
- msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
178
- logger.error(msg)
177
+ logger.error(f"Failed to create {object_type} `{display_name}`.")
179
178
  return None
180
179
 
181
- except Exception as e:
182
- logger.error(f"Error performing {command}: {e}")
180
+ else:
181
+ logger.error(f"Unsupported directive: {directive}")
183
182
  return None
184
- else:
183
+
184
+ except PyegeriaException as e:
185
+ logger.error(f"PyegeriaException occurred: {e}")
186
+ print_basic_exception(e)
185
187
  return None
186
188
 
189
+ except Exception as e:
190
+ logger.exception(f"Unexpected error: {e}")
191
+ return None
187
192
 
188
193
 
189
194
  @logger.catch
@@ -214,8 +219,7 @@ def process_gov_def_link_detach_command(egeria_client: EgeriaTech, txt: str,
214
219
  description = attributes.get('Description', {}).get('value', None)
215
220
 
216
221
  valid = parsed_output['valid']
217
- exists = definition1 is not None and definition2 is not None
218
-
222
+ exists = definition1 is not None and definition2 is not None
219
223
 
220
224
  if directive == "display":
221
225
 
@@ -228,70 +232,92 @@ def process_gov_def_link_detach_command(egeria_client: EgeriaTech, txt: str,
228
232
  return valid
229
233
 
230
234
  elif directive == "process":
231
- gov_peer_relationship_type = object_type[:-1].replace(" ","") + "Link"
235
+ # Initialize the inflect engine
236
+ inflector = engine()
232
237
 
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)
238
+ # Split the object_type into words
239
+ object_type_parts = object_type.split()
247
240
 
248
- egeria_client._async_detach_peer_definitions(definition1, gov_peer_relationship_type,
249
- definition2,body)
241
+ # Determine which word to singularize (third word if present, otherwise fallback to last word)
242
+ if len(object_type_parts) >= 3:
243
+ word_to_singularize = object_type_parts[2]
244
+ else:
245
+ word_to_singularize = object_type_parts[-1] # Fallback to last word
250
246
 
251
- logger.success(f"===> Detached segment with {label} from `{definition1}`to {definition2}\n")
252
- out = parsed_output['display'].replace('Unlink', 'Link', 1)
247
+ # Singularize the selected word
248
+ singular_word = inflector.singular_noun(word_to_singularize) or word_to_singularize
253
249
 
254
- return (out)
250
+ # Construct gov_peer_relationship_type
251
+ gov_peer_relationship_type = f"Governance{singular_word}Link"
255
252
 
253
+ try:
254
+ if object_action == "Detach":
255
+ if not exists:
256
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
257
+ f"object_action\n")
258
+ logger.error(msg)
259
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
260
+ return out
261
+ elif not valid:
262
+ return None
263
+ else:
264
+ print(Markdown(
265
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
266
+ body = set_delete_request_body(object_type, attributes)
256
267
 
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)
268
+ egeria_client.detach_peer_definitions(definition1, gov_peer_relationship_type,
269
+ definition2, body)
262
270
 
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
271
+ logger.success(f"===> Detached segment with {label} from `{definition1}`to {definition2}\n")
272
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
267
273
 
268
- else:
269
- body = set_peer_gov_def_request_body(object_type, attributes)
274
+ return (out)
270
275
 
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
276
 
277
+ elif object_action == "Link":
278
+ if valid is False and exists:
279
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
280
+ f"`Link` to `Detach` in processed output\n")
281
+ logger.error(msg)
278
282
 
279
- except Exception as e:
280
- logger.error(f"Error performing {command}: {e}")
281
- return None
283
+ elif valid is False:
284
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
285
+ logger.error(msg)
286
+ return
287
+
288
+ else:
289
+ body = set_peer_gov_def_request_body(object_type, attributes)
290
+ egeria_client.link_peer_definitions(definition1, gov_peer_relationship_type,
291
+ definition2, body)
292
+ msg = f"==>Created {object_type} link named `{label}`\n"
293
+ logger.success(msg)
294
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
295
+ return out
296
+
297
+ except ValidationError as e:
298
+ print_validation_error(e)
299
+ logger.error(f"Validation Error performing {command}: {e}")
300
+ return None
301
+ except PyegeriaException as e:
302
+ print_basic_exception(e)
303
+ logger.error(f"PyegeriaException occurred: {e}")
304
+ return None
305
+
306
+ except Exception as e:
307
+ logger.error(f"Error performing {command}: {e}")
308
+ return None
282
309
  else:
283
310
  return None
284
311
 
285
312
 
286
313
  @logger.catch
287
- def process_gov_definition_list_command(egeria_client: EgeriaTech, txt: str,
288
- directive: str = "display") -> Optional[str]:
314
+ def process_supporting_gov_def_link_detach_command(egeria_client: EgeriaTech, txt: str,
315
+ directive: str = "display") -> Optional[str]:
289
316
  """
290
- Processes a Governance Definition list object_action by extracting key attributes such as
291
- search string from the given text.
317
+ Processes a link or unlink command to associate or break up peer governance definitions.
292
318
 
293
319
  :param txt: A string representing the input cell to be processed for
294
- extracting term-related attributes.
320
+ extracting blueprint-related attributes.
295
321
  :param directive: an optional string indicating the directive to be used - display, validate or execute
296
322
  :return: A string summarizing the outcome of the processing.
297
323
  """
@@ -300,60 +326,106 @@ def process_gov_definition_list_command(egeria_client: EgeriaTech, txt: str,
300
326
 
301
327
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
302
328
 
303
-
304
-
305
- valid = parsed_output['valid']
306
- print(Markdown(f"Performing {command}"))
307
329
  print(Markdown(parsed_output['display']))
308
330
 
309
- attr = parsed_output.get('attributes',{})
331
+ logger.debug(json.dumps(parsed_output, indent=4))
310
332
 
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)
333
+ attributes = parsed_output['attributes']
334
+
335
+ definition1 = attributes.get('Definition 1', {}).get('guid', None)
336
+ definition2 = attributes.get('Definition 2', {}).get('guid', None)
337
+ label = attributes.get('Link Label', {}).get('value', None)
338
+ description = attributes.get('Description', {}).get('value', None)
314
339
 
340
+ valid = parsed_output['valid']
341
+ exists = definition1 is not None and definition2 is not None
315
342
 
316
343
  if directive == "display":
344
+
317
345
  return None
318
346
  elif directive == "validate":
319
347
  if valid:
320
348
  print(Markdown(f"==> Validation of {command} completed successfully!\n"))
321
349
  else:
322
350
  msg = f"Validation failed for object_action `{command}`\n"
323
- logger.error(msg)
324
351
  return valid
325
352
 
326
353
  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"
354
+
355
+ # Construct gov_peer_relationship_type
356
+ relationship_type_name = object_type.replace(' ', '')
357
+ print(f"relationship_type_name: {relationship_type_name}")
358
+ try:
359
+ if object_action == "Detach":
360
+ if not exists:
361
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
362
+ f"object_action\n")
330
363
  logger.error(msg)
364
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
365
+ return out
366
+ elif not valid:
331
367
  return None
368
+ else:
369
+ print(Markdown(
370
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
371
+ body = set_delete_request_body(object_type, attributes)
332
372
 
333
- list_md = f"\n# `{object_type}` with filter: `{search_string}`\n\n"
334
- body = set_update_body(object_type, attr)
373
+ egeria_client.detach_supporting_definitions(definition1, relationship_type_name,
374
+ definition2, body)
335
375
 
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}`")
376
+ logger.success(f"===> Detached segment with {label} from `{definition1}`to {definition2}\n")
377
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
344
378
 
345
- return list_md
379
+ return (out)
346
380
 
347
- except Exception as e:
348
- logger.error(f"Error performing {command}: {e}")
349
- console.print_exception(show_locals=True)
350
- return None
381
+
382
+ elif object_action == "Link":
383
+ if valid is False and exists:
384
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
385
+ f"`Link` to `Detach` in processed output\n")
386
+ logger.error(msg)
387
+
388
+ elif valid is False:
389
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
390
+ logger.error(msg)
391
+ return
392
+
393
+ else:
394
+ body_prop = {
395
+ "class": "SupportingDefinitionProperties",
396
+ "rationale": attributes.get('Rationale', {}).get('value', None),
397
+ "effectiveFrom": attributes.get('Effective From', {}).get('value', None),
398
+ "effectiveTo": attributes.get('Effective To', {}).get('value', None),
399
+ }
400
+
401
+ body = set_peer_gov_def_request_body(object_type, attributes)
402
+ body['properties'] = body_prop
403
+ egeria_client.attach_supporting_definitions(definition1, relationship_type_name,
404
+ definition2, body)
405
+ msg = f"==>Created {object_type} link named `{label}`\n"
406
+ logger.success(msg)
407
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
408
+ return out
409
+
410
+ except ValidationError as e:
411
+ print_validation_error(e)
412
+ logger.error(f"Validation Error performing {command}: {e}")
413
+ return None
414
+ except PyegeriaException as e:
415
+ print_basic_exception(e)
416
+ logger.error(f"PyegeriaException occurred: {e}")
417
+ return None
418
+
419
+ except Exception as e:
420
+ logger.error(f"Error performing {command}: {e}")
421
+ return None
351
422
  else:
352
423
  return None
353
424
 
425
+
354
426
  @logger.catch
355
427
  def process_gov_def_context_command(egeria_client: EgeriaTech, txt: str,
356
- directive: str = "display") -> Optional[str]:
428
+ directive: str = "display") -> Optional[str]:
357
429
  """
358
430
  Retrieves the context graph for a governance definition.
359
431
 
@@ -375,12 +447,11 @@ def process_gov_def_context_command(egeria_client: EgeriaTech, txt: str,
375
447
 
376
448
  print(Markdown(parsed_output['display']))
377
449
 
378
- attr = parsed_output.get('attributes',{})
450
+ attr = parsed_output.get('attributes', {})
379
451
 
380
452
  output_format = attr.get('Output Format', {}).get('value', 'LIST')
381
453
  detailed = attr.get('Detailed', {}).get('value', False)
382
454
 
383
-
384
455
  if directive == "display":
385
456
  return None
386
457
  elif directive == "validate":
@@ -401,7 +472,7 @@ def process_gov_def_context_command(egeria_client: EgeriaTech, txt: str,
401
472
  list_md = f"\n# `{object_type}` with Qualified Name: `{qualified_name}`\n\n"
402
473
  body = set_update_body(object_type, attr)
403
474
 
404
- struct = egeria_client.get_gov_def_in_context(guid, body = body, output_format=output_format)
475
+ struct = egeria_client.get_gov_def_in_context(guid, body=body, output_format=output_format)
405
476
  if output_format.upper() == "DICT":
406
477
  list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
407
478
  else:
@@ -416,5 +487,3 @@ def process_gov_def_context_command(egeria_client: EgeriaTech, txt: str,
416
487
  return None
417
488
  else:
418
489
  return None
419
-
420
-