pyegeria 5.4.0.dev13__py3-none-any.whl → 5.4.0.dev14__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 (109) hide show
  1. commands/cat/debug_log +2802 -2
  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_md.py +30 -6
  5. md_processing/__init__.py +16 -3
  6. md_processing/data/commands.json +18541 -171
  7. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
  8. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
  9. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
  10. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
  11. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
  12. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  13. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  14. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  15. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  16. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
  17. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
  18. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
  19. md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
  20. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
  21. md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
  22. md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
  23. md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
  24. md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
  25. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
  26. md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
  27. md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
  28. md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
  29. md_processing/family_docs/Data Designer.md +842 -0
  30. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
  31. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
  32. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
  33. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
  34. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
  35. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
  36. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
  37. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
  38. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
  39. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
  40. md_processing/family_docs/Digital Product Manager.md +668 -0
  41. md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
  42. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
  43. md_processing/family_docs/Glossary/Create_Category.md +38 -0
  44. md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
  45. md_processing/family_docs/Glossary/Create_Term.md +70 -0
  46. md_processing/family_docs/Glossary.md +206 -0
  47. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
  48. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
  49. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
  50. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
  51. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
  52. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
  53. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
  54. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
  55. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
  56. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
  57. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
  58. md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
  59. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
  60. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
  61. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
  62. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
  63. md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
  64. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
  65. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
  66. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
  67. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
  68. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
  69. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
  70. md_processing/family_docs/Governance Officer.md +2412 -0
  71. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
  72. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
  73. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
  74. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
  75. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
  76. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
  77. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
  78. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
  79. md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
  80. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
  81. md_processing/family_docs/Solution Architect.md +490 -0
  82. md_processing/md_commands/data_designer_commands.py +9 -10
  83. md_processing/md_commands/glossary_commands.py +16 -2
  84. md_processing/md_commands/governance_officer_commands.py +420 -0
  85. md_processing/md_commands/product_manager_commands.py +186 -752
  86. md_processing/md_commands/project_commands.py +5 -2
  87. md_processing/md_commands/solution_architect_commands.py +9 -8
  88. md_processing/md_processing_utils/common_md_proc_utils.py +15 -10
  89. md_processing/md_processing_utils/common_md_utils.py +194 -2
  90. md_processing/md_processing_utils/debug_log +574 -0
  91. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
  92. md_processing/md_processing_utils/extraction_utils.py +1 -1
  93. md_processing/md_processing_utils/generate_dr_help.py +20 -5
  94. md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
  95. md_processing/md_processing_utils/md_processing_constants.py +56 -4
  96. pyegeria/governance_officer_omvs.py +14 -99
  97. pyegeria/output_formatter.py +3 -2
  98. pyegeria/utils.py +7 -0
  99. {pyegeria-5.4.0.dev13.dist-info → pyegeria-5.4.0.dev14.dist-info}/METADATA +1 -1
  100. {pyegeria-5.4.0.dev13.dist-info → pyegeria-5.4.0.dev14.dist-info}/RECORD +103 -29
  101. commands/cat/debug_log.2025-07-01_15-22-20_102237.zip +0 -0
  102. commands/cat/debug_log.2025-07-04_15-43-28_460900.zip +0 -0
  103. commands/cat/debug_log.2025-07-06_20-48-04_338314.zip +0 -0
  104. commands/cat/debug_log.2025-07-09_10-17-09_526262.zip +0 -0
  105. commands/cat/debug_log.2025-07-10_10-25-47_958331.zip +0 -0
  106. pyegeria/m_test.py +0 -118
  107. {pyegeria-5.4.0.dev13.dist-info → pyegeria-5.4.0.dev14.dist-info}/LICENSE +0 -0
  108. {pyegeria-5.4.0.dev13.dist-info → pyegeria-5.4.0.dev14.dist-info}/WHEEL +0 -0
  109. {pyegeria-5.4.0.dev13.dist-info → pyegeria-5.4.0.dev14.dist-info}/entry_points.txt +0 -0
@@ -12,7 +12,9 @@ from rich.console import Console
12
12
  from rich.markdown import Markdown
13
13
 
14
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
15
+ from md_processing.md_processing_utils.common_md_utils import update_element_dictionary, setup_log, set_update_body, \
16
+ set_element_status_request_body, set_prop_body, set_metadata_source_request_body, set_peer_gov_def_request_body, \
17
+ set_rel_request_body
16
18
  from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
17
19
  from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
18
20
  from pyegeria import DEBUG_LEVEL, body_slimmer
@@ -41,15 +43,7 @@ load_commands('commands.json')
41
43
  debug_level = DEBUG_LEVEL
42
44
 
43
45
  console = Console(width=int(200))
44
-
45
- log_format = "D {time} | {level} | {function} | {line} | {message} | {extra}"
46
- logger.remove()
47
- logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
48
- full_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_INBOX_PATH, "data_designer_debug.log")
49
- # logger.add(full_file_path, rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
50
- # colorize=True)
51
- logger.add("debug_log", rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
52
- colorize=True)
46
+ setup_log()
53
47
 
54
48
 
55
49
  #
@@ -411,12 +405,14 @@ def sync_data_class_rel_elements(egeria_client: EgeriaTech, containing_data_clas
411
405
  egeria_client.link_specialist_data_class(guid, el)
412
406
  msg = f"Linked `{el}` to `{display_name}`"
413
407
  logger.trace(msg)
414
-
408
+ #
409
+ # Product Manager Commands
410
+ #
415
411
 
416
412
  @logger.catch
417
413
  def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
418
414
  """
419
- Processes a data specification create or update object_action by extracting key attributes such as
415
+ Processes a digital product create or update object_action by extracting key attributes such as
420
416
  spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
421
417
 
422
418
  :param txt: A string representing the input cell to be processed for
@@ -426,6 +422,7 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
426
422
  """
427
423
 
428
424
  command, object_type, object_action = extract_command_plus(txt)
425
+ print(Markdown(f"# {command}\n"))
429
426
 
430
427
  parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
431
428
 
@@ -442,38 +439,32 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
442
439
  attributes = parsed_output['attributes']
443
440
 
444
441
  display_name = attributes['Display Name'].get('value', None)
445
- description = attributes['Description'].get('value', None)
446
- user_defined_status = attributes['User Defined Status'].get('value', None)
447
- product_identifier = attributes['Product Identifier'].get('value', None)
448
- product_name = attributes['Product Name'].get('value', None)
449
- product_type = attributes['Product Type'].get('value', None)
442
+ description = attributes.get('Description',{}).get('value', None)
443
+ user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
444
+ product_identifier = attributes.get('Product Identifier',{}).get('value', None)
445
+ product_name = attributes.get('Product Name',{}).get('value', None)
446
+ product_type = attributes.get('Product Type',{}).get('value', None)
450
447
 
451
448
 
452
449
 
453
- product_description = attributes['Product Description'].get('value', None)
454
- maturity = attributes['Maturity'].get('value', None)
455
- service_life = attributes['Service Life'].get('value', None)
456
- introduction_date = attributes['Introduction Date'].get('value', None)
457
- next_version_date = attributes['Next Version Date'].get('value', None)
458
- withdrawal_date = attributes['Withdrawal Date'].get('value', None)
450
+ product_description = attributes.get('Product Description',{}).get('value', None)
451
+ maturity = attributes.get('Maturity',{}).get('value', None)
452
+ service_life = attributes.get('Service Life',{}).get('value', None)
453
+ introduction_date = attributes.get('Introduction Date',{}).get('value', None)
454
+ next_version_date = attributes.get('Next Version Date',{}).get('value', None)
455
+ withdrawal_date = attributes.get('Withdrawal Date',{}).get('value', None)
459
456
 
460
457
  collection_type = attributes.get('Collection Type', {}).get('value', None)
461
- current_version = attributes['Current Version'].get('value', None)
462
- product_manager = attributes['Product Manager'].get('value', None)
463
-
464
- agreements = attributes['Agreements'].get('value', None)
465
- agreement_names = attributes['Agreements Names'].get('name_list', None)
466
- agreement_guids = attributes['Agreements Guids'].get('guid_list', None)
458
+ current_version = attributes.get('Version Identifier',{}).get('value', None)
459
+ product_manager = attributes.get('Product Manager',{}).get('value', None)
467
460
 
468
- subscriptions = attributes['Digital Subscriptions'].get('value', None)
469
- subscription_names = attributes['Digital Subscriptions Names'].get('name_list', None)
470
- subscription_guids = attributes['Digital Subscriptions Guids'].get('guid_list', None)
471
461
 
472
- product_status = attributes['Product Status'].get('value', "ACTIVE")
462
+ product_status = attributes.get('Status',{}).get('value', "ACTIVE")
473
463
 
474
464
  anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
475
465
  parent_guid = attributes.get('Parent ID', {}).get('guid', None)
476
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', "CollectionMembership")
466
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
467
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
477
468
  parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
478
469
  anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
479
470
  is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
@@ -516,6 +507,7 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
516
507
  else:
517
508
  print(Markdown(
518
509
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
510
+ prop_body = set_prop_body(object_type,qualified_name,attributes)
519
511
 
520
512
  body ={
521
513
  "class": "UpdateElementRequestBody",
@@ -534,7 +526,6 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
534
526
  "nextVersionDate": next_version_date,
535
527
  "withdrawDate": withdrawal_date,
536
528
  "currentVersion": current_version,
537
-
538
529
  "additionalProperties": additional_properties,
539
530
  "extendedProperties": extended_properties,
540
531
  },
@@ -621,9 +612,9 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
621
612
 
622
613
 
623
614
  @logger.catch
624
- def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
615
+ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
625
616
  """
626
- Processes a data dictionary create or update object_action by extracting key attributes such as
617
+ Processes an agreement create or update object_action by extracting key attributes such as
627
618
  spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
628
619
 
629
620
  :param txt: A string representing the input cell to be processed for
@@ -633,6 +624,7 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
633
624
  """
634
625
 
635
626
  command, object_type, object_action = extract_command_plus(txt)
627
+ print(Markdown(f"# {command}\n"))
636
628
 
637
629
  parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
638
630
 
@@ -643,31 +635,47 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
643
635
  guid = parsed_output.get('guid', None)
644
636
 
645
637
  print(Markdown(parsed_output['display']))
638
+
646
639
  logger.debug(json.dumps(parsed_output, indent=4))
647
640
 
648
641
  attributes = parsed_output['attributes']
649
- description = attributes['Description'].get('value', None)
650
- display_name = attributes.get('Display Name', {}).get('value', "None Found")
651
- display_name = display_name if display_name is not None else "None Found"
642
+
643
+ display_name = attributes['Display Name'].get('value', None)
644
+ description = attributes.get('Description',{}).get('value', None)
645
+ user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
646
+ agreement_status = attributes.get('Status',{}).get('value', None)
647
+ agreement_identifier = attributes.get('Agreement Identifier',{}).get('value', None)
648
+
649
+ version_identifier = attributes.get('Version Identifier',{}).get('value', None)
650
+
651
+ actors = attributes.get('Agreement Actors',{}).get('value', None)
652
+ actor_names = attributes.get('Agreement Actors',{}).get('name_list', None)
653
+ actor_guids = attributes.get('Agreement Actors',{}).get('guid_list', None)
652
654
  anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
653
655
  parent_guid = attributes.get('Parent ID', {}).get('guid', None)
654
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',
655
- "CollectionMembership")
656
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
657
+ parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
656
658
  parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
657
-
658
659
  anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
659
660
  is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
660
661
  if parent_guid is None:
661
662
  is_own_anchor = True
662
- collection_type = attributes.get('Collection Type', {}).get('value', None)
663
- replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
663
+
664
664
 
665
665
  additional_prop = attributes.get('Additional Properties', {}).get('value', None)
666
666
  additional_properties = json.loads(additional_prop) if additional_prop is not None else None
667
667
  extended_prop = attributes.get('Extended Properties', {}).get('value', None)
668
668
  extended_properties = json.loads(extended_prop) if extended_prop is not None else None
669
+ external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
670
+ external_source_name = attributes.get('External Source Name', {}).get('value', None)
671
+ effective_time = attributes.get('Effective Time', {}).get('value', None)
672
+ for_lineage = attributes.get('For Lineage', {}).get('value', None)
673
+ for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
674
+
675
+ replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
669
676
 
670
677
  if directive == "display":
678
+
671
679
  return None
672
680
  elif directive == "validate":
673
681
  if valid:
@@ -677,561 +685,130 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
677
685
  return valid
678
686
 
679
687
  elif directive == "process":
680
-
681
688
  try:
682
689
  if object_action == "Update":
683
-
684
690
  if not exists:
685
- logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
686
- f"object_action\n\n___")
691
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
692
+ f"object_action\n")
693
+ logger.error(msg)
687
694
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
688
695
  elif not valid:
689
- logger.error(f"Element `{display_name}` does not have a valid specification? Review..\n\n___ ")
690
696
  return None
691
697
  else:
692
698
  print(Markdown(
693
- f"==> Validation of {command} completed successfully! Proceeding to apply the changes."))
694
-
695
- egeria_client.update_collection(guid, qualified_name, display_name, description, collection_type,
696
- additional_properties,
697
- extended_properties, replace_all_props)
698
- logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
699
- update_element_dictionary(qualified_name, {
700
- 'guid': guid, 'display_name': display_name
701
- })
702
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Dictionary', output_format='MD')
703
-
704
- elif object_action == "Create":
705
- if valid is False and exists:
706
- logger.error(f"\nElement `{display_name}` already exists and result document updated changing "
707
- f"`Create` to `Update` in processed output\n\n___")
708
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
709
- else:
710
- guid = egeria_client.create_data_dictionary_collection(display_name, description, qualified_name,
711
- is_own_anchor, anchor_guid, parent_guid,
712
- parent_relationship_type_name,
713
- parent_at_end1, collection_type,
714
- anchor_scope_guid, additional_properties,
715
- extended_properties)
716
- if guid:
717
- update_element_dictionary(qualified_name, {
718
- 'guid': guid, 'display_name': display_name
719
- })
720
- logger.success(f"Created Element `{display_name}` with GUID {guid}\n\n___")
721
-
722
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Dictionary',
723
- output_format='MD')
724
- else:
725
- logger.error(f"Failed to create Term `{display_name}`\n\n___")
726
- return None
727
-
728
- except Exception as e:
729
- logger.error(f"{ERROR}Error performing {command}: {e}")
730
- Console().print_exception(show_locals=True)
731
- return None
732
- else:
733
- return None
734
-
735
-
736
- @logger.catch
737
- def process_data_structure_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
738
- str]:
739
- """
740
- Processes a data structure create or update object_action by extracting key attributes such as
741
- spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
742
-
743
- :param txt: A string representing the input cell to be processed for
744
- extracting glossary-related attributes.
745
- :param directive: an optional string indicating the directive to be used - display, validate or execute
746
- :return: A string summarizing the outcome of the processing.
747
- """
748
- from md_processing.md_processing_utils.common_md_utils import set_debug_level
749
-
750
- set_debug_level(directive)
751
-
752
- command, object_type, object_action = extract_command_plus(txt)
753
-
754
- parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
755
-
756
- valid = parsed_output['valid']
757
- exists = parsed_output['exists']
758
-
759
- qualified_name = parsed_output.get('qualified_name', None)
760
- guid = parsed_output.get('guid', None)
761
-
762
- print(Markdown(parsed_output['display']))
763
-
764
- if directive == "display":
765
- return None
766
-
767
- elif directive == "validate":
768
- if valid:
769
- print(Markdown(f"==> Validation of {command} completed successfully!\n"))
770
- else:
771
- msg = f"Validation failed for object_action `{command}`\n"
772
- return valid
773
-
774
- elif directive == "process":
775
- logger.debug(json.dumps(parsed_output, indent=4))
776
- attributes = parsed_output['attributes']
699
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
777
700
 
778
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
779
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
780
- effective_time = attributes.get('Effective Time', {}).get('value', None)
781
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
782
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
783
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
784
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', None)
785
- parent_id = attributes.get('Parent ID', {}).get('value', None)
786
- parent_guid = attributes.get('Parent ID', {}).get('guid', None)
787
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
788
- parent_relationship_properties = attributes.get('Parent Relationship Properties', {}).get('value', None)
789
- parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
790
-
791
- display_name = attributes['Display Name'].get('value', None)
792
-
793
- namespace = attributes.get('Namespace', {}).get('value', None)
794
- description = attributes.get('Description', {}).get('value', None)
795
- version_id = attributes.get('Version Identifier', {}).get('value', None)
796
- aliases = attributes.get('Aliases', {}).get('value', None)
797
- name_patterns = attributes.get('Name Patterns', {}).get('value', None)
798
- is_nullable = attributes.get('Is Nullable', {}).get('value', None)
799
- default_value = attributes.get('Default Value', {}).get('value', None)
800
- data_type = attributes.get('Data Type', {}).get('value', None)
801
- min_length = attributes.get('Minimum Length', {}).get('value', None)
802
- length = attributes.get('Length', {}).get('value', None)
803
- precision = attributes.get('Precision', {}).get('value', None)
804
- ordered_values = attributes.get('Ordered Values', {}).get('value', None)
805
- sort_order = attributes.get('Sort Order', {}).get('value', None)
806
- additional_properties = attributes.get('Additional Properties', {}).get('value', None)
807
- effective_from = attributes.get('Effective From', {}).get('value', None)
808
- effective_to = attributes.get('Effective To', {}).get('value', None)
809
-
810
- position = attributes.get('Position', {}).get('value', None)
811
- min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
812
- max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
813
- in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
814
- data_class = attributes.get('Data Class', {}).get('value', None)
815
- glossary_term = attributes.get('Glossary Term', {}).get('value', None)
816
- glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
817
-
818
- # name_details_list = attributes.get("dict_list", None)
819
-
820
- data_spec_name_list = attributes.get("In Data Specification", {}).get("name_list", "")
821
- data_spec_value = attributes.get("In Data Specification", {}).get("value", None)
822
- data_spec_guid_list = attributes.get("In Data Specification", {}).get("guid_list", None)
823
-
824
- in_data_dictionary = attributes.get('In Data Dictionary', {}).get('dict_list', None)
825
- data_dict_name_list = attributes.get('In Data Dictionary', {}).get('name_list', "")
826
- data_dict_value_list = attributes.get('In Data Dictionary', {}).get('value', None)
827
- data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
828
-
829
- parent_data_field = attributes.get('Parent Data Field', {}).get('value', None)
830
- parent_data_field_guid = attributes.get('Parent Data Field', {}).get('guid', None)
831
-
832
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
833
-
834
- collection_type = object_type
835
- replace_all_props = True
836
- if not valid:
837
- if exists and object_action == "Create":
838
- msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
839
- f"processed output \n\n___")
840
- logger.error(msg)
841
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
842
- else:
843
- return None
844
- elif object_action == "Update" and not exists:
845
- logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
846
- f"object_action\n\n___")
847
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
701
+ product_body = {
702
+ "class": "AgreementProperties",
703
+ "qualifiedName": qualified_name,
704
+ "userDefinedStatus": user_defined_status,
705
+ "name": display_name,
706
+ "description": description,
707
+ "identifier": agreement_identifier,
708
+ "additionalProperties": additional_properties,
709
+ "extendedProperties": extended_properties,
710
+ }
848
711
 
849
- else:
850
- print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
712
+ body = set_update_body(object_type, attributes)
713
+ body['properties'] = product_body
851
714
 
852
- try:
853
- if object_action == "Update":
854
- body = {
855
- "class": "UpdateElementRequestBody", "externalSourceGUID": external_source_guid,
856
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
857
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
858
- "class": "DataStructureProperties", "qualifiedName": qualified_name,
859
- "displayName": display_name, "description": description, "namespace": namespace,
860
- "versionIdentifier": version_id, "additionalProperties": additional_properties,
861
- "effectiveFrom": effective_from, "effectiveTo": effective_to
862
- }
863
- }
864
- egeria_client.update_data_structure_w_body(guid, body, replace_all_props)
865
- logger.info(f"Updated element `{display_name}` with GUID {guid}")
866
- core_props = egeria_client.get_data_structure_by_guid(guid, output_format='MD')
715
+ egeria_client.update_agreement(guid, body, replace_all_props)
716
+ status_update_body = set_element_status_request_body(object_type, attributes)
717
+ egeria_client.update_agreement_status(guid, status_update_body)
867
718
 
719
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
868
720
  update_element_dictionary(qualified_name, {
869
721
  'guid': guid, 'display_name': display_name
870
722
  })
871
-
872
- update_data_collection_memberships(egeria_client, object_type, data_spec_guid_list, "DataSpec", guid,
873
- display_name, replace_all_props)
874
- core_props += f"## In Data Dictionary\n\n{data_dict_name_list}\n\n"
875
- core_props += f"## In Data Specification\n\n{data_spec_name_list}\n\n"
876
- logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
877
- return core_props
723
+ return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
724
+ output_format='MD')
878
725
 
879
726
  elif object_action == "Create":
880
- if exists:
881
- logger.warning(f"\nTerm `{display_name}` already exists and result document updated\n\n___")
727
+ if valid is False and exists:
728
+ msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
729
+ f"`Create` to `Update` in processed output\n\n___")
730
+ logger.error(msg)
882
731
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
883
- else:
884
732
 
733
+ else:
885
734
  body = {
886
- "class": "NewElementRequestBody", "externalSourceGUID": external_source_guid,
887
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
888
- "forLineage": False, "forDuplicateProcessing": False, "anchorGUID": anchor_guid,
889
- "isOwnAnchor": is_own_anchor, "parentGUID": parent_guid,
735
+ "class": "NewAgreementRequestBody",
736
+ "isOwnAnchor": is_own_anchor,
737
+ "parentGUID": parent_guid,
890
738
  "parentRelationshipTypeName": parent_relationship_type_name,
891
- "parentRelationshipProperties": parent_relationship_properties, "parentAtEnd1": parent_at_end1,
739
+ "parentAtEnd1": parent_at_end1,
892
740
  "properties": {
893
- "class": "DataStructureProperties", "qualifiedName": qualified_name,
894
- "displayName": display_name, "description": description, "namespace": namespace,
895
- "versionIdentifier": version_id, "additionalProperties": additional_properties,
896
- "effectiveFrom": effective_from, "effectiveTo": effective_to
897
- }
741
+ "class": "AgreementProperties",
742
+ "qualifiedName": qualified_name,
743
+ "userDefinedStatus": user_defined_status,
744
+ "name": display_name,
745
+ "description" : description,
746
+ "identifier" : agreement_identifier,
747
+ "additionalProperties": additional_properties,
748
+ "extendedProperties": extended_properties,
749
+ },
750
+ "initialStatus": agreement_status,
751
+ "externalSourceGUID": external_source_guid,
752
+ "externalSourceName": external_source_name,
753
+ "effectiveTime" : effective_time,
754
+ "forLineage": for_lineage,
755
+ "forDuplicateProcessing": for_duplicate_processing
898
756
  }
757
+ if object_type == "Data Sharing Agreement":
758
+ guid = egeria_client.create_data_sharing_agreement(body)
759
+ elif object_type == "Agreement":
760
+ guid = egeria_client.create_agreement(body)
899
761
 
900
- guid = egeria_client.create_data_structure_w_body(body_slimmer(body))
901
762
  if guid:
902
763
  update_element_dictionary(qualified_name, {
903
764
  'guid': guid, 'display_name': display_name
904
765
  })
905
-
906
- core_props = egeria_client.get_data_structure_by_guid(guid, output_format='MD')
907
-
908
- if in_data_dictionary:
909
- logger.info(f"Will add to data dictionary(s) `{in_data_dictionary}`")
910
- result = add_member_to_collections(egeria_client, in_data_dictionary, display_name,
911
- guid)
912
- core_props += f"## In Data Dictionary\n\n{data_dict_name_list}\n\n"
913
-
914
- if data_spec_guid_list:
915
- result = add_member_to_collections(egeria_client, data_spec_guid_list, display_name,
916
- guid)
917
- core_props += f"## In Data Specifications\n\n`{data_spec_name_list}`\n\n"
918
-
919
- logger.info(f"Created Element `{display_name}` with GUID {guid}\n\n___")
920
-
921
- return core_props
766
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
767
+ logger.success(msg)
768
+ return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
769
+ output_format='MD')
922
770
  else:
923
- logger.error(f"Failed to create Data Structure `{display_name}`\n\n___")
771
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
772
+ logger.error(msg)
924
773
  return None
925
774
 
926
-
927
775
  except Exception as e:
928
- logger.error(f"Error performing {object_action}: {e}\n\n___")
776
+ logger.error(f"Error performing {command}: {e}")
929
777
  return None
930
778
  else:
931
779
  return None
932
780
 
933
781
 
934
- @logger.catch
935
- def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
782
+ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
783
+ directive: str = "display") -> Optional[str]:
936
784
  """
937
- Processes a data field create or update object_action by extracting key attributes such as
938
- spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
785
+ Processes a link or unlink command to associate or break up peer governance definitions.
939
786
 
940
787
  :param txt: A string representing the input cell to be processed for
941
- extracting glossary-related attributes.
788
+ extracting blueprint-related attributes.
942
789
  :param directive: an optional string indicating the directive to be used - display, validate or execute
943
790
  :return: A string summarizing the outcome of the processing.
944
791
  """
945
- from md_processing.md_processing_utils.common_md_utils import set_debug_level
946
-
947
- set_debug_level(directive)
948
-
949
792
  command, object_type, object_action = extract_command_plus(txt)
793
+ print(Markdown(f"# {command}\n"))
950
794
 
951
- parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
952
- attributes = parsed_output['attributes']
953
- display_name = attributes['Display Name'].get('value', None)
954
- qualified_name = parsed_output.get('qualified_name', None)
955
- guid = parsed_output.get('guid', None)
956
- valid = parsed_output['valid']
957
- exists = parsed_output['exists']
795
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
958
796
 
959
797
  print(Markdown(parsed_output['display']))
960
798
 
961
- if directive == "display":
962
-
963
- return None
964
- elif directive == "validate":
965
- if valid:
966
- print(Markdown(f"==> Validation of {command} completed successfully!\n"))
967
- else:
968
- msg = f"Validation failed for object_action `{command}`\n"
969
- logger.error(msg)
970
- return valid
971
-
972
- elif directive == "process":
973
- logger.debug(json.dumps(parsed_output, indent=4))
974
-
975
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
976
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
977
- effective_time = attributes.get('Effective Time', {}).get('value', None)
978
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
979
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
980
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
981
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', None)
982
- # parent_id = attributes.get('Parent ID', {}).get('value', None)
983
- # parent_guid = attributes['Parent ID'].get('guid', None)
984
- # parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
985
- # parent_relationship_properties = attributes.get('Parent Relationship Properties',{}).get('value', None)
986
- # parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
987
-
988
- namespace = attributes.get('Namespace', {}).get('value', None)
989
- description = attributes.get('Description', {}).get('value', None)
990
- version_id = attributes.get('Version Identifier', {}).get('value', None)
991
- aliases = attributes.get('Aliases', {}).get('value', None)
992
- name_patterns = attributes.get('Name Patterns', {}).get('value', None)
993
- is_nullable = attributes.get('Is Nullable', {}).get('value', None)
994
- default_value = attributes.get('Default Value', {}).get('value', None)
995
- data_type = attributes.get('Data Type', {}).get('value', None)
996
- min_length = attributes.get('Minimum Length', {}).get('value', None)
997
- length = attributes.get('Length', {}).get('value', None)
998
- precision = attributes.get('Precision', {}).get('value', None)
999
- ordered_values = attributes.get('Ordered Values', {}).get('value', None)
1000
- sort_order = attributes.get('Sort Order', {}).get('value', None)
1001
- additional_properties = attributes.get('Additional Properties', {}).get('value', None)
1002
- effective_from = attributes.get('Effective From', {}).get('value', None)
1003
- effective_to = attributes.get('Effective To', {}).get('value', None)
1004
-
1005
- glossary_term = attributes['Glossary Term'].get('value', None)
1006
- glossary_term_guid = attributes['Glossary Term'].get('guid', None)
1007
-
1008
- merge_update = attributes.get('Merge Update', {}).get('value', None)
1009
-
1010
- position = attributes.get('Position', {}).get('value', None)
1011
- min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
1012
- max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
1013
-
1014
- in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
1015
- data_structure_guid_list = attributes.get('In Data Structure', {}).get('guid_list', None)
1016
- in_data_structure_names = attributes.get('In Data Structure Names', {}).get('name_list', None)
1017
-
1018
- data_class = attributes.get('Data Class', {}).get('value', None)
1019
- data_class_guid = attributes.get('Data Class', {}).get('guid', None)
1020
-
1021
- glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
1022
- if glossary_term_guid:
1023
- glossary_term_guid = [glossary_term_guid]
1024
-
1025
- glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
1026
-
1027
- # name_details_list = attributes.get("dict_list", None)
1028
-
1029
- in_data_spec = attributes.get("In Data Specification", {}).get("value", None) # this is a [dict]
1030
- data_spec_name_list = attributes.get("In Data Specification", {}).get("name_list", None)
1031
- data_spec_guid_list = attributes.get("In Data Specification", {}).get("guid_list", None)
1032
-
1033
- in_data_dictionary = attributes.get('In Data Dictionary', {}).get('value', None)
1034
- in_data_dictionary_names = attributes.get('In Data Dictionary', {}).get('name_list', None)
1035
- data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
1036
-
1037
- parent_data_field = attributes.get('Parent Data Field', {}).get('value', None)
1038
- parent_data_field_guids = attributes.get('Parent Data Field', {}).get('guid_list', None)
1039
- parent_data_field_names = attributes.get('Parent Data Field', {}).get('name_list', None)
1040
-
1041
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
1042
-
1043
- replace_all_props = not merge_update
1044
-
1045
- if not valid:
1046
- if exists and object_action == "Create":
1047
- msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
1048
- f"processed output\n\n___")
1049
- logger.error(msg)
1050
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1051
- else:
1052
- msg = f"Invalid specification - please review\n\n___"
1053
- logger.error(msg)
1054
- return None
1055
- else:
1056
- print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1057
-
1058
- try:
1059
- if object_action == "Update":
1060
- if not exists:
1061
- logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
1062
- f"object_action\n\n___")
1063
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1064
-
1065
- # first update the base data field
1066
- body = {
1067
- "class": "UpdateElementRequestBody", "externalSourceGUID": external_source_guid,
1068
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
1069
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
1070
- "class": "DataFieldProperties", "qualifiedName": qualified_name, "displayName": display_name,
1071
- "namespace": namespace, "description": description, "versionIdentifier": version_id,
1072
- "aliases": aliases, "namePatterns": name_patterns, "isDeprecated": False,
1073
- "isNullable": is_nullable, "defaultValue": default_value, "dataType": data_type,
1074
- "minimumLength": min_length, "length": length, "precision": precision,
1075
- "orderedValues": ordered_values, "sortOrder": sort_order,
1076
- "additionalProperties": additional_properties, "effectiveFrom": effective_from,
1077
- "effectiveTo": effective_to
1078
- }
1079
- }
1080
-
1081
- egeria_client.update_data_field(guid, body, not merge_update)
1082
- logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}")
1083
- # Update data dictionary membership
1084
- update_element_dictionary(qualified_name, {
1085
- 'guid': guid, 'display_name': display_name
1086
- })
1087
- core_props = egeria_client.find_data_fields(qualified_name,
1088
- output_format='MD') ## update back to by_guid?
1089
-
1090
- # existing_data_field = egeria_client.get_data_field_by_guid(guid, output_format='JSON')
1091
-
1092
- # Sync membership in data dictionaries
1093
- update_data_collection_memberships(egeria_client, object_type, data_dict_guid_list, "DataDictionary",
1094
- guid, display_name, replace_all_props)
1095
- logger.success(f"Updating data dictionaries `{in_data_dictionary_names}`")
1096
- core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
1097
-
1098
- # Sync data field related elements (data structure, parent data fields, terms, data classes
1099
- sync_data_field_rel_elements(egeria_client, data_structure_guid_list, parent_data_field_guids,
1100
- glossary_term_guid, data_class_guid, guid, display_name, replace_all_props)
1101
- core_props += f"\n\n## In Data Structure {in_data_structure_names}\n\n"
1102
- core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
1103
- core_props += f"\n\n## Parent Data Field\n\n{parent_data_field_names}\n\n"
1104
- core_props += f"\n\n## Data Class\n\n{data_class}\n\n"
1105
- core_props += "\n_______________________________________________________________________________\n\n"
1106
-
1107
- # Update data classes
1108
- logger.success(f"Updated Element `{display_name}`\n\n___")
1109
- return core_props
1110
-
1111
- elif object_action == "Create":
1112
- if valid is False and exists:
1113
- logger.error(
1114
- f"\nData Field `{display_name}` already exists and result document updated changing `Create` "
1115
- f"to `Update` in processed output\n\n___")
1116
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1117
- else:
1118
- # First lets create the data field
1119
- body = {
1120
- "class": "NewElementRequestBody", "properties": {
1121
- "class": "DataFieldProperties", "qualifiedName": qualified_name,
1122
- "displayName": display_name, "namespace": namespace, "description": description,
1123
- "versionIdentifier": version_id, "aliases": aliases, "namePatterns": name_patterns,
1124
- "isDeprecated": False, "isNullable": is_nullable, "defaultValue": default_value,
1125
- "dataType": data_type, "minimumLength": min_length, "length": length,
1126
- "precision": precision, "orderedValues": ordered_values, "sortOrder": sort_order,
1127
- "additionalProperties": additional_properties
1128
- }
1129
- }
1130
- guid = egeria_client.create_data_field(body)
1131
- if guid:
1132
- # Now update our element dictionary with the new information
1133
- update_element_dictionary(qualified_name, {
1134
- 'guid': guid, 'display_name': display_name
1135
- })
1136
- # Start assembling the information we will present back out
1137
- core_props = egeria_client.get_data_field_by_guid(guid, None, 'MD')
1138
-
1139
- # Add the field to any data dictionaries
1140
- if in_data_dictionary:
1141
- logger.info(f"Will add to data dictionary `{in_data_dictionary}`")
1142
- add_member_to_collections(egeria_client, data_dict_guid_list, display_name, guid)
1143
- core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
1144
-
1145
- # Add the field to any data structures
1146
- if in_data_structure:
1147
- core_props += f"\n\n## In Data Structure\n\n{in_data_structure_names}\n\n"
1148
- for ds_guid in data_structure_guid_list:
1149
- # todo This is too naive? - need to better accommodate the relationship
1150
- df_body = {
1151
- "class": "RelationshipRequestBody", "properties": {
1152
- "class": "MemberDataFieldProperties", "dataFieldPosition": position,
1153
- "minCardinality": min_cardinality, "maxCardinality": max_cardinality,
1154
- }
1155
- }
1156
-
1157
- msg = f"Adding field to structure {ds_guid}"
1158
- logger.info(msg)
1159
- egeria_client.link_member_data_field(ds_guid, guid, df_body)
1160
- core_props += f"\n\n## In Data Structure {in_data_structure_names}\n\n"
1161
-
1162
- if glossary_term:
1163
- if glossary_term_guid:
1164
- glossary_body = {
1165
- "class": "RelationshipRequestBody", "externalSourceGUID": external_source_guid,
1166
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
1167
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
1168
- }
1169
- core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
1170
- egeria_client.link_semantic_definition(guid, glossary_term_guid, glossary_body)
1171
-
1172
- if parent_data_field_guids:
1173
- # parent_df_body = {
1174
- # "class": "MetadataSourceRequestBody", "externalSourceGUID": external_source_guid,
1175
- # "externalSourceName": external_source_name, "effectiveTime": effective_time,
1176
- # "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
1177
- # }
1178
-
1179
- # egeria_client.link_nested_data_field(parent_data_field_guid, guid, parent_df_body)
1180
- for parent_guid in parent_data_field_guids:
1181
- egeria_client.link_nested_data_field(parent_guid, guid)
1182
- core_props += f"\n\n## Parent Data Field\n\n{parent_data_field_names}\n\n"
1183
-
1184
- # Link data class
1185
- if data_class:
1186
- body = {
1187
- "class": "RelationshipRequestBody", "externalSourceGUID": external_source_guid,
1188
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
1189
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
1190
- }
1191
- egeria_client.link_data_class_definition(guid, data_class_guid, body)
1192
- msg = f"Adding data class `{data_class}` to data field {display_name}"
1193
- logger.info(msg)
1194
-
1195
- logger.success(f"Created Element `{display_name}` with guid `{guid}`")
1196
- logger.success("=====================================================\n\n")
1197
- core_props += "\n___\n\n"
1198
- return core_props
1199
-
1200
- else:
1201
- logger.error(f"Failed to create Term `{display_name}`\n\n___")
1202
- return None
1203
-
1204
- except Exception as e:
1205
- logger.error(f"Error performing {command}: {e}\n\n___")
1206
- return None
1207
- else:
1208
- return None
1209
-
1210
-
1211
- @logger.catch
1212
- def process_data_class_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
1213
- """
1214
- Processes a data class create or update object_action by extracting key attributes such as
1215
- spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
1216
-
1217
- :param txt: A string representing the input cell to be processed for
1218
- extracting glossary-related attributes.
1219
- :param directive: an optional string indicating the directive to be used - display, validate or execute
1220
- :return: A string summarizing the outcome of the processing.
1221
- """
1222
-
1223
- command, object_type, object_action = extract_command_plus(txt)
1224
-
1225
- parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
799
+ logger.debug(json.dumps(parsed_output, indent=4))
1226
800
 
1227
801
  attributes = parsed_output['attributes']
1228
- display_name = attributes['Display Name'].get('value', None)
1229
- qualified_name = parsed_output.get('qualified_name', None)
1230
- guid = parsed_output.get('guid', None)
802
+ agreement = attributes.get('Agreement Name',{}).get('value', None)
803
+ agreement_guid = attributes.get('Definition 1', {}).get('guid', None)
804
+ item = attributes.get('Item Name',{}).get('value', None)
805
+ item_guid = attributes.get('Definition 2', {}).get('guid', None)
806
+ label = attributes.get('Link Label', {}).get('value', None)
807
+ description = attributes.get('Description', {}).get('value', None)
808
+
1231
809
  valid = parsed_output['valid']
1232
- exists = parsed_output['exists']
810
+ exists = agreement_guid is not None and item_guid is not None
1233
811
 
1234
- print(Markdown(parsed_output['display']))
1235
812
 
1236
813
  if directive == "display":
1237
814
 
@@ -1241,225 +818,78 @@ def process_data_class_upsert_command(egeria_client: EgeriaTech, txt: str, direc
1241
818
  print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1242
819
  else:
1243
820
  msg = f"Validation failed for object_action `{command}`\n"
1244
- logger.error(msg)
1245
821
  return valid
1246
822
 
1247
823
  elif directive == "process":
1248
- logger.debug(json.dumps(parsed_output, indent=4))
1249
-
1250
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
1251
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
1252
- effective_time = attributes.get('Effective Time', {}).get('value', None)
1253
- for_lineage = attributes.get('For Lineage', {}).get('value', False)
1254
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', False)
1255
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
1256
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', None)
1257
- # parent_id = attributes.get('Parent ID', {}).get('value', None)
1258
- # parent_guid = attributes['Parent ID'].get('guid', None)
1259
- # parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
1260
- # parent_relationship_properties = attributes.get('Parent Relationship Properties',{}).get('value', None)
1261
- # parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
1262
-
1263
- namespace = attributes.get('Namespace', {}).get('value', None)
1264
- description = attributes.get('Description', {}).get('value', None)
1265
- version_id = attributes.get('Version Identifier', {}).get('value', None)
1266
-
1267
- ###############
1268
- match_property_names = attributes.get('Match Property Names', {}).get('value', [])
1269
- specification_details = attributes.get('Specification Details', {}).get('value', {})
1270
- match_threshold = attributes.get('Match Threshold', {}).get('value', 0)
1271
- specification = attributes.get('Specification', {}).get('value', None)
1272
- data_type = attributes.get('Data Type', {}).get('value', None)
1273
- is_nullable = attributes.get('Is Nullable', {}).get('value', True)
1274
- allow_duplicates = attributes.get('Allow Duplicates', {}).get('value', True)
1275
- default_value = attributes.get('Default Value', {}).get('value', None)
1276
- average_value = attributes.get('Average Value', {}).get('value', None)
1277
- value_list = attributes.get('Value List', {}).get('value', None)
1278
- value_range_from = attributes.get('Value Range From', {}).get('value', None)
1279
- value_range_to = attributes.get('Value Range To', {}).get('value', None)
1280
- sample_values = attributes.get('Sample Values', {}).get('value', [])
1281
- data_patterns = attributes.get('Data Patterns', {}).get('value', [])
1282
- additional_properties = attributes.get('Additional Properties', {}).get('value', {})
1283
-
1284
- ###############
1285
- aliases = attributes.get('Aliases', {}).get('value', None)
1286
- name_patterns = attributes.get('Name Patterns', {}).get('value', None)
1287
-
1288
- min_length = attributes.get('Minimum Length', {}).get('value', None)
1289
- length = attributes.get('Length', {}).get('value', None)
1290
- precision = attributes.get('Precision', {}).get('value', None)
1291
- ordered_values = attributes.get('Ordered Values', {}).get('value', None)
1292
- sort_order = attributes.get('Sort Order', {}).get('value', None)
1293
- effective_from = attributes.get('Effective From', {}).get('value', None)
1294
- effective_to = attributes.get('Effective To', {}).get('value', None)
1295
-
1296
- glossary_term = attributes.get('Glossary Term', {}).get('value', None)
1297
- glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
1298
-
1299
- merge_update = attributes.get('Merge Update', {}).get('value', True)
1300
-
1301
- position = attributes.get('Position', {}).get('value', None)
1302
- min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
1303
- max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
1304
-
1305
- in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
1306
- data_structure_guid_list = attributes.get('In Data Structure', {}).get('guid_list', None)
1307
- in_data_structure_names = attributes.get('In Data Structure Names', {}).get('name_list', None)
1308
-
1309
- data_class = attributes.get('Data Class', {}).get('value', None)
1310
- glossary_term = attributes.get('Glossary Term', {}).get('value', None)
1311
-
1312
- glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
1313
-
1314
- in_data_dictionary = attributes.get('In Data Dictionary', {}).get('value', None)
1315
- in_data_dictionary_names = attributes.get('In Data Dictionary', {}).get('name_list', None)
1316
- data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
1317
-
1318
- containing_data_class = attributes.get('Containing Data Class', {}).get('value', None)
1319
- containing_data_class_guids = attributes.get('Containing Data Class', {}).get('guid_list', None)
1320
- containing_data_class_names = attributes.get('Containing Data Class', {}).get('name_list', None)
1321
-
1322
- specializes_data_class = attributes.get('Specializes Data Class', {}).get('value', None)
1323
- specializes_data_class_guid = attributes.get('Specializes Data Class', {}).get('guid', None)
1324
- specializes_data_class_name = attributes.get('Specializes Data Class', {}).get('name', None)
1325
-
1326
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
1327
-
1328
- replace_all_props = not merge_update
1329
-
1330
- if not valid:
1331
- if exists and object_action == "Create":
1332
- msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
1333
- f"processed output\n\n___")
1334
- logger.error(msg)
1335
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1336
- else:
1337
- msg = f"Invalid specification - please review\n\n___"
1338
- return None
1339
- else:
1340
- print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
824
+ gov_peer_relationship_type = object_type[:-1].replace(" ","") + "Link"
1341
825
 
1342
826
  try:
1343
- if object_action == "Update":
827
+ if object_action == "Detach":
1344
828
  if not exists:
1345
- logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
1346
- f"object_action\n\n___")
1347
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1348
-
1349
- # first update the base data class
1350
- body = {
1351
- "class": "UpdateElementRequestBody", "externalSourceGUID": external_source_guid,
1352
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
1353
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
1354
- "class": "DataClassProperties", "qualifiedName": qualified_name, "displayName": display_name,
1355
- "description": description, "namespace": namespace, "matchPropertyNames": match_property_names,
1356
- "matchThreshold": match_threshold, "specification": specification,
1357
- "specificationDetails": specification_details, "dataType": data_type,
1358
- "allowsDuplicateValues": allow_duplicates, "isNullable": is_nullable,
1359
- "defaultValue": default_value, "averageValue": average_value, "valueList": value_list,
1360
- "valueRangeFrom": value_range_from, "valueRangeTo": value_range_to,
1361
- "sampleValues": sample_values, "dataPatterns": data_patterns,
1362
- "additionalProperties": additional_properties
1363
- }
1364
- }
829
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
830
+ f"object_action\n")
831
+ logger.error(msg)
832
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
833
+ return out
834
+ elif not valid:
835
+ return None
836
+ else:
837
+ print(Markdown(
838
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
839
+ body = set_metadata_source_request_body(object_type, attributes)
1365
840
 
1366
- egeria_client.update_data_class(guid, body, not merge_update)
1367
- logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}")
1368
- # Update data dictionary membership
1369
- update_element_dictionary(qualified_name, {
1370
- 'guid': guid, 'display_name': display_name
1371
- })
1372
- core_props = egeria_client.get_data_class_by_guid(guid, None, 'MD')
841
+ egeria_client.detach_agreement_item(agreement_guid, item_guid,body)
1373
842
 
1374
- # Sync membership in data dictionaries
1375
- update_data_collection_memberships(egeria_client, object_type, data_dict_guid_list, "DataDictionary",
1376
- guid, display_name, replace_all_props)
1377
- logger.success(f"Updating data dictionaries `{in_data_dictionary_names}`")
1378
- core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
843
+ logger.success(f"===> Detached agreement item `{item}` from agreement `{agreement}`\n")
844
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1379
845
 
1380
- # Sync data field related elements (data structure, parent data fields, terms, data classes
1381
- sync_data_class_rel_elements(egeria_client, containing_data_class_guids, glossary_term_guid,
1382
- specializes_data_class_guid, guid, display_name, replace_all_props)
846
+ return (out)
1383
847
 
1384
- core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
1385
- core_props += f"\n\n## Containing Data Class\n\n{containing_data_class_names}\n\n"
1386
- core_props += "\n___\n\n"
848
+ elif object_action == "Link":
849
+ if valid is False and exists:
850
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
851
+ f"`Link` to `Detach` in processed output\n")
852
+ logger.error(msg)
1387
853
 
1388
- # Update data classes
1389
- logger.success(f"Updated Element `{display_name}`\n\n___")
1390
- return core_props
854
+ elif valid is False:
855
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
856
+ logger.error(msg)
857
+ return
1391
858
 
1392
- elif object_action == "Create":
1393
- if valid is False and exists:
1394
- logger.error(
1395
- f"\nData Class `{display_name}` already exists and result document updated changing `Create` "
1396
- f"to `Update` in processed output\n\n___")
1397
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
1398
859
  else:
1399
- # First lets create the data class
1400
- body = {
1401
- "class": "NewElementRequestBody", "properties": {
1402
- "class": "DataClassProperties", "qualifiedName": qualified_name,
1403
- "displayName": display_name, "description": description, "namespace": namespace,
1404
- "matchPropertyNames": match_property_names, "matchThreshold": match_threshold,
1405
- "specification": specification, "specificationDetails": specification_details,
1406
- "dataType": data_type, "allowsDuplicateValues": allow_duplicates, "isNullable": is_nullable,
1407
- "defaultValue": default_value, "averageValue": average_value, "valueList": value_list,
1408
- "valueRangeFrom": value_range_from, "valueRangeTo": value_range_to,
1409
- "sampleValues": sample_values, "dataPatterns": data_patterns,
1410
- "additionalProperties": additional_properties
1411
- }
1412
- }
1413
- guid = egeria_client.create_data_class(body)
1414
- if guid:
1415
- # Now update our element dictionary with the new information
1416
- update_element_dictionary(qualified_name, {
1417
- 'guid': guid, 'display_name': display_name
1418
- })
1419
- # Start assembling the information we will present back out
1420
- core_props = egeria_client.get_data_class_by_guid(guid, None, 'MD')
1421
-
1422
- # Add the field to any data dictionaries
1423
- if in_data_dictionary:
1424
- logger.info(f"Will add to data dictionary `{in_data_dictionary}`")
1425
- add_member_to_collections(egeria_client, data_dict_guid_list, display_name, guid)
1426
- core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
1427
-
1428
- if glossary_term:
1429
- if glossary_term_guid:
1430
- glossary_body = {
1431
- "class": "RelationshipRequestBody", "externalSourceGUID": external_source_guid,
1432
- "externalSourceName": external_source_name, "effectiveTime": effective_time,
1433
- "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
1434
- }
1435
-
1436
- core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
1437
- egeria_client.link_semantic_definition(guid, glossary_term_guid, glossary_body)
1438
-
1439
- if containing_data_class_guids:
1440
- for dc_guid in containing_data_class_guids:
1441
- egeria_client.link_nested_data_class(dc_guid, guid)
1442
- core_props += f"\n\n## Parent Data Field\n\n{containing_data_class_names}\n\n"
1443
-
1444
- if specializes_data_class_guid:
1445
- egeria_client.link_specialist_data_class(specializes_data_class_guid, guid)
1446
- core_props += f"\n\n## Specialized Data Field\n\n{specializes_data_class_name}\n\n"
1447
-
1448
- logger.success(f"Created Element `{display_name}`")
1449
- core_props += "\n___\n\n"
1450
- return core_props
860
+ body = set_rel_request_body(object_type, attributes)
861
+ item_props = {
862
+ "class": "AgreementItemProperties",
863
+ "agreementItemId": attributes["Agreement Item Id"],
864
+ "agreementStart": attributes["Agreement Start"],
865
+ "agreementEnd": attributes["Agreement End"],
866
+ "restrictions": attributes["Restrictions"],
867
+ "obligations": attributes["Obligations"],
868
+ "entitlements": attributes["Entitlements"],
869
+ "usageMeasurements": attributes["Usage Measurements"],
870
+ "effectiveFrom": attributes["Effective From"],
871
+ "effectiveTo": attributes["Effective To"]
872
+
873
+ }
874
+ egeria_client.link_agreement_item(agreement_guid,
875
+ item_guid, body)
876
+ msg = f"==>Linked {object_type} `{agreement} to item {item}\n"
877
+ logger.success(msg)
878
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
879
+ return out
1451
880
 
1452
- else:
1453
- logger.error(f"Failed to create Term `{display_name}`\n\n___")
1454
- return None
1455
881
 
1456
882
  except Exception as e:
1457
- logger.error(f"Error performing {command}: {e}\n\n___")
883
+ logger.error(f"Error performing {command}: {e}")
1458
884
  return None
1459
885
  else:
1460
886
  return None
1461
887
 
1462
888
 
889
+
890
+ #
891
+ # View commands
892
+ #
1463
893
  @logger.catch
1464
894
  def process_data_collection_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
1465
895
  str]:
@@ -1473,6 +903,7 @@ def process_data_collection_list_command(egeria_client: EgeriaTech, txt: str, di
1473
903
  :return: A string summarizing the outcome of the processing.
1474
904
  """
1475
905
  command, object_type, object_action = extract_command_plus(txt)
906
+ print(Markdown(f"# {command}\n"))
1476
907
  if object_type in ["Data Dictionary", "Data Dictionaries", "DataDict", "DataDictionary"]:
1477
908
  col_type = "DataDictionary"
1478
909
  elif object_type in ["Data Specification", "Data Specifications", "Data Specs"]:
@@ -1546,8 +977,8 @@ def process_data_collection_list_command(egeria_client: EgeriaTech, txt: str, di
1546
977
  else:
1547
978
  return None
1548
979
 
1549
-
1550
- def process_data_structure_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
980
+ # TODO
981
+ def process_data_agreement_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
1551
982
  str]:
1552
983
  """
1553
984
  Processes a Data Dictionary list object_action by extracting key attributes such as
@@ -1559,6 +990,7 @@ def process_data_structure_list_command(egeria_client: EgeriaTech, txt: str, dir
1559
990
  :return: A string summarizing the outcome of the processing.
1560
991
  """
1561
992
  command, object_type, object_action = extract_command_plus(txt)
993
+ print(Markdown(f"# {command}\n"))
1562
994
 
1563
995
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1564
996
 
@@ -1608,8 +1040,8 @@ def process_data_structure_list_command(egeria_client: EgeriaTech, txt: str, dir
1608
1040
  else:
1609
1041
  return None
1610
1042
 
1611
-
1612
- def process_data_field_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
1043
+ # TODO
1044
+ def process_subscription_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
1613
1045
  """
1614
1046
  Processes a Data Dictionary list object_action by extracting key attributes such as
1615
1047
  search string from the given text.
@@ -1620,6 +1052,7 @@ def process_data_field_list_command(egeria_client: EgeriaTech, txt: str, directi
1620
1052
  :return: A string summarizing the outcome of the processing.
1621
1053
  """
1622
1054
  command, object_type, object_action = extract_command_plus(txt)
1055
+ print(Markdown(f"# {command}\n"))
1623
1056
 
1624
1057
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1625
1058
 
@@ -1684,8 +1117,8 @@ def process_data_field_list_command(egeria_client: EgeriaTech, txt: str, directi
1684
1117
  else:
1685
1118
  return None
1686
1119
 
1687
-
1688
- def process_data_class_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
1120
+ # TODO
1121
+ def process_digital_product_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
1689
1122
  """
1690
1123
  Processes a Data Dictionary list object_action by extracting key attributes such as
1691
1124
  search string from the given text.
@@ -1696,6 +1129,7 @@ def process_data_class_list_command(egeria_client: EgeriaTech, txt: str, directi
1696
1129
  :return: A string summarizing the outcome of the processing.
1697
1130
  """
1698
1131
  command, object_type, object_action = extract_command_plus(txt)
1132
+ print(Markdown(f"# {command}\n"))
1699
1133
 
1700
1134
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1701
1135