pyegeria 5.4.0.24__py3-none-any.whl → 5.4.0.25__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. commands/cat/debug_log +7373 -1452
  2. commands/cat/debug_log.2025-08-17_11-34-27_981852.zip +0 -0
  3. commands/cat/dr_egeria_md.py +21 -4
  4. commands/cat/logs/pyegeria.log +4 -0
  5. md_processing/.DS_Store +0 -0
  6. md_processing/__init__.py +7 -3
  7. md_processing/data/commands.json +1683 -2801
  8. md_processing/dr_egeria_inbox/product.md +69 -20
  9. md_processing/dr_egeria_outbox/.obsidian/workspace.json +5 -5
  10. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +426 -0
  11. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +212 -0
  12. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +201 -0
  13. md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +209 -0
  14. md_processing/md_commands/governance_officer_commands.py +1 -73
  15. md_processing/md_commands/product_manager_commands.py +453 -211
  16. md_processing/md_processing_utils/common_md_proc_utils.py +60 -5
  17. md_processing/md_processing_utils/common_md_utils.py +21 -9
  18. md_processing/md_processing_utils/extraction_utils.py +2 -2
  19. md_processing/md_processing_utils/md_processing_constants.py +8 -7
  20. pyegeria/.DS_Store +0 -0
  21. pyegeria/_client_new.py +58 -10
  22. pyegeria/_output_formats.py +25 -0
  23. pyegeria/collection_manager.py +79 -14
  24. pyegeria/{data_designer_omvs.py → data_designer.py} +1171 -1675
  25. pyegeria/glossary_browser.py +1259 -0
  26. pyegeria/{glossary_manager_omvs.py → glossary_manager.py} +1181 -1099
  27. pyegeria/models.py +9 -3
  28. pyegeria/output_formatter.py +2 -1
  29. pyegeria/project_manager.py +1952 -0
  30. pyegeria/utils.py +4 -1
  31. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.25.dist-info}/METADATA +1 -1
  32. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.25.dist-info}/RECORD +35 -34
  33. md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  34. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +0 -2744
  35. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +0 -62
  36. md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +0 -444
  37. md_processing/dr_egeria_outbox/monday/processed-2025-08-17 21:04-product.md +0 -97
  38. pyegeria/glossary_browser_omvs.py +0 -3840
  39. pyegeria/governance_officer_omvs.py +0 -2367
  40. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.25.dist-info}/LICENSE +0 -0
  41. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.25.dist-info}/WHEEL +0 -0
  42. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.25.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ from md_processing.md_processing_utils.common_md_utils import update_element_dic
18
18
 
19
19
  from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
20
20
  from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
21
- from pyegeria import DEBUG_LEVEL, body_slimmer, to_pascal_case, PyegeriaException
21
+ from pyegeria import DEBUG_LEVEL, body_slimmer, to_pascal_case, PyegeriaException, print_basic_exception, print_exception_table
22
22
  from pyegeria.egeria_tech_client import EgeriaTech
23
23
 
24
24
  GERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
@@ -443,37 +443,7 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
443
443
  attributes = parsed_output['attributes']
444
444
 
445
445
  display_name = attributes['Display Name'].get('value', None)
446
- # description = attributes.get('Description',{}).get('value', None)
447
- # user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
448
- #
449
- # collection_classification = attributes.get('Collection Classification', {}).get('value', None)
450
-
451
- # current_version = attributes.get('Version Identifier',{}).get('value', None)
452
-
453
- # status = attributes.get('Status',{}).get('value', "ACTIVE")
454
-
455
- # anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
456
- # parent_guid = attributes.get('Parent ID', {}).get('guid', None)
457
- # parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
458
- # parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
459
- # parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
460
- # anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
461
- # is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
462
- # if parent_guid is None:
463
- # is_own_anchor = True
464
-
465
-
466
- # additional_prop = attributes.get('Additional Properties', {}).get('value', None)
467
- # additional_properties = json.loads(additional_prop) if additional_prop is not None else None
468
- # extended_prop = attributes.get('Extended Properties', {}).get('value', None)
469
- # extended_properties = json.loads(extended_prop) if extended_prop is not None else None
470
- # external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
471
- # external_source_name = attributes.get('External Source Name', {}).get('value', None)
472
- # effective_time = attributes.get('Effective Time', {}).get('value', None)
473
- # for_lineage = attributes.get('For Lineage', {}).get('value', None)
474
- # for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
475
-
476
- # replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
446
+ status = attributes.get('Status', {}).get('value', None)
477
447
 
478
448
  if directive == "display":
479
449
 
@@ -487,6 +457,11 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
487
457
 
488
458
  elif directive == "process":
489
459
  try:
460
+ if object_type in ["Root Collection", "Folder"]:
461
+ obj = "Collection"
462
+ else:
463
+ obj = object_type
464
+
490
465
  if object_action == "Update":
491
466
  if not exists:
492
467
  msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
@@ -498,19 +473,20 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
498
473
  else:
499
474
  print(Markdown(
500
475
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
501
- prop_body = set_prop_body(object_type,qualified_name,attributes)
476
+ prop_body = set_prop_body(obj,qualified_name,attributes)
502
477
 
503
- body = set_update_body(object_type, attributes)
504
- body['properties'] = set_prop_body(object_type,qualified_name,attributes)
478
+ body = set_update_body(obj, attributes)
479
+ body['properties'] = set_prop_body(obj,qualified_name,attributes)
505
480
 
506
- egeria_client.update_collection_w_body(guid, body)
507
- # egeria_client.update_collection_status(guid, status)
481
+ egeria_client.update_collection(guid, body)
482
+ if status:
483
+ egeria_client.update_collection_status(guid, status)
508
484
 
509
485
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
510
486
  update_element_dictionary(qualified_name, {
511
487
  'guid': guid, 'display_name': display_name
512
488
  })
513
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
489
+ return egeria_client.get_collection_by_guid(guid, element_type='Data Specification',
514
490
  output_format='MD')
515
491
 
516
492
 
@@ -525,19 +501,18 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
525
501
  body = set_create_body(object_type,attributes)
526
502
 
527
503
  # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
528
- body["initialClassifications"] = set_collections_classifications(object_type, attributes)
529
- body["properties"] = set_prop_body(object_type, qualified_name,attributes)
504
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes, ["Folder", "Root Collection"])
505
+ body["properties"] = set_prop_body(obj, qualified_name,attributes)
530
506
 
531
507
 
532
- guid = egeria_client.create_collection_w_body(body)
508
+ guid = egeria_client.create_collection(body = body)
533
509
  if guid:
534
510
  update_element_dictionary(qualified_name, {
535
511
  'guid': guid, 'display_name': display_name
536
512
  })
537
513
  msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
538
514
  logger.success(msg)
539
- return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
540
- output_format='MD')
515
+ return egeria_client.get_collection_by_guid(guid, obj, output_format='MD')
541
516
  else:
542
517
  msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
543
518
  logger.error(msg)
@@ -545,6 +520,7 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
545
520
 
546
521
  except PyegeriaException as e:
547
522
  logger.error(f"Pyegeria error performing {command}: {e}")
523
+ print_basic_exception(e)
548
524
  return None
549
525
  except Exception as e:
550
526
  logger.error(f"Error performing {command}: {e}")
@@ -574,6 +550,7 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
574
550
  qualified_name = parsed_output.get('qualified_name', None)
575
551
  guid = parsed_output.get('guid', None)
576
552
 
553
+
577
554
  print(Markdown(parsed_output['display']))
578
555
 
579
556
  logger.debug(json.dumps(parsed_output, indent=4))
@@ -582,6 +559,7 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
582
559
 
583
560
  display_name = attributes['Display Name'].get('value', None)
584
561
  product_manager = attributes.get('Product Manager',{}).get('value', None)
562
+ product_status = attributes.get('Product Status',{}).get('value', None)
585
563
 
586
564
  if directive == "display":
587
565
 
@@ -607,16 +585,20 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
607
585
  print(Markdown(
608
586
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
609
587
  prop_body = set_product_body(object_type,qualified_name,attributes)
588
+ body = set_update_body(object_type, attributes)
589
+ body['properties'] = set_prop_body(object_type,qualified_name,attributes)
610
590
  # Todo: Update product manager later?
611
591
 
612
592
  egeria_client.update_digital_product(guid, body)
613
- egeria_client.update_digital_product_status(guid, product_status)
593
+ # if product_status:
594
+ # egeria_client.update_digital_product_status(guid, product_status)
595
+
614
596
 
615
597
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
616
598
  update_element_dictionary(qualified_name, {
617
599
  'guid': guid, 'display_name': display_name
618
600
  })
619
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
601
+ return egeria_client.get_collection_by_guid(guid, element_type='Digital Product',
620
602
  output_format='MD')
621
603
 
622
604
 
@@ -629,11 +611,11 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
629
611
 
630
612
  else:
631
613
  body = set_create_body(object_type, attributes)
632
- body["initialClassifications"] = set_collection_classifications(object_type, attributes)
614
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes,[])
633
615
  prop_body = set_product_body(object_type, qualified_name, attributes)
634
616
  body["properties"] = prop_body
635
617
 
636
- guid = egeria_client.create_digital_product(body)
618
+ guid = egeria_client.create_digital_product(body_slimmer(body))
637
619
  if guid:
638
620
  update_element_dictionary(qualified_name, {
639
621
  'guid': guid, 'display_name': display_name
@@ -666,11 +648,13 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
666
648
  :param directive: an optional string indicating the directive to be used - display, validate or execute
667
649
  :return: A string summarizing the outcome of the processing.
668
650
  """
669
-
670
651
  command, object_type, object_action = extract_command_plus(txt)
671
652
  print(Markdown(f"# {command}\n"))
672
653
 
673
654
  parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
655
+ if not parsed_output:
656
+ logger.error(f"No output for `{object_action}`")
657
+ return None
674
658
 
675
659
  valid = parsed_output['valid']
676
660
  exists = parsed_output['exists']
@@ -685,38 +669,7 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
685
669
  attributes = parsed_output['attributes']
686
670
 
687
671
  display_name = attributes['Display Name'].get('value', None)
688
- description = attributes.get('Description',{}).get('value', None)
689
- user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
690
- agreement_status = attributes.get('Status',{}).get('value', None)
691
- agreement_identifier = attributes.get('Agreement Identifier',{}).get('value', None)
692
-
693
- version_identifier = attributes.get('Version Identifier',{}).get('value', None)
694
-
695
- actors = attributes.get('Agreement Actors',{}).get('value', None)
696
- actor_names = attributes.get('Agreement Actors',{}).get('name_list', None)
697
- actor_guids = attributes.get('Agreement Actors',{}).get('guid_list', None)
698
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
699
- parent_guid = attributes.get('Parent ID', {}).get('guid', None)
700
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
701
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
702
- parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
703
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
704
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
705
- if parent_guid is None:
706
- is_own_anchor = True
707
-
708
-
709
- additional_prop = attributes.get('Additional Properties', {}).get('value', None)
710
- additional_properties = json.loads(additional_prop) if additional_prop is not None else None
711
- extended_prop = attributes.get('Extended Properties', {}).get('value', None)
712
- extended_properties = json.loads(extended_prop) if extended_prop is not None else None
713
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
714
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
715
- effective_time = attributes.get('Effective Time', {}).get('value', None)
716
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
717
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
718
-
719
- replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
672
+ status = attributes.get('Status', {}).get('value', None)
720
673
 
721
674
  if directive == "display":
722
675
 
@@ -730,6 +683,11 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
730
683
 
731
684
  elif directive == "process":
732
685
  try:
686
+ if object_type in ["Data Sharing Agreement"]:
687
+ obj = "Agreement"
688
+ else:
689
+ obj = object_type
690
+
733
691
  if object_action == "Update":
734
692
  if not exists:
735
693
  msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
@@ -741,32 +699,23 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
741
699
  else:
742
700
  print(Markdown(
743
701
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
744
-
745
- product_body = {
746
- "class": "AgreementProperties",
747
- "qualifiedName": qualified_name,
748
- "userDefinedStatus": user_defined_status,
749
- "name": display_name,
750
- "description": description,
751
- "identifier": agreement_identifier,
752
- "additionalProperties": additional_properties,
753
- "extendedProperties": extended_properties,
754
- }
702
+ prop_body = set_prop_body(obj, qualified_name, attributes)
755
703
 
756
704
  body = set_update_body(object_type, attributes)
757
- body['properties'] = product_body
705
+ body['properties'] = set_prop_body(object_type, qualified_name, attributes)
758
706
 
759
- egeria_client.update_agreement(guid, body, replace_all_props)
760
- status_update_body = set_element_status_request_body(object_type, attributes)
761
- egeria_client.update_agreement_status(guid, status_update_body)
707
+ egeria_client.update_agreement(guid, body)
708
+ # if status is not None and status !={}:
709
+ # egeria_client.update_agreement_status(guid, status)
762
710
 
763
711
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
764
712
  update_element_dictionary(qualified_name, {
765
713
  'guid': guid, 'display_name': display_name
766
714
  })
767
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
715
+ return egeria_client.get_collection_by_guid(guid, element_type='Data Specification',
768
716
  output_format='MD')
769
717
 
718
+
770
719
  elif object_action == "Create":
771
720
  if valid is False and exists:
772
721
  msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
@@ -775,58 +724,43 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
775
724
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
776
725
 
777
726
  else:
778
- body = {
779
- "class": "NewAgreementRequestBody",
780
- "isOwnAnchor": is_own_anchor,
781
- "parentGUID": parent_guid,
782
- "parentRelationshipTypeName": parent_relationship_type_name,
783
- "parentAtEnd1": parent_at_end1,
784
- "properties": {
785
- "class": "AgreementProperties",
786
- "qualifiedName": qualified_name,
787
- "userDefinedStatus": user_defined_status,
788
- "name": display_name,
789
- "description" : description,
790
- "identifier" : agreement_identifier,
791
- "additionalProperties": additional_properties,
792
- "extendedProperties": extended_properties,
793
- },
794
- "initialStatus": agreement_status,
795
- "externalSourceGUID": external_source_guid,
796
- "externalSourceName": external_source_name,
797
- "effectiveTime" : effective_time,
798
- "forLineage": for_lineage,
799
- "forDuplicateProcessing": for_duplicate_processing
800
- }
801
- if object_type == "Data Sharing Agreement":
802
- guid = egeria_client.create_data_sharing_agreement(body)
803
- elif object_type == "Agreement":
804
- guid = egeria_client.create_agreement(body)
727
+ body = set_create_body(object_type, attributes)
728
+
729
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
730
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes,
731
+ ["Data Sharing Agreement"])
732
+ body["properties"] = set_prop_body(obj, qualified_name, attributes)
805
733
 
734
+ guid = egeria_client.create_agreement(body=body)
806
735
  if guid:
807
736
  update_element_dictionary(qualified_name, {
808
737
  'guid': guid, 'display_name': display_name
809
738
  })
810
739
  msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
811
740
  logger.success(msg)
812
- return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
813
- output_format='MD')
741
+ return egeria_client.get_collection_by_guid(guid, obj, output_format='MD')
814
742
  else:
815
743
  msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
816
744
  logger.error(msg)
817
745
  return None
818
746
 
747
+ except PyegeriaException as e:
748
+ logger.error(f"Pyegeria error performing {command}: {e}")
749
+ print_exception_table(e)
750
+ return None
819
751
  except Exception as e:
820
752
  logger.error(f"Error performing {command}: {e}")
821
- return None
822
753
  else:
823
754
  return None
824
755
 
825
756
 
757
+
758
+
759
+
826
760
  def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
827
761
  directive: str = "display") -> Optional[str]:
828
762
  """
829
- Processes a link or unlink command to associate or break up peer governance definitions.
763
+ Processes a link or unlink command to add or remove an agreement item.
830
764
 
831
765
  :param txt: A string representing the input cell to be processed for
832
766
  extracting blueprint-related attributes.
@@ -844,9 +778,9 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
844
778
 
845
779
  attributes = parsed_output['attributes']
846
780
  agreement = attributes.get('Agreement Name',{}).get('value', None)
847
- agreement_guid = attributes.get('Definition 1', {}).get('guid', None)
781
+ agreement_guid = attributes.get('Agreement Name', {}).get('guid', None)
848
782
  item = attributes.get('Item Name',{}).get('value', None)
849
- item_guid = attributes.get('Definition 2', {}).get('guid', None)
783
+ item_guid = attributes.get('Item Name', {}).get('guid', None)
850
784
  label = attributes.get('Link Label', {}).get('value', None)
851
785
  description = attributes.get('Description', {}).get('value', None)
852
786
 
@@ -879,21 +813,8 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
879
813
  else:
880
814
  print(Markdown(
881
815
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
882
- body = set_metadata_source_request_body(object_type, attributes)
883
- item_props = {
884
- "class": "AgreementItemProperties",
885
- "agreementItemId": attributes["Agreement Item Id"],
886
- "agreementStart": attributes["Agreement Start"],
887
- "agreementEnd": attributes["Agreement End"],
888
- "restrictions": attributes["Restrictions"],
889
- "obligations": attributes["Obligations"],
890
- "entitlements": attributes["Entitlements"],
891
- "usageMeasurements": attributes["Usage Measurements"],
892
- "effectiveFrom": attributes["Effective From"],
893
- "effectiveTo": attributes["Effective To"]
894
-
895
- }
896
- body['properties'] = item_props
816
+ body = set_delete_request_body(object_type, attributes)
817
+
897
818
  egeria_client.detach_agreement_item(agreement_guid, item_guid,body)
898
819
 
899
820
  logger.success(f"===> Detached agreement item `{item}` from agreement `{agreement}`\n")
@@ -908,7 +829,7 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
908
829
  logger.error(msg)
909
830
 
910
831
  elif valid is False:
911
- msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
832
+ msg = f"==>{object_type} Link with Agreement `{agreement}` and item `{item}` is not valid and can't be created"
912
833
  logger.error(msg)
913
834
  return
914
835
 
@@ -916,15 +837,16 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
916
837
  body = set_rel_request_body(object_type, attributes)
917
838
  item_props = {
918
839
  "class": "AgreementItemProperties",
919
- "agreementItemId": attributes["Agreement Item Id"],
920
- "agreementStart": attributes["Agreement Start"],
921
- "agreementEnd": attributes["Agreement End"],
922
- "restrictions": attributes["Restrictions"],
923
- "obligations": attributes["Obligations"],
924
- "entitlements": attributes["Entitlements"],
925
- "usageMeasurements": attributes["Usage Measurements"],
926
- "effectiveFrom": attributes["Effective From"],
927
- "effectiveTo": attributes["Effective To"]
840
+ "agreementItemId": attributes.get("Agreement Item Id",{}).get("value", None),
841
+ "agreementItemTypeName": attributes.get("Agreement Item Type",{}).get("value", None),
842
+ "agreementStart": attributes.get("Agreement Start",{}).get("value", None),
843
+ "agreementEnd": attributes.get("Agreement End",{}).get("value", None),
844
+ "restrictions": attributes.get("Restrictions",{}).get("value", None),
845
+ "obligations": attributes.get("Obligations",{}).get("value", None),
846
+ "entitlements": attributes.get("Entitlements",{}).get("value", None),
847
+ "usageMeasurements": attributes.get("Usage Measurements",{}).get("value", None),
848
+ "effectiveFrom": attributes.get("Effective From",{}).get("value", None),
849
+ "effectiveTo": attributes.get("Effective To",{}).get("value", None)
928
850
 
929
851
  }
930
852
  body['properties'] = item_props
@@ -942,19 +864,230 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
942
864
  else:
943
865
  return None
944
866
 
867
+ def process_add_to_collection_command(egeria_client: EgeriaTech, txt: str,
868
+ directive: str = "display") -> Optional[str]:
869
+ """
870
+ Processes a link or unlink command to add or remove a member to/from a collection..
945
871
 
872
+ :param txt: A string representing the input cell to be processed for
873
+ extracting blueprint-related attributes.
874
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
875
+ :return: A string summarizing the outcome of the processing.
876
+ """
877
+ command, object_type, object_action = extract_command_plus(txt)
878
+ print(Markdown(f"# {command}\n"))
946
879
 
947
- #
948
- # View commands
949
- #
950
- @logger.catch
951
- def process_collection_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
880
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
881
+
882
+ print(Markdown(parsed_output['display']))
883
+
884
+ logger.debug(json.dumps(parsed_output, indent=4))
885
+
886
+ attributes = parsed_output['attributes']
887
+ element_guid = attributes.get('Element Id',{}).get('guid', None)
888
+ collection_guid = attributes.get('Collection Id', {}).get('guid', None)
889
+ membership_rationale = attributes.get('Membership Rationale',{}).get('value', None)
890
+ expression = attributes.get('Expression', {}).get('value', None)
891
+ confidence = attributes.get('Confidence', {}).get('value', None)
892
+ membership_status = attributes.get('Membership Status', {}).get('value', None)
893
+ user_defined_status = attributes.get('User Defined Status', {}).get('value', None)
894
+ steward = attributes.get('Steward', {}).get('guid', None)
895
+ steward_type_name = attributes.get('Steward Type Name', {}).get('value', None)
896
+ steward_property_name = attributes.get('Steward Property Name', {}).get('value', None)
897
+ source = attributes.get('Source', {}).get('value', None)
898
+ notes = attributes.get('Notes', {}).get('value', None)
899
+ glossary_term = attributes.get('Glossary Term', {}).get('value', None)
900
+ journal_entry = attributes.get('Journal Entry', {}).get('value', None)
901
+
902
+
903
+ valid = parsed_output['valid']
904
+ exists = agreement_guid is not None and item_guid is not None
905
+
906
+
907
+ if directive == "display":
908
+
909
+ return None
910
+ elif directive == "validate":
911
+ if valid:
912
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
913
+ else:
914
+ msg = f"Validation failed for object_action `{command}`\n"
915
+ return valid
916
+
917
+ elif directive == "process":
918
+ prop_body = {
919
+ "class" : "CollectionMembershipProperties",
920
+ "membershipRationale": membership_rationale,
921
+ "expression": expression,
922
+ "membershipStatus": membership_status,
923
+ "userDefinedStatus": user_defined_status,
924
+ "confidence": confidence,
925
+ "steward": steward,
926
+ "stewardTypeName": steward_type_name,
927
+ "stewardPropertyName": steward_property_name,
928
+ "source": source,
929
+ "notes": notes,
930
+ }
931
+ try:
932
+ if object_action == "Detach":
933
+ if not exists:
934
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
935
+ f"object_action\n")
936
+ logger.error(msg)
937
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
938
+ return out
939
+ elif not valid:
940
+ return None
941
+ else:
942
+ print(Markdown(
943
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
944
+ body = set_delete_request_body(object_type, attributes)
945
+
946
+ egeria_client.remove_from_collection(collection_guid, element_guid,body)
947
+
948
+ logger.success(f"===> Detached element `{element_guid}` from collection `{collection_guid}`\n")
949
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
950
+
951
+ return (out)
952
+
953
+ elif object_action == "Link":
954
+ if valid is False and exists:
955
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
956
+ f"`Link` to `Detach` in processed output\n")
957
+ logger.error(msg)
958
+
959
+ elif valid is False:
960
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
961
+ logger.error(msg)
962
+ return
963
+
964
+ else:
965
+ body = set_rel_request_body(object_type, attributes)
966
+
967
+ body['properties'] = prop_body
968
+ egeria_client.add_to_collection(collection_guid,
969
+ element_guid, body)
970
+ msg = f"==>Linked `{element_guid}` to collection `{collection_guid}` \n"
971
+ logger.success(msg)
972
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
973
+ return out
974
+
975
+
976
+ except Exception as e:
977
+ logger.error(f"Error performing {command}: {e}")
978
+ return None
979
+ else:
980
+ return None
981
+
982
+ def process_product_dependency_command(egeria_client: EgeriaTech, txt: str,
983
+ directive: str = "display") -> Optional[str]:
984
+ """
985
+ Processes a link or unlink command to associate or break up a dependency between digital products..
986
+
987
+ :param txt: A string representing the input cell to be processed for
988
+ extracting blueprint-related attributes.
989
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
990
+ :return: A string summarizing the outcome of the processing.
991
+ """
992
+ command, object_type, object_action = extract_command_plus(txt)
993
+ print(Markdown(f"# {command}\n"))
994
+
995
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
996
+
997
+ print(Markdown(parsed_output['display']))
998
+
999
+ logger.debug(json.dumps(parsed_output, indent=4))
1000
+
1001
+ attributes = parsed_output['attributes']
1002
+ digital_product1_guid = attributes.get('Digital Product 1', None)
1003
+ digital_product2_guid = attributes.get('Digital Product 2', None)
1004
+ label = attributes.get('Label',{}).get('value', None)
1005
+ description = attributes.get('Description', {}).get('value', None)
1006
+ effective_from = attributes.get('Effective From', {}).get('value', None)
1007
+ effective_to = attributes.get('Effective To', {}).get('value', None)
1008
+
1009
+
1010
+ valid = parsed_output['valid']
1011
+ exists = agreement_guid is not None and item_guid is not None
1012
+
1013
+
1014
+ if directive == "display":
1015
+
1016
+ return None
1017
+ elif directive == "validate":
1018
+ if valid:
1019
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1020
+ else:
1021
+ msg = f"Validation failed for object_action `{command}`\n"
1022
+ return valid
1023
+
1024
+ elif directive == "process":
1025
+ prop_body = {
1026
+ "class" : "DigitalProductDependencyProperties",
1027
+ "label": label,
1028
+ "description": description,
1029
+ "effectiveFrom": effective_from,
1030
+ "effectiveTo": effective_to
1031
+ }
1032
+
1033
+ try:
1034
+ if object_action == "Detach":
1035
+ if not exists:
1036
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1037
+ f"object_action\n")
1038
+ logger.error(msg)
1039
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1040
+ return out
1041
+ elif not valid:
1042
+ return None
1043
+ else:
1044
+ print(Markdown(
1045
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1046
+ body = set_delete_request_body(object_type, attributes)
1047
+
1048
+ egeria_client.detach_digital_product_dependency(digital_product1_guid, digital_product2_guid,body)
1049
+
1050
+ logger.success(f"===> Detached dependency between products `{digital_product1_guid}` and `{digital_product2_guid}`\n")
1051
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1052
+
1053
+ return (out)
1054
+
1055
+ elif object_action == "Link":
1056
+ if valid is False and exists:
1057
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1058
+ f"`Link` to `Detach` in processed output\n")
1059
+ logger.error(msg)
1060
+
1061
+ elif valid is False:
1062
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
1063
+ logger.error(msg)
1064
+ return
1065
+
1066
+ else:
1067
+ body = set_rel_request_body(object_type, attributes)
1068
+
1069
+ body['properties'] = prop_body
1070
+ egeria_client.link_digital_product_dependency(digital_product1_guid,
1071
+ digital_product2_guid, body)
1072
+ msg = f"==>Linked dependency from digital product `{digital_product1_guid}` to product `{digital_product2_guid}` \n"
1073
+ logger.success(msg)
1074
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1075
+ return out
1076
+
1077
+
1078
+ except Exception as e:
1079
+ logger.error(f"Error performing {command}: {e}")
1080
+ return None
1081
+ else:
1082
+ return None
1083
+
1084
+ def process_attach_collection_command(egeria_client: EgeriaTech, txt: str,
1085
+ directive: str = "display") -> Optional[str]:
952
1086
  """
953
- Processes a Data Dictionary list object_action by extracting key attributes such as
954
- search string from the given text.
1087
+ Processes a link or unlink command to attach a collection to a resources.
955
1088
 
956
1089
  :param txt: A string representing the input cell to be processed for
957
- extracting term-related attributes.
1090
+ extracting blueprint-related attributes.
958
1091
  :param directive: an optional string indicating the directive to be used - display, validate or execute
959
1092
  :return: A string summarizing the outcome of the processing.
960
1093
  """
@@ -963,76 +1096,185 @@ def process_collection_list_command(egeria_client: EgeriaTech, txt: str, directi
963
1096
 
964
1097
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
965
1098
 
966
- col_type = to_pascal_case(object_type) if object_type != "Collections" else None
1099
+ print(Markdown(parsed_output['display']))
1100
+
1101
+ logger.debug(json.dumps(parsed_output, indent=4))
1102
+
1103
+ attributes = parsed_output['attributes']
1104
+ collection_guid = attributes.get('Collection Id', {}).get('guid', None)
1105
+ resource_guid = attributes.get('Resource Id', {}).get('guid', None)
1106
+ resource_use = attributes.get('Resource Use', {}).get('value', None)
1107
+ resource_description = attributes.get('Resource Description', {}).get('value', None)
1108
+ resource_properties = attributes.get('Resource Properties', {}).get('value', None)
1109
+ effective_from = attributes.get('Effective From', {}).get('value', None)
1110
+ effective_to = attributes.get('Effective To', {}).get('value', None)
1111
+
967
1112
 
968
1113
  valid = parsed_output['valid']
969
- print(Markdown(f"Performing {command}"))
1114
+ exists = agreement_guid is not None and item_guid is not None
1115
+
1116
+
1117
+ if directive == "display":
1118
+
1119
+ return None
1120
+ elif directive == "validate":
1121
+ if valid:
1122
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1123
+ else:
1124
+ msg = f"Validation failed for object_action `{command}`\n"
1125
+ return valid
1126
+
1127
+ elif directive == "process":
1128
+ prop_body = {
1129
+ "class" : "ResourceListProperties",
1130
+ "resourceUse": resource_use,
1131
+ "resourceDescription": resource_description,
1132
+ "resourceProperties": resource_properties,
1133
+ "effectiveFrom": effective_from,
1134
+ "effectiveTo": effective_to
1135
+ }
1136
+
1137
+ try:
1138
+ if object_action == "Detach":
1139
+ if not exists:
1140
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1141
+ f"object_action\n")
1142
+ logger.error(msg)
1143
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1144
+ return out
1145
+ elif not valid:
1146
+ return None
1147
+ else:
1148
+ print(Markdown(
1149
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1150
+ body = set_delete_request_body(object_type, attributes)
1151
+
1152
+ egeria_client.detach_collection(resource_guid, collection_guid,body)
1153
+
1154
+ logger.success(f"===> Detached linkage between resource `{resource_guid}` and collection`{collection_guid}`\n")
1155
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1156
+
1157
+ return (out)
1158
+
1159
+ elif object_action == "Link":
1160
+ if valid is False and exists:
1161
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1162
+ f"`Link` to `Detach` in processed output\n")
1163
+ logger.error(msg)
1164
+
1165
+ elif valid is False:
1166
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
1167
+ logger.error(msg)
1168
+ return
1169
+
1170
+ else:
1171
+ body = set_rel_request_body(object_type, attributes)
1172
+
1173
+ body['properties'] = prop_body
1174
+ egeria_client.attach_collection(resource_guid,
1175
+ collection_guid, body)
1176
+ msg = f"==>Attached collection `{collection_guid}` to resource `{resource_guid}` \n"
1177
+ logger.success(msg)
1178
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1179
+ return out
1180
+
1181
+
1182
+ except Exception as e:
1183
+ logger.error(f"Error performing {command}: {e}")
1184
+ return None
1185
+ else:
1186
+ return None
1187
+
1188
+ def process_attach_subscriber_command(egeria_client: EgeriaTech, txt: str,
1189
+ directive: str = "display") -> Optional[str]:
1190
+ """
1191
+ Processes a link or unlink command to attach a subscriber to a subscription.
1192
+
1193
+ :param txt: A string representing the input cell to be processed for
1194
+ extracting blueprint-related attributes.
1195
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
1196
+ :return: A string summarizing the outcome of the processing.
1197
+ """
1198
+ command, object_type, object_action = extract_command_plus(txt)
1199
+ print(Markdown(f"# {command}\n"))
1200
+
1201
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1202
+
970
1203
  print(Markdown(parsed_output['display']))
971
1204
 
972
- attr = parsed_output.get('attributes',{})
973
- columns = attr.get('Columns',{}).get('value',None).replace("'", '"')
1205
+ logger.debug(json.dumps(parsed_output, indent=4))
974
1206
 
975
- try:
976
- columns_list = json.loads(columns)
977
- except Exception as e:
978
- print(e)
979
- exit(1)
980
-
981
- effective_time = attr.get('effectiveTime', {}).get('value', None)
982
- as_of_time = attr.get('asOfTime', {}).get('value', None)
983
- for_duplicate_processing = attr.get('forDuplicateProcessing', {}).get('value', False)
984
- for_lineage = attr.get('forLineage',{}).get('value', False)
985
- limit_result_by_status = attr.get('limitResultsByStatus',{}).get('value', [])
986
- sequencing_property = attr.get('sequencingProperty',{}).get('value',"qualifiedName" )
987
- sequencing_order = attr.get('sequencingOrder',{}).get('value', "PROPERTY_ASCENDING")
988
- search_string = attr.get('Search String', {}).get('value', '*')
989
- search_string = search_string if search_string != "*" else None
990
- output_format = attr.get('Output Format', {}).get('value', 'LIST')
991
- detailed = attr.get('Detailed', {}).get('value', False)
1207
+ attributes = parsed_output['attributes']
1208
+ subscriber_guid = attributes.get('Subscriber', {}).get('guid', None)
1209
+ subscription_guid = attributes.get('Subscription', {}).get('guid', None)
1210
+
1211
+ valid = parsed_output['valid']
992
1212
 
993
1213
  if directive == "display":
1214
+
994
1215
  return None
995
1216
  elif directive == "validate":
996
1217
  if valid:
997
1218
  print(Markdown(f"==> Validation of {command} completed successfully!\n"))
998
1219
  else:
999
1220
  msg = f"Validation failed for object_action `{command}`\n"
1000
- logger.error(msg)
1001
1221
  return valid
1002
1222
 
1003
1223
  elif directive == "process":
1224
+ prop_body = {
1225
+ "class": "DigitalSubscriberProperties",
1226
+ "subscriberId": attributes.get('Subscriber Id', {}).get('value', None),
1227
+ "effectiveFrom": attributes.get('Effective From', {}).get('value', None),
1228
+ "effectiveTo": attributes.get('Effective To', {}).get('value', None),
1229
+ }
1230
+
1004
1231
  try:
1005
- if not valid: # First validate the command before we process it
1006
- msg = f"Validation failed for {object_action} `{object_type}`\n"
1007
- logger.error(msg)
1008
- return None
1009
-
1010
- list_md = f"\n# `{col_type}` with filter: `{search_string}`\n\n"
1011
- body = {
1012
- "class": "FilterRequestBody",
1013
- "asOfTime": as_of_time,
1014
- "effectiveTime": effective_time,
1015
- "forLineage": for_lineage,
1016
- "forDuplicateProcessing": for_duplicate_processing,
1017
- "limitResultsByStatus": limit_result_by_status,
1018
- "sequencingOrder": sequencing_order,
1019
- "sequencingProperty": sequencing_property,
1020
- "filter": search_string,
1021
- }
1022
-
1023
- struct = egeria_client.find_collections_w_body(body, col_type,
1024
- output_format = output_format, columns=columns_list)
1025
- if output_format == "DICT":
1026
- list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
1027
- else:
1028
- list_md += struct
1029
- logger.info(f"Wrote `{col_type}` for search string: `{search_string}`")
1232
+ if object_action == "Detach":
1233
+ if not exists:
1234
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1235
+ f"object_action\n")
1236
+ logger.error(msg)
1237
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1238
+ return out
1239
+ elif not valid:
1240
+ return None
1241
+ else:
1242
+ print(Markdown(
1243
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1244
+ body = set_delete_request_body(object_type, attributes)
1245
+
1246
+ egeria_client.detach_subscriber(subscriber_guid, subscription_guid,body)
1247
+
1248
+ logger.success(f"===> Detached linkage between subscriber `{subscriber_guid}` and subscription`{subscription_guid}`\n")
1249
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1250
+
1251
+ return (out)
1252
+
1253
+ elif object_action == "Link":
1254
+ if valid is False and exists:
1255
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1256
+ f"`Link` to `Detach` in processed output\n")
1257
+ logger.error(msg)
1258
+
1259
+ elif valid is False:
1260
+ msg = f"==>{object_type} Subscription link `{subscriber_guid}` is not valid and can't be created"
1261
+ logger.error(msg)
1262
+ return
1263
+
1264
+ else:
1265
+ body = set_rel_request_body(object_type, attributes)
1266
+
1267
+ body['properties'] = prop_body
1268
+ egeria_client.link_subscriber(subscriber_guid,
1269
+ subscription_guid, body)
1270
+ msg = f"==>Attached subscriber `{subscriber_guid}` to subscription `{subscriber_guid}` \n"
1271
+ logger.success(msg)
1272
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1273
+ return out
1030
1274
 
1031
- return list_md
1032
1275
 
1033
1276
  except Exception as e:
1034
1277
  logger.error(f"Error performing {command}: {e}")
1035
- console.print_exception(show_locals=True)
1036
1278
  return None
1037
1279
  else:
1038
1280
  return None