pyegeria 5.3.10__py3-none-any.whl → 5.4.0.dev3__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 (47) hide show
  1. commands/cat/debug_log.2025-06-05_20-24-18_123924.log.zip +0 -0
  2. commands/cat/debug_log.2025-06-10_08-45-03_929921.log.zip +0 -0
  3. commands/cat/debug_log.2025-06-11_09-57-21_247890.log.zip +0 -0
  4. commands/cat/debug_log.2025-06-12_16-14-31_212042.log.zip +0 -0
  5. commands/cat/debug_log.log +1267 -0
  6. commands/cat/dr_egeria_md.py +32 -5
  7. commands/cat/list_collections.py +10 -4
  8. commands/cat/list_data_designer.py +172 -0
  9. commands/cat/solution_architect_log.log +0 -0
  10. md_processing/__init__.py +7 -2
  11. md_processing/data/commands.json +4666 -848
  12. md_processing/dr_egeria_inbox/data_designer_search_test.md +11 -0
  13. md_processing/dr_egeria_inbox/data_test.md +106 -13
  14. md_processing/dr_egeria_inbox/data_test2.md +376 -0
  15. md_processing/dr_egeria_inbox/{search_test.md → glossary_search_test.md} +1 -0
  16. md_processing/dr_egeria_inbox/solution-components.md +66 -91
  17. md_processing/md_commands/data_designer_commands.py +840 -557
  18. md_processing/md_commands/solution_architect_commands.py +985 -0
  19. md_processing/md_processing_utils/common_md_proc_utils.py +262 -89
  20. md_processing/md_processing_utils/common_md_utils.py +11 -4
  21. md_processing/md_processing_utils/md_processing_constants.py +18 -16
  22. pyegeria/_client.py +39 -0
  23. pyegeria/classification_manager_omvs.py +1 -1
  24. pyegeria/collection_manager_omvs.py +248 -188
  25. pyegeria/data_designer_omvs.py +217 -9
  26. pyegeria/governance_officer_omvs.py +2349 -0
  27. pyegeria/output_formatter.py +24 -12
  28. pyegeria/solution_architect_omvs.py +4219 -1084
  29. pyegeria/utils.py +15 -2
  30. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dev3.dist-info}/METADATA +2 -1
  31. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dev3.dist-info}/RECORD +35 -36
  32. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dev3.dist-info}/entry_points.txt +4 -0
  33. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
  34. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
  35. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
  36. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
  37. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
  38. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
  39. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
  40. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
  41. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
  42. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
  43. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
  44. md_processing/md_commands/blueprint_commands.py +0 -303
  45. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  46. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dev3.dist-info}/LICENSE +0 -0
  47. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dev3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,985 @@
1
+ """
2
+ This file contains blueprint/solution-related object_action functions for processing Egeria Markdown
3
+ """
4
+ import json
5
+ import sys
6
+ from typing import Optional
7
+
8
+ from loguru import logger
9
+ from pygments.lexers import blueprint
10
+ from rich import print
11
+ from rich.console import Console
12
+ from rich.markdown import Markdown
13
+
14
+ from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
15
+ from md_processing.md_processing_utils.common_md_utils import update_element_dictionary
16
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
17
+ from md_processing.md_processing_utils.md_processing_constants import (load_commands)
18
+ from pyegeria import body_slimmer, EgeriaTech
19
+
20
+ load_commands('commands.json')
21
+
22
+ console = Console(width=int(200))
23
+
24
+ log_format = "D {time} | {level} | {function} | {line} | {message} | {extra}"
25
+ logger.remove()
26
+ logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
27
+ logger.add("solution_architect_log.log", rotation="1 day", retention="1 week", compression="zip", level="TRACE",
28
+ format=log_format, colorize=True)
29
+
30
+
31
+ @logger.catch
32
+ def sync_component_related_elements(egeria_client: EgeriaTech, object_type: str, sub_component_guids: list,
33
+ actor_guids: list, in_blueprint_guids: list, guid: str, qualified_name: str,
34
+ display_name: str, replace_all_props: bool = True) -> None:
35
+ """Sync a components related elements.
36
+
37
+ """
38
+ if replace_all_props:
39
+ rel_el_list = egeria_client.get_component_related_elements(guid)
40
+ # should I throw an exception if empty?
41
+ as_is_sub_components = set(rel_el_list.get("sub_component_guids", []))
42
+ as_is_actors = set(rel_el_list.get("actor_guids", []))
43
+ as_is_blueprints = set(rel_el_list.get("blueprint_guids", []))
44
+
45
+ to_be_sub_components = set(sub_component_guids) if sub_component_guids is not None else set()
46
+ to_be_actors = set(actor_guids) if actor_guids is not None else set()
47
+ to_be_blueprints = set(in_blueprint_guids) if in_blueprint_guids is not None else set()
48
+
49
+ logger.trace(
50
+ f"as_is_sub_components: {list(as_is_sub_components)} to_be_sub_components: {list(to_be_sub_components)}")
51
+ logger.trace(f"as_is_actors: {list(as_is_actors)} to_be_actors: {list(to_be_actors)}")
52
+ logger.trace(f"as_is_blueprints: {list(as_is_blueprints)} to_be_blueprints: {list(to_be_blueprints)}")
53
+
54
+ sub_components_to_remove = as_is_sub_components - to_be_sub_components
55
+ logger.trace(f"sub_components_to_remove: {list(sub_components_to_remove)}")
56
+ if len(sub_components_to_remove) > 0:
57
+ for ds in sub_components_to_remove:
58
+ egeria_client.detach_sub_component(guid, ds, None)
59
+ msg = f"Removed `{ds}` from component `{display_name}`"
60
+ logger.trace(msg)
61
+ sub_components_to_add = to_be_sub_components - as_is_sub_components
62
+ logger.trace(f"sub_components_to_add: {list(sub_components_to_add)}")
63
+ if len(sub_components_to_add) > 0:
64
+ for ds in sub_components_to_add:
65
+ egeria_client.link_subcomponent(guid, ds, None)
66
+ msg = f"Added `{ds}` to component `{display_name}`"
67
+ logger.trace(msg)
68
+
69
+ actors_to_remove = to_be_actors - as_is_actors
70
+ logger.trace(f"actors_to_remove: {list(actors_to_remove)}")
71
+ if len(actors_to_remove) > 0:
72
+ for actor in actors_to_remove:
73
+ egeria_client.detach_component_from_role(actor, guid, None)
74
+ msg = f"Removed actor `{actor}` from component `{display_name}`"
75
+ logger.trace(msg)
76
+ actors_to_add = to_be_actors - as_is_actors
77
+ logger.trace(f"actors_to_add: {list(actors_to_add)}")
78
+ if len(actors_to_add) > 0:
79
+ for actor in actors_to_add:
80
+ egeria_client.link_component_to_role(actor, guid, None)
81
+ msg = f"Added `{display_name}` to role `{actor}`"
82
+ logger.trace(msg)
83
+
84
+ blueprints_to_remove = as_is_blueprints - to_be_blueprints
85
+ logger.trace(f"blueprints_to_remove: {list(blueprints_to_remove)}")
86
+ if len(blueprints_to_remove) > 0:
87
+ for bp in blueprints_to_remove:
88
+ egeria_client.detach_solution_component_from_blueprint(bp, guid)
89
+ msg = f"Removed `{bp}` from `{display_name}`"
90
+ logger.trace(msg)
91
+ blueprints_to_add = to_be_blueprints - as_is_blueprints
92
+ logger.trace(f"blueprints_to_add: {list(blueprints_to_add)}")
93
+ if len(blueprints_to_add) > 0:
94
+ for bp in blueprints_to_add:
95
+ egeria_client.link_solution_component_to_blueprint(bp, guid)
96
+ msg = f"Added `{bp}` to`{display_name}`"
97
+ logger.trace(msg)
98
+ logger.info(f"Replaced the related elements in `{display_name}`")
99
+
100
+ else: # merge - add field to related elements
101
+ if sub_component_guids:
102
+ for comp in sub_component_guids:
103
+ egeria_client.link_subcomponent(guid, comp, None)
104
+ msg = f"Added `{sub_component_guids}` to `{display_name}`"
105
+ logger.trace(msg)
106
+
107
+ if actor_guids:
108
+ for actor in actor_guids:
109
+ egeria_client.link_component_to_role(actor, guid, None)
110
+ msg = f"Added `{actor_guids}` to `{display_name}`"
111
+ logger.trace(msg)
112
+
113
+ if in_blueprint_guids:
114
+ for bp in in_blueprint_guids:
115
+ egeria_client.link_solution_component_to_blueprint(bp, guid, None)
116
+ msg = f"Added `{in_blueprint_guids}` to `{display_name}`"
117
+ logger.trace(msg)
118
+ logger.info(f"Merged related elements in `{display_name}`")
119
+
120
+
121
+ def sync_blueprint_related_elements(egeria_client: EgeriaTech, object_type: str, component_guids: list, guid: str,
122
+ qualified_name: str, display_name: str, replace_all_props: bool = True) -> None:
123
+ """Sync a blueprints related elements.
124
+
125
+ """
126
+ if replace_all_props:
127
+ bp_element = egeria_client.get_solution_blueprint_by_guid(guid)
128
+ solution_components = bp_element['solutionComponents']
129
+ as_is_components = {}
130
+ if len(solution_components) > 0:
131
+ for component in solution_components:
132
+ as_is_components.append(component['elementHeader']['guid'])
133
+
134
+ # should I throw an exception if empty?
135
+
136
+ to_be_components = set(component_guids) if component_guids is not None else set()
137
+
138
+ logger.trace(f"as_is_components: {list(as_is_components)} to_be_sub_components: {list(to_be_components)}")
139
+
140
+ components_to_remove = as_is_components - to_be_components
141
+ logger.trace(f"components_to_remove: {list(components_to_remove)}")
142
+ if len(components_to_remove) > 0:
143
+ for ds in components_to_remove:
144
+ egeria_client.detach_solution_component_from_blueprint(guid, ds, None)
145
+ msg = f"Removed `{ds}` from component `{display_name}`"
146
+ logger.trace(msg)
147
+ components_to_add = to_be_components - as_is_components
148
+ logger.trace(f"sub_components_to_add: {list(components_to_add)}")
149
+ if len(components_to_add) > 0:
150
+ for ds in components_to_add:
151
+ egeria_client.link_solution_component_to_blueprint(guid, ds, None)
152
+ msg = f"Added `{ds}` to component `{display_name}`"
153
+ logger.trace(msg)
154
+
155
+ logger.info(f"Replaced the related elements in `{display_name}`")
156
+
157
+ else: # merge - add field to related elements
158
+ if component_guids:
159
+ for comp in component_guids:
160
+ egeria_client.link_solution_component_to_blueprint(guid, comp, None)
161
+ msg = f"Added `{component_guids}` to `{display_name}`"
162
+ logger.trace(msg)
163
+
164
+ logger.info(f"Merged related elements in `{display_name}`")
165
+
166
+
167
+ @logger.catch
168
+ def process_blueprint_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
169
+ """
170
+ Processes a solution blueprint create or update object_action by extracting key attributes such as
171
+ blueprint name, description, and usage from the given text.
172
+
173
+ :param txt: A string representing the input cell to be processed for
174
+ extracting blueprint-related attributes.
175
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
176
+ :return: A string summarizing the outcome of the processing.
177
+ """
178
+ command, object_type, object_action = extract_command_plus(txt)
179
+
180
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
181
+
182
+ valid = parsed_output['valid']
183
+ exists = parsed_output['exists']
184
+
185
+ qualified_name = parsed_output.get('qualified_name', None)
186
+ guid = parsed_output.get('guid', None)
187
+
188
+ print(Markdown(parsed_output['display']))
189
+
190
+ logger.debug(json.dumps(parsed_output, indent=4))
191
+
192
+ attributes = parsed_output['attributes']
193
+ description = attributes.get('Description', {}).get('value', None)
194
+ display_name = attributes['Display Name'].get('value', None)
195
+ version_identifier = attributes.get('Version Identifier', {}).get('value', None)
196
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
197
+ effective_from = attributes.get('Effective From', {}).get('value', None)
198
+ effective_to = attributes.get('Effective To', {}).get('value', None)
199
+ external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
200
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
201
+
202
+ anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
203
+ parent_guid = attributes.get('Parent ID', {}).get('guid', None)
204
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
205
+ parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
206
+
207
+ anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
208
+ is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
209
+ if parent_guid is None:
210
+ is_own_anchor = True
211
+
212
+ additional_prop = attributes.get('Additional Properties', {}).get('value', None)
213
+ additional_properties = json.loads(additional_prop) if additional_prop is not None else None
214
+ extended_prop = attributes.get('Extended Properties', {}).get('value', None)
215
+ extended_properties = json.loads(extended_prop) if extended_prop is not None else None
216
+ component_guids = attributes.get('Solution Components', {}).get('guid_list', None)
217
+
218
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
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
+ try:
232
+ if object_action == "Update":
233
+ if not exists:
234
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
235
+ f"object_action\n")
236
+ logger.error(msg)
237
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
238
+ elif not valid:
239
+ return None
240
+ else:
241
+ print(Markdown(
242
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
243
+
244
+ body = body_slimmer({
245
+ "class": "UpdateSolutionBlueprintRequestBody", "externalSourceGUID": external_source_guid,
246
+ "externalSourceName": external_source_name, "effectiveTime": effective_time,
247
+ "forLineage": False, "forDuplicateProcessing": False, "properties": {
248
+ "class": "SolutionBlueprintProperties", "qualifiedName": qualified_name,
249
+ "displayName": display_name, "description": description, "version": version_identifier,
250
+ "additionalProperties": additional_properties, "extendedProperties": extended_properties,
251
+ "effectiveFrom": effective_from, "effectiveTo": effective_to
252
+ }
253
+ })
254
+
255
+ egeria_client.update_solution_blueprint(guid, body, replace_all_props)
256
+ logger.success(f"==> Updated {object_type} `{display_name}` with GUID {guid}\n\n")
257
+ update_element_dictionary(qualified_name, {
258
+ 'guid': guid, 'display_name': display_name
259
+ })
260
+ sync_blueprint_related_elements(egeria_client, object_type, component_guids, guid, qualified_name,
261
+ display_name, replace_all_props)
262
+ logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
263
+ return egeria_client.find_solution_blueprints(qualified_name, output_format='MD')
264
+
265
+
266
+ elif object_action == "Create":
267
+ if valid is False and exists:
268
+ msg = (f" Data Specification `{display_name}` already exists and result document updated changing "
269
+ f"`Create` to `Update` in processed output\n\n___")
270
+ logger.error(msg)
271
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
272
+
273
+ elif not valid:
274
+ msg = (f"==>{object_type} `{display_name}` is not valid and can't be created")
275
+ logger.error(msg)
276
+ return
277
+ else:
278
+ body = {
279
+ "class": "NewSolutionBlueprintRequestBody", "externalSourceGUID": external_source_guid,
280
+ "externalSourceName": external_source_name, "forLineage": False, "forDuplicateProcessing": False,
281
+ "effectiveTime": effective_time, "anchorGUID": anchor_guid, "isOwnAnchor": is_own_anchor,
282
+ "anchorScopeGUID": anchor_scope_guid, "parentGUID": parent_guid,
283
+ "parentRelationshipTypeName": parent_relationship_type_name, "parentAtEnd1": parent_at_end1,
284
+ "properties": {
285
+ "class": "SolutionBlueprintProperties", "effectiveFrom": effective_from,
286
+ "effectiveTo": effective_to, # "typeName": type_name,
287
+ "extendedProperties": extended_properties, "qualifiedName": qualified_name,
288
+ "additionalProperties": additional_properties, "displayName": display_name,
289
+ "description": description, "version": version_identifier
290
+ }
291
+ }
292
+
293
+ guid = egeria_client.create_solution_blueprint(body)
294
+ if guid:
295
+ update_element_dictionary(qualified_name, {
296
+ 'guid': guid, 'display_name': display_name
297
+ })
298
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
299
+ logger.success(msg)
300
+ return egeria_client.find_solution_blueprints(qualified_name, output_format='MD')
301
+ else:
302
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
303
+ logger.error(msg)
304
+ return None
305
+
306
+ except Exception as e:
307
+ logger.error(f"Error performing {command}: {e}")
308
+ return None
309
+ else:
310
+ return None
311
+
312
+
313
+ @logger.catch
314
+ def process_solution_component_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> \
315
+ Optional[str]:
316
+ """
317
+ Processes a solution component create or update object_action by extracting key attributes such as
318
+ component name, description, and parent components from the given text.
319
+
320
+ :param txt: A string representing the input cell to be processed for
321
+ extracting component-related attributes.
322
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
323
+ :return: A string summarizing the outcome of the processing.
324
+ """
325
+ command, object_type, object_action = extract_command_plus(txt)
326
+
327
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
328
+
329
+ valid = parsed_output['valid']
330
+ exists = parsed_output['exists']
331
+
332
+ qualified_name = parsed_output.get('qualified_name', None)
333
+ guid = parsed_output.get('guid', None)
334
+
335
+ print(Markdown(parsed_output['display']))
336
+
337
+ logger.debug(json.dumps(parsed_output, indent=4))
338
+
339
+ attributes = parsed_output['attributes']
340
+ description = attributes.get('Description', {}).get('value', None)
341
+ display_name = attributes['Display Name'].get('value', None)
342
+ version_identifier = attributes.get('Version Identifier', {}).get('value', None)
343
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
344
+ effective_from = attributes.get('Effective From', {}).get('value', None)
345
+ effective_to = attributes.get('Effective To', {}).get('value', None)
346
+ external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
347
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
348
+
349
+ anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
350
+ parent_guid = attributes.get('Parent ID', {}).get('guid', None)
351
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
352
+ parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
353
+
354
+ anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
355
+ is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
356
+ if parent_guid is None:
357
+ is_own_anchor = True
358
+
359
+ additional_prop = attributes.get('Additional Properties', {}).get('value', None)
360
+ additional_properties = json.loads(additional_prop) if additional_prop is not None else None
361
+ extended_prop = attributes.get('Extended Properties', {}).get('value', None)
362
+ extended_properties = json.loads(extended_prop) if extended_prop is not None else None
363
+
364
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
365
+
366
+ solution_component_type = attributes.get('Solution Component Type', {}).get('value', None)
367
+ planned_deployed_impl_type = attributes.get('Planned Deployed Implementation Type', {}).get('value', None)
368
+ sub_component_names = attributes.get('Solution SubComponents', {}).get('name_list', None)
369
+ sub_component_guids = attributes.get('Solution SubComponents', {}).get('guid_list', None)
370
+ actor_names = attributes.get('Actors', {}).get('name_list', None)
371
+ actor_guids = attributes.get('Actors', {}).get('guid_list', None)
372
+ in_blueprint_names = attributes.get('Solution Blueprints', {}).get('name_list', None)
373
+ in_blueprint_guids = attributes.get('Solution Blueprints', {}).get('guid_list', None)
374
+
375
+ if directive == "display":
376
+
377
+ return None
378
+ elif directive == "validate":
379
+ if valid:
380
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
381
+ else:
382
+ msg = f"Validation failed for object_action `{command}`\n"
383
+ return valid
384
+
385
+ elif directive == "process":
386
+ try:
387
+ if object_action == "Update":
388
+ if not exists:
389
+ msg = (f"==> Element `{display_name}` does not exist! Updating result document with Create."
390
+ f"object_action\n")
391
+ logger.error(msg)
392
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
393
+ elif not valid:
394
+ logger.error(f"==> Element `{display_name}` entry is not valid. Please refer to the errors above.")
395
+ return None
396
+ else:
397
+ print(Markdown(
398
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
399
+
400
+ body = body_slimmer({
401
+ "class": "UpdateSolutionComponentRequestBody", "externalSourceGUID": external_source_guid,
402
+ "externalSourceName": external_source_name, "effectiveTime": effective_time, "forLineage": False,
403
+ "forDuplicateProcessing": False, "parentAtEnd1": parent_at_end1, "properties": {
404
+ "class": "SolutionComponentProperties", "qualifiedName": qualified_name,
405
+ "displayName": display_name, "description": description,
406
+ "solutionComponentType": solution_component_type,
407
+ "plannedDeployedImplementationType": planned_deployed_impl_type,
408
+ "additionalProperties": additional_properties, "extendedProperties": extended_properties,
409
+ "effectiveFrom": effective_from, "effectiveTo": effective_to
410
+ }
411
+ })
412
+
413
+ egeria_client.update_solution_component(guid, body, replace_all_props)
414
+ logger.success(f"==>Updated {object_type} `{display_name}` with GUID {guid}\n")
415
+ update_element_dictionary(qualified_name, {
416
+ 'guid': guid, 'display_name': display_name
417
+ })
418
+ # Sync Parent Components and Blueprints
419
+ sync_component_related_elements(egeria_client, object_type, sub_component_guids, actor_guids,
420
+ in_blueprint_guids, guid, qualified_name, display_name,
421
+ replace_all_props)
422
+ logger.success(f"==>Updated {object_type} `{display_name}` with related elements")
423
+ return egeria_client.get_solution_component_by_guid(guid, output_format='MD')
424
+
425
+
426
+ elif object_action == "Create":
427
+ if valid is False and exists:
428
+ msg = (f" {object_type} `{display_name}` already exists and result document updated changing "
429
+ f"`Create` to `Update` in processed output\n\n___")
430
+ logger.error(msg)
431
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
432
+
433
+ elif not valid:
434
+ msg = (f"==>{object_type} `{display_name}` is not valid and can't be created")
435
+ logger.error(msg)
436
+ return
437
+
438
+ else:
439
+ body = body_slimmer({
440
+ "class": "NewSolutionComponentRequestBody", "externalSourceGUID": external_source_guid,
441
+ "externalSourceName": external_source_name, "forLineage": False,
442
+ "forDuplicateProcessing": False, "effectiveTime": effective_time, "anchorGUID": anchor_guid,
443
+ "isOwnAnchor": True, "anchorScopeGUID": anchor_scope_guid, "parentGUID": parent_guid,
444
+ "parentRelationshipTypeName": parent_relationship_type_name, "parentAtEnd1": parent_at_end1,
445
+ "properties": {
446
+ "class": "SolutionComponentProperties", "effectiveFrom": effective_from,
447
+ "effectiveTo": effective_to, "extendedProperties": extended_properties,
448
+ "qualifiedName": qualified_name, "additionalProperties": additional_properties,
449
+ "displayName": display_name, "description": description,
450
+ "solutionComponentType": solution_component_type,
451
+ "plannedDeployedImplementationType": planned_deployed_impl_type
452
+
453
+ }
454
+ })
455
+
456
+ guid = egeria_client.create_solution_component(body)
457
+ if guid:
458
+ update_element_dictionary(qualified_name, {
459
+ 'guid': guid, 'display_name': display_name
460
+ })
461
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
462
+ logger.success(msg)
463
+ if sub_component_guids:
464
+ for comp in sub_component_guids:
465
+ egeria_client.link_subcomponent(guid, comp, None)
466
+ msg = f"Added `{sub_component_guids}` to `{display_name}`"
467
+ logger.trace(msg)
468
+
469
+ if actor_guids:
470
+ for actor in actor_guids:
471
+ egeria_client.link_component_to_role(actor, guid, None)
472
+ msg = f"Added `{actor_guids}` to `{display_name}`"
473
+ logger.trace(msg)
474
+
475
+ if in_blueprint_guids:
476
+ for bp in in_blueprint_guids:
477
+ egeria_client.link_solution_component_to_blueprint(bp, guid, None)
478
+ msg = f"Added `{in_blueprint_guids}` to `{display_name}`"
479
+ logger.trace(msg)
480
+
481
+ return egeria_client.get_solution_component_by_guid(guid, output_format='MD')
482
+ else:
483
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
484
+ logger.error(msg)
485
+ return None
486
+
487
+ except Exception as e:
488
+ logger.error(f"Error performing {command}: {e}")
489
+ return None
490
+ else:
491
+ return None
492
+
493
+
494
+ @logger.catch
495
+ def process_information_supply_chain_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") \
496
+ -> \
497
+ Optional[str]:
498
+ """
499
+ Processes a solution blueprint create or update object_action by extracting key attributes such as
500
+ blueprint name, description, and usage from the given text.
501
+
502
+ :param txt: A string representing the input cell to be processed for
503
+ extracting blueprint-related attributes.
504
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
505
+ :return: A string summarizing the outcome of the processing.
506
+ """
507
+ command, object_type, object_action = extract_command_plus(txt)
508
+
509
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
510
+
511
+ valid = parsed_output['valid']
512
+ exists = parsed_output['exists']
513
+
514
+ qualified_name = parsed_output.get('qualified_name', None)
515
+ guid = parsed_output.get('guid', None)
516
+
517
+ print(Markdown(parsed_output['display']))
518
+
519
+ logger.debug(json.dumps(parsed_output, indent=4))
520
+
521
+ attributes = parsed_output['attributes']
522
+ description = attributes.get('Description', {}).get('value', None)
523
+ display_name = attributes['Display Name'].get('value', None)
524
+ version_identifier = attributes.get('Version Identifier', {}).get('value', None)
525
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
526
+ effective_from = attributes.get('Effective From', {}).get('value', None)
527
+ effective_to = attributes.get('Effective To', {}).get('value', None)
528
+ external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
529
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
530
+
531
+ anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
532
+ parent_guid = attributes.get('Parent ID', {}).get('guid', None)
533
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
534
+ parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
535
+
536
+ anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
537
+ is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
538
+ if parent_guid is None:
539
+ is_own_anchor = True
540
+
541
+ additional_prop = attributes.get('Additional Properties', {}).get('value', None)
542
+ additional_properties = json.loads(additional_prop) if additional_prop is not None else None
543
+ extended_prop = attributes.get('Extended Properties', {}).get('value', None)
544
+ extended_properties = json.loads(extended_prop) if extended_prop is not None else None
545
+
546
+ scope = attributes.get('Scope', {}).get('value', None)
547
+ purposes = attributes.get('Purposes', {}).get('value', None)
548
+ segment_guids = attributes.get('Information Supply Chain Segments', {}).get('guid_list', None)
549
+
550
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
551
+
552
+ if directive == "display":
553
+
554
+ return None
555
+ elif directive == "validate":
556
+ if valid:
557
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
558
+ else:
559
+ msg = f"Validation failed for object_action `{command}`\n"
560
+ return valid
561
+
562
+ elif directive == "process":
563
+ try:
564
+ if object_action == "Update":
565
+ if not exists:
566
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
567
+ f"object_action\n")
568
+ logger.error(msg)
569
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
570
+ elif not valid:
571
+ return None
572
+ else:
573
+ print(Markdown(
574
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
575
+
576
+ body = body_slimmer({
577
+ "class": "UpdateInformationSupplyChainRequestBody", "externalSourceGUID": external_source_guid,
578
+ "externalSourceName": external_source_name, "effectiveTime": effective_time,
579
+ "forLineage": False, "forDuplicateProcessing": False, "properties": {
580
+ "class": "InformationSupplyChainProperties", "effectiveFrom": effective_from,
581
+ "effectiveTo": effective_to, "extendedProperties": extended_properties,
582
+ "qualifiedName": qualified_name, "additionalProperties": additional_properties,
583
+ "displayName": display_name, "description": description, "scope": scope,
584
+ "purposes": purposes, "version": version_identifier
585
+ }
586
+ })
587
+
588
+ egeria_client.update_info_supply_chain(guid, body, replace_all_props)
589
+ logger.success(f"==> Updated {object_type} `{display_name}` with GUID {guid}\n\n")
590
+ update_element_dictionary(qualified_name, {
591
+ 'guid': guid, 'display_name': display_name
592
+ })
593
+ # sync_blueprint_related_elements(egeria_client,object_type, segment_guids, guid, qualified_name,
594
+ # display_name, replace_all_props)
595
+ # logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
596
+ return egeria_client.get_info_supply_chain_by_guid(guid, output_format='MD')
597
+
598
+
599
+ elif object_action == "Create":
600
+ if valid is False and exists:
601
+ msg = (
602
+ f"--> Data Specification `{display_name}` already exists and result document updated changing "
603
+ f"`Create` to `Update` in processed output\n")
604
+ logger.error(msg)
605
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
606
+
607
+ elif valid is False:
608
+ msg = f"==>{object_type} `{display_name}` is not valid and can't be created"
609
+ logger.error(msg)
610
+ return
611
+ else:
612
+ body = {
613
+ "class": "NewInformationSupplyChainRequestBody", "externalSourceGUID": external_source_guid,
614
+ "externalSourceName": external_source_name, "forLineage": False,
615
+ "forDuplicateProcessing": False, "effectiveTime": effective_time, "anchorGUID": anchor_guid,
616
+ "isOwnAnchor": is_own_anchor, "anchorScopeGUID": anchor_scope_guid, "parentGUID": parent_guid,
617
+ "parentRelationshipTypeName": parent_relationship_type_name, "parentAtEnd1": parent_at_end1,
618
+ "properties": {
619
+ "class": "InformationSupplyChainProperties", "effectiveFrom": effective_from,
620
+ "effectiveTo": effective_to, "extendedProperties": extended_properties,
621
+ "qualifiedName": qualified_name, "additionalProperties": additional_properties,
622
+ "displayName": display_name, "description": description, "scope": scope,
623
+ "purposes": purposes, "version": version_identifier
624
+ }
625
+ }
626
+
627
+ guid = egeria_client.create_info_supply_chain(body)
628
+ if guid:
629
+ update_element_dictionary(qualified_name, {
630
+ 'guid': guid, 'display_name': display_name
631
+ })
632
+ msg = f"==>Created Element `{display_name}` with GUID {guid}\n"
633
+ logger.success(msg)
634
+ return egeria_client.get_info_supply_chain_by_guid(guid, output_format='MD')
635
+ else:
636
+ msg = f"==>Failed to create element `{display_name}` with GUID {guid}\n"
637
+ logger.error(msg)
638
+ return None
639
+
640
+ except Exception as e:
641
+ logger.error(f"Error performing {command}: {e}")
642
+ return None
643
+ else:
644
+ return None
645
+
646
+
647
+ @logger.catch
648
+ def process_information_supply_chain_segment_upsert_command(egeria_client: EgeriaTech, txt: str,
649
+ directive: str = "display") -> Optional[str]:
650
+ """
651
+ Processes a solution blueprint create or update object_action by extracting key attributes such as
652
+ blueprint name, description, and usage from the given text.
653
+
654
+ :param txt: A string representing the input cell to be processed for
655
+ extracting blueprint-related attributes.
656
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
657
+ :return: A string summarizing the outcome of the processing.
658
+ """
659
+ command, object_type, object_action = extract_command_plus(txt)
660
+
661
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
662
+
663
+ valid = parsed_output['valid']
664
+ exists = parsed_output['exists']
665
+
666
+ qualified_name = parsed_output.get('qualified_name', None)
667
+ guid = parsed_output.get('guid', None)
668
+
669
+ print(Markdown(parsed_output['display']))
670
+
671
+ logger.debug(json.dumps(parsed_output, indent=4))
672
+
673
+ attributes = parsed_output['attributes']
674
+ description = attributes.get('Description', {}).get('value', None)
675
+ display_name = attributes['Display Name'].get('value', None)
676
+ version_identifier = attributes.get('Version Identifier', {}).get('value', None)
677
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
678
+ effective_from = attributes.get('Effective From', {}).get('value', None)
679
+ effective_to = attributes.get('Effective To', {}).get('value', None)
680
+ external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
681
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
682
+
683
+ anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
684
+ parent_guid = attributes.get('Parent ID', {}).get('guid', None)
685
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
686
+ parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
687
+
688
+ anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
689
+ is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
690
+ if parent_guid is None:
691
+ is_own_anchor = True
692
+
693
+ additional_prop = attributes.get('Additional Properties', {}).get('value', None)
694
+ additional_properties = json.loads(additional_prop) if additional_prop is not None else None
695
+ extended_prop = attributes.get('Extended Properties', {}).get('value', None)
696
+ extended_properties = json.loads(extended_prop) if extended_prop is not None else None
697
+
698
+ scope = attributes.get('Scope', {}).get('value', None)
699
+ integration_style = attributes.get('Integration Style', {}).get('value', None)
700
+ volumetrics = attributes.get('Estimated Volumetrics', {}).get('value', None)
701
+ info_supply_chain = attributes.get('Information Supply Chain', {}).get('value', None)
702
+ info_supply_chain_guid = attributes.get('Information Supply Chain', {}).get('guid', None)
703
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
704
+
705
+ if directive == "display":
706
+
707
+ return None
708
+ elif directive == "validate":
709
+ if valid:
710
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
711
+ else:
712
+ msg = f"Validation failed for object_action `{command}`\n"
713
+ return valid
714
+
715
+ elif directive == "process":
716
+ try:
717
+ if object_action == "Update":
718
+ if not exists:
719
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
720
+ f"object_action\n")
721
+ logger.error(msg)
722
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
723
+ elif not valid:
724
+ return None
725
+ else:
726
+ print(Markdown(
727
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
728
+
729
+ body = body_slimmer({
730
+ "class": "UpdateInformationSupplyChainSegmentRequestBody",
731
+ "externalSourceGUID": external_source_guid, "externalSourceName": external_source_name,
732
+ "effectiveTime": effective_time, "forLineage": False, "forDuplicateProcessing": False,
733
+ "properties": {
734
+ "class": "InformationSupplyChainSegmentProperties", "effectiveFrom": effective_from,
735
+ "effectiveTo": effective_to, "extendedProperties": extended_properties,
736
+ "qualifiedName": qualified_name, "additionalProperties": additional_properties,
737
+ "displayName": display_name, "description": description, "scope": scope,
738
+ "integrationStyle": integration_style, "estimatedVolumetrics": volumetrics,
739
+ "version": version_identifier
740
+ }
741
+ })
742
+
743
+ egeria_client.update_info_supply_chain_segment(info_supply_chain_guid, body, replace_all_props)
744
+ update_element_dictionary(qualified_name, {
745
+ 'guid': guid, 'display_name': display_name
746
+ })
747
+ logger.success(f"===> Updated {object_type} `{display_name}` with GUID {guid}\n")
748
+ # sync_blueprint_related_elements(egeria_client,object_type, segment_guids, guid, qualified_name,
749
+ # display_name, replace_all_props)
750
+ # logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
751
+ return egeria_client.get_info_supply_chain_segment_by_guid(guid, info_supply_chain_guid)
752
+
753
+
754
+ elif object_action == "Create":
755
+ if valid is False and exists:
756
+ msg = (
757
+ f"--> Data Specification `{display_name}` already exists and result document updated changing "
758
+ f"`Create` to `Update` in processed output\n")
759
+ logger.error(msg)
760
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
761
+
762
+ elif valid is False:
763
+ msg = f"==>{object_type} `{display_name}` is not valid and can't be created"
764
+ logger.error(msg)
765
+ return
766
+ else:
767
+ body = {
768
+ "class": "NewInformationSupplyChainSegmentRequestBody",
769
+ "externalSourceGUID": external_source_guid, "externalSourceName": external_source_name,
770
+ "forLineage": False, "forDuplicateProcessing": False, "effectiveTime": effective_time,
771
+ "anchorGUID": anchor_guid, "isOwnAnchor": is_own_anchor, "anchorScopeGUID": anchor_scope_guid,
772
+ "parentGUID": parent_guid, "parentRelationshipTypeName": parent_relationship_type_name,
773
+ "parentAtEnd1": parent_at_end1, "properties": {
774
+ "class": "InformationSupplyChainSegmentProperties", "effectiveFrom": effective_from,
775
+ "effectiveTo": effective_to, "extendedProperties": extended_properties,
776
+ "qualifiedName": qualified_name, "additionalProperties": additional_properties,
777
+ "displayName": display_name, "description": description, "scope": scope,
778
+ "integrationStyle": integration_style, "estimatedVolumetrics": volumetrics,
779
+ "version": version_identifier
780
+ }
781
+ }
782
+
783
+ guid = egeria_client.create_info_supply_chain_segment(info_supply_chain_guid, body)
784
+ if guid:
785
+ update_element_dictionary(qualified_name, {
786
+ 'guid': guid, 'display_name': display_name
787
+ })
788
+ msg = f"==>Created Element `{display_name}` with GUID {guid}\n"
789
+ logger.success(msg)
790
+ return egeria_client.get_info_supply_chain_segment_by_guid(guid, info_supply_chain_guid)
791
+ else:
792
+ msg = f"==>Failed to create element `{display_name}` with GUID {guid}\n"
793
+ logger.error(msg)
794
+ return None
795
+
796
+ except Exception as e:
797
+ logger.error(f"Error performing {command}: {e}")
798
+ return None
799
+ else:
800
+ return None
801
+
802
+
803
+ @logger.catch
804
+ def process_information_supply_chain_link_unlink_command(egeria_client: EgeriaTech, txt: str,
805
+ directive: str = "display") -> Optional[str]:
806
+ """
807
+ Processes a solution blueprint create or update object_action by extracting key attributes such as
808
+ blueprint name, description, and usage from the given text.
809
+
810
+ :param txt: A string representing the input cell to be processed for
811
+ extracting blueprint-related attributes.
812
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
813
+ :return: A string summarizing the outcome of the processing.
814
+ """
815
+ command, object_type, object_action = extract_command_plus(txt)
816
+
817
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
818
+
819
+ print(Markdown(parsed_output['display']))
820
+
821
+ logger.debug(json.dumps(parsed_output, indent=4))
822
+
823
+ attributes = parsed_output['attributes']
824
+
825
+ segment1 = attributes.get('Segment1', {}).get('guid', None)
826
+ segment2 = attributes.get('Segment1', {}).get('guid', None)
827
+ label = attributes.get('Link Label', {}).get('value', None)
828
+ description = attributes.get('Description', {}).get('value', None)
829
+
830
+ valid = parsed_output['valid']
831
+ exists = parsed_output['exists']
832
+
833
+ external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
834
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
835
+
836
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
837
+ effective_from = attributes.get('Effective From', {}).get('value', None)
838
+ effective_to = attributes.get('Effective To', {}).get('value', None)
839
+
840
+ additional_prop = attributes.get('Additional Properties', {}).get('value', None)
841
+ additional_properties = json.loads(additional_prop) if additional_prop is not None else None
842
+ extended_prop = attributes.get('Extended Properties', {}).get('value', None)
843
+ extended_properties = json.loads(extended_prop) if extended_prop is not None else None
844
+
845
+ if directive == "display":
846
+
847
+ return None
848
+ elif directive == "validate":
849
+ if valid:
850
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
851
+ else:
852
+ msg = f"Validation failed for object_action `{command}`\n"
853
+ return valid
854
+
855
+ elif directive == "process":
856
+ try:
857
+ if object_action == "Detach":
858
+ if not exists:
859
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
860
+ f"object_action\n")
861
+ logger.error(msg)
862
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
863
+ return out
864
+ elif not valid:
865
+ return None
866
+ else:
867
+ print(Markdown(
868
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
869
+
870
+ body = body_slimmer({
871
+ "class": "MetadataSourceRequestBody", "externalSourceGUID": external_source_guid,
872
+ "externalSourceName": external_source_name, "effectiveTime": effective_time,
873
+ "forLineage": False, "forDuplicateProcessing": False
874
+
875
+ })
876
+
877
+ egeria_client.detach_info_supply_chain_segments(segment1, segment2, body)
878
+
879
+ logger.success(f"===> Detached segment with {label} from `{segment1}`to {segment2}\n")
880
+ out = parsed_output['display'].replace('Detach', 'Link', 1)
881
+
882
+ return (out)
883
+
884
+
885
+ elif object_action == "Link":
886
+ if valid is False and exists:
887
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
888
+ f"`Link` to `Detach` in processed output\n")
889
+ logger.error(msg)
890
+
891
+ elif valid is False:
892
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
893
+ logger.error(msg)
894
+ return
895
+ else:
896
+ body = {
897
+ "class": "InformationSupplyChainLinkRequestBody", "effectiveTime": effective_time,
898
+ "forLineage": False, "forDuplicateProcessing": False, "properties": {
899
+ "class": "InformationSupplyChainLinkProperties", "label": label, "description": description,
900
+ "effectiveFrom": effective_from, "effectiveTo": effective_to
901
+ }
902
+ }
903
+
904
+ egeria_client.link_info_supply_chain_segments(segment1, segment2, body)
905
+ msg = f"==>Created {object_type} link named `{label}`\n"
906
+ logger.success(msg)
907
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
908
+ return out
909
+
910
+
911
+ except Exception as e:
912
+ logger.error(f"Error performing {command}: {e}")
913
+ return None
914
+ else:
915
+ return None
916
+
917
+ @logger.catch
918
+ def process_sol_arch_list_command(egeria_client: EgeriaTech, txt: str, kind:str, directive: str = "display" ) -> Optional[str]:
919
+ """
920
+ Processes a Informartion Blueprint list object_action by extracting key attributes such as
921
+ search string from the given text.
922
+
923
+ :param txt: A string representing the input cell to be processed for
924
+ extracting term-related attributes.
925
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
926
+ :return: A string summarizing the outcome of the processing.
927
+ """
928
+ command, object_type, object_action = extract_command_plus(txt)
929
+
930
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
931
+
932
+ attributes = parsed_output['attributes']
933
+
934
+ valid = parsed_output['valid']
935
+
936
+ print(Markdown(parsed_output['display']))
937
+
938
+ if directive == "display":
939
+ return None
940
+ elif directive == "validate":
941
+ if valid:
942
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
943
+ else:
944
+ msg = f"Validation failed for object_action `{command}`\n"
945
+ logger.error(msg)
946
+ return valid
947
+
948
+ elif directive == "process":
949
+ attributes = parsed_output['attributes']
950
+ search_string = attributes.get('Search String', {}).get('value', '*')
951
+ output_format = attributes.get('Output Format', {}).get('value', 'LIST')
952
+ detailed = attributes.get('Detailed', {}).get('value', False)
953
+
954
+ match kind:
955
+ case "Solution Blueprints":
956
+ find_proc = egeria_client.find_solution_blueprints
957
+ case "Information Supply Chains":
958
+ find_proc = egeria_client.find_information_supply_chains
959
+ case "Solution Components":
960
+ find_proc = egeria_client.find_solution_components
961
+ case "Solution Roles":
962
+ find_proc = egeria_client.find_solution_roles
963
+
964
+ try:
965
+ if not valid: # First validate the command before we process it
966
+ msg = f"Validation failed for {object_action} `{object_type}`\n"
967
+ logger.error(msg)
968
+ return None
969
+
970
+ list_md = f"\n# {kind} with filter: `{search_string}`\n\n"
971
+ if output_format == "DICT":
972
+ struct = find_proc(search_string, output_format=output_format)
973
+ list_md += f"```{json.dumps(struct, indent=4)}```\n"
974
+ else:
975
+ list_md += find_proc(search_string, output_format=output_format)
976
+ logger.info(f"Wrote Output for search string: `{search_string}`")
977
+
978
+ return list_md
979
+
980
+ except Exception as e:
981
+ logger.error(f"Error performing {command}: {e}")
982
+ console.print_exception(show_locals=True)
983
+ return None
984
+ else:
985
+ return None