pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. commands/cat/debug_log +2806 -0
  2. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  3. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  4. commands/cat/dr_egeria_command_help.py +273 -0
  5. commands/cat/dr_egeria_md.py +90 -20
  6. commands/cat/glossary_actions.py +2 -2
  7. commands/cat/list_collections.py +24 -10
  8. commands/cat/list_data_designer.py +183 -0
  9. md_processing/__init__.py +28 -5
  10. md_processing/data/commands.json +31474 -1096
  11. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
  12. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
  13. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
  14. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
  15. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
  16. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  17. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  18. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  19. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  20. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
  21. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
  22. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
  23. md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
  24. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
  25. md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
  26. md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
  27. md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
  28. md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
  29. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
  30. md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
  31. md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
  32. md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
  33. md_processing/family_docs/Data Designer.md +842 -0
  34. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
  35. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
  36. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
  37. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
  38. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
  39. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
  40. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
  41. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
  42. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
  43. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
  44. md_processing/family_docs/Digital Product Manager.md +668 -0
  45. md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
  46. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
  47. md_processing/family_docs/Glossary/Create_Category.md +38 -0
  48. md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
  49. md_processing/family_docs/Glossary/Create_Term.md +70 -0
  50. md_processing/family_docs/Glossary.md +206 -0
  51. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
  52. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
  53. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
  54. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
  55. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
  56. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
  57. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
  58. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
  59. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
  60. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
  61. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
  62. md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
  63. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
  64. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
  65. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
  66. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
  67. md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
  68. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
  69. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
  70. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
  71. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
  72. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
  73. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
  74. md_processing/family_docs/Governance Officer.md +2412 -0
  75. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
  76. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
  77. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
  78. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
  79. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
  80. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
  81. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
  82. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
  83. md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
  84. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
  85. md_processing/family_docs/Solution Architect.md +490 -0
  86. md_processing/md_commands/data_designer_commands.py +1192 -710
  87. md_processing/md_commands/glossary_commands.py +19 -32
  88. md_processing/md_commands/governance_officer_commands.py +420 -0
  89. md_processing/md_commands/product_manager_commands.py +1180 -0
  90. md_processing/md_commands/project_commands.py +5 -2
  91. md_processing/md_commands/solution_architect_commands.py +1140 -0
  92. md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
  93. md_processing/md_processing_utils/common_md_utils.py +205 -6
  94. md_processing/md_processing_utils/debug_log +574 -0
  95. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
  96. md_processing/md_processing_utils/extraction_utils.py +1 -1
  97. md_processing/md_processing_utils/generate_dr_help.py +165 -0
  98. md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
  99. md_processing/md_processing_utils/generate_md_templates.py +92 -0
  100. md_processing/md_processing_utils/generated_help_terms.md +842 -0
  101. md_processing/md_processing_utils/md_processing_constants.py +94 -17
  102. pyegeria/__init__.py +1 -0
  103. pyegeria/_client.py +39 -1
  104. pyegeria/classification_manager_omvs.py +1 -1
  105. pyegeria/collection_manager_omvs.py +4667 -1178
  106. pyegeria/data_designer_omvs.py +348 -31
  107. pyegeria/egeria_tech_client.py +9 -25
  108. pyegeria/glossary_browser_omvs.py +5 -6
  109. pyegeria/glossary_manager_omvs.py +2 -2
  110. pyegeria/governance_officer_omvs.py +2367 -0
  111. pyegeria/output_formatter.py +157 -32
  112. pyegeria/solution_architect_omvs.py +5063 -1110
  113. pyegeria/utils.py +22 -2
  114. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
  115. pyegeria-5.4.0.dist-info/RECORD +243 -0
  116. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
  117. commands/cat/.DS_Store +0 -0
  118. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
  119. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
  120. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
  121. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
  122. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
  123. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
  124. md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
  125. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
  126. md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
  127. md_processing/dr_egeria_inbox/cat_test.md +0 -100
  128. md_processing/dr_egeria_inbox/data_field.md +0 -54
  129. md_processing/dr_egeria_inbox/data_spec.md +0 -77
  130. md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
  131. md_processing/dr_egeria_inbox/data_test.md +0 -86
  132. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
  133. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
  134. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
  135. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
  136. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
  137. md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
  138. md_processing/dr_egeria_inbox/rel.md +0 -8
  139. md_processing/dr_egeria_inbox/sb.md +0 -119
  140. md_processing/dr_egeria_inbox/search_test.md +0 -39
  141. md_processing/dr_egeria_inbox/solution-components.md +0 -154
  142. md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
  143. md_processing/dr_egeria_inbox/synonym_test.md +0 -42
  144. md_processing/dr_egeria_inbox/t1.md +0 -0
  145. md_processing/dr_egeria_inbox/t2.md +0 -268
  146. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
  147. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
  148. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
  149. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
  150. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
  151. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
  152. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
  153. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
  154. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
  155. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
  156. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
  157. md_processing/md_commands/blueprint_commands.py +0 -303
  158. pyegeria/.DS_Store +0 -0
  159. pyegeria/m_test.py +0 -118
  160. pyegeria-5.3.9.9.7.dist-info/RECORD +0 -196
  161. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  162. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
  163. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -8,8 +8,10 @@ This module provides access to the data-designer OMVS module.
8
8
  """
9
9
 
10
10
  import asyncio
11
+ from os import terminal_size
11
12
 
12
13
  from httpx import Response
14
+ from prompt_toolkit import data_structures
13
15
 
14
16
  from pyegeria._client import Client, max_paging_size
15
17
  from pyegeria._globals import NO_ELEMENTS_FOUND
@@ -569,6 +571,238 @@ r replace_all_properties: bool, default = False
569
571
  loop.run_until_complete(
570
572
  self._async_update_data_structure_w_body(data_struct_guid, body, replace_all_properties))
571
573
 
574
+ def get_data_memberships(self, data_get_fcn: callable, data_struct_guid: str) -> dict | None:
575
+ data_structure_info = data_get_fcn(data_struct_guid, output_format="JSON")
576
+ if data_structure_info == "No elements found":
577
+ return None
578
+ collection_list = {"DictList": [], "SpecList": [], "CollectionDetails": []}
579
+ if isinstance(data_structure_info, (dict, list)):
580
+ member_of_collections = data_structure_info.get('memberOfCollections',"")
581
+ if isinstance(member_of_collections, list):
582
+ for member_rel in member_of_collections:
583
+ props = member_rel["relatedElement"]["properties"]
584
+ qname = props.get('qualifiedName', None)
585
+ guid = member_rel['relatedElement']['elementHeader']['guid']
586
+ description = props.get('description', None)
587
+ collection_type = props.get('collectionType', None)
588
+ if collection_type == "Data Dictionary":
589
+ collection_list["DictList"].append(guid)
590
+ elif collection_type == "Data Specification":
591
+ collection_list["SpecList"].append(guid)
592
+ collection_list["CollectionDetails"].append({"guid":guid, "description":description,
593
+ "collectionType":collection_type, "qualifiedName":qname})
594
+ else:
595
+ return None
596
+ return collection_list
597
+ else:
598
+ return None
599
+
600
+ def get_data_memberships_with_dict(self, data_field_elements: dict) -> dict:
601
+ collection_list = {"DictList_guid": [], "DictList_qn": [], "SpecList_guid": [], "SpecList_qn": [], "CollectionDetails": []}
602
+ if isinstance(data_field_elements, (dict, list)):
603
+
604
+ for member_rel in data_field_elements:
605
+ type_name = ""
606
+ props = member_rel["relatedElement"]["properties"]
607
+ qname = props.get('qualifiedName', None)
608
+ guid = member_rel['relatedElement']['elementHeader']['guid']
609
+ description = props.get('description', None)
610
+ collection_type = props.get('collectionType', None)
611
+ classifications = member_rel["relatedElement"]["elementHeader"]["classifications"]
612
+ for classification in classifications:
613
+ type_name = classification["type"]['typeName']
614
+ if type_name == "DataDictionary":
615
+ collection_list["DictList_guid"].append(guid)
616
+ collection_list["DictList_qn"].append(qname)
617
+ elif type_name == "DataSpec":
618
+ collection_list["SpecList_guid"].append(guid)
619
+ collection_list["SpecList_qn"].append(qname)
620
+ collection_list["CollectionDetails"].append({"typeName":type_name, "guid":guid, "description":description,
621
+ "collectionType": collection_type,
622
+ "qualifiedName": qname
623
+ })
624
+ return collection_list
625
+
626
+
627
+ def get_data_rel_elements_dict(self, el_struct: dict)-> dict | str:
628
+ """return the lists of objects related to a data field"""
629
+
630
+ parent_guids = []
631
+ parent_names = []
632
+ parent_qnames = []
633
+
634
+ data_structure_guids = []
635
+ data_structure_names = []
636
+ data_structure_qnames = []
637
+
638
+ assigned_meanings_guids = []
639
+ assigned_meanings_names = []
640
+ assigned_meanings_qnames = []
641
+
642
+ data_class_guids = []
643
+ data_class_names = []
644
+ data_class_qnames = []
645
+
646
+ external_references_guids = []
647
+ external_references_names = []
648
+ external_references_qnames = []
649
+
650
+ member_of_data_dicts_guids = []
651
+ member_of_data_dicts_names = []
652
+ member_of_data_dicts_qnames = []
653
+
654
+ member_of_data_spec_guids = []
655
+ member_of_data_spec_names = []
656
+ member_of_data_spec_qnames = []
657
+
658
+ member_data_field_guids = []
659
+ member_data_field_names = []
660
+ member_data_field_qnames = []
661
+
662
+ nested_data_classes_guids = []
663
+ nested_data_classes_names = []
664
+ nested_data_classes_qnames = []
665
+
666
+ specialized_data_classes_guids = []
667
+ specialized_data_classes_names = []
668
+ specialized_data_classes_qnames = []
669
+
670
+
671
+
672
+ # terms
673
+ assigned_meanings = el_struct.get("assignedMeanings", {})
674
+ for meaning in assigned_meanings:
675
+ assigned_meanings_guids.append(meaning['relatedElement']['elementHeader']['guid'])
676
+ assigned_meanings_names.append(meaning['relatedElement']['properties']['displayName'])
677
+ assigned_meanings_qnames.append(meaning['relatedElement']['properties']['qualifiedName'])
678
+
679
+
680
+ # extract existing related data structure and data field elements
681
+ other_related_elements = el_struct.get("otherRelatedElements",None)
682
+ if other_related_elements:
683
+ for rel in other_related_elements:
684
+ related_element = rel["relatedElement"]
685
+ type = related_element["elementHeader"]["type"]["typeName"]
686
+ guid = related_element["elementHeader"]["guid"]
687
+ qualified_name = related_element["properties"].get("qualifiedName","") or ""
688
+ display_name = related_element["properties"].get("displayName","") or ""
689
+ if type == "DataStructure":
690
+ data_structure_guids.append(guid)
691
+ data_structure_names.append(display_name)
692
+ data_structure_qnames.append(qualified_name)
693
+
694
+ elif type == "DataField":
695
+ parent_guids.append(guid)
696
+ parent_names.append(display_name)
697
+ parent_qnames.append(qualified_name)
698
+
699
+
700
+ member_of_collections = el_struct.get("memberOfCollections",{})
701
+ for collection in member_of_collections:
702
+ c_type = collection["relatedElement"]["properties"].get("collectionType","") or ""
703
+ guid = collection["relatedElement"]["elementHeader"]["guid"]
704
+ name = collection["relatedElement"]["properties"].get("name","") or ""
705
+ qualifiedName = collection['relatedElement']["properties"].get("qualifiedName","") or ""
706
+ classifications = collection["relatedElement"]["elementHeader"]["classifications"]
707
+ for classification in classifications:
708
+ type_name = classification["type"]['typeName']
709
+ if type_name == "DataDictionary":
710
+ member_of_data_dicts_guids.append(guid)
711
+ member_of_data_dicts_names.append(name)
712
+ member_of_data_dicts_qnames.append(qualifiedName)
713
+ elif type_name == "DataSpec":
714
+ member_of_data_spec_guids.append(guid)
715
+ member_of_data_spec_names.append(name)
716
+ member_of_data_spec_qnames.append(qualifiedName)
717
+
718
+ member_data_fields = el_struct.get("memberDataFields", {})
719
+ for data_field in member_data_fields:
720
+ member_data_field_guids.append(data_field["elementHeader"]["guid"])
721
+ member_data_field_names.append(data_field["properties"]["displayName"])
722
+ member_data_field_qnames.append(data_field["properties"]["qualifiedName"])
723
+
724
+ data_classes = el_struct.get("assignedDataClasses", {})
725
+ for data_class in data_classes:
726
+ data_class_guids.append(data_class['relatedElement']["elementHeader"]["guid"])
727
+ data_class_names.append(data_class['relatedElement']["properties"]["displayName"])
728
+ data_class_qnames.append(data_class['relatedElement']["properties"]["qualifiedName"])
729
+
730
+ nested_data_classes = el_struct.get("nestedDataClasses", {})
731
+ for nested_data_class in nested_data_classes:
732
+ nested_data_classes_guids.append(nested_data_class['relatedElement']["elementHeader"]["guid"])
733
+ nested_data_classes_names.append(nested_data_class['relatedElement']["properties"]["displayName"])
734
+ nested_data_classes_qnames.append(nested_data_class['relatedElement']["properties"]["qualifiedName"])
735
+
736
+ specialized_data_classes = el_struct.get("specializedDataClasses", {})
737
+ for nested_data_class in specialized_data_classes:
738
+ specialized_data_classes_guids.append(nested_data_class['relatedElement']["elementHeader"]["guid"])
739
+ specialized_data_classes_names.append(nested_data_class['relatedElement']["properties"]["displayName"])
740
+ specialized_data_classes_qnames.append(nested_data_class['relatedElement']["properties"]["qualifiedName"])
741
+
742
+ mermaid = el_struct.get("mermaidGraph", {})
743
+
744
+ return {"parent_guids": parent_guids,
745
+ "parent_names": parent_names,
746
+ "parent_qnames": parent_qnames,
747
+
748
+ "data_structure_guids": data_structure_guids,
749
+ "data_structure_names": data_structure_names,
750
+ "data_structure_qnames": data_structure_qnames,
751
+
752
+ "assigned_meanings_guids": assigned_meanings_guids,
753
+ "assigned_meanings_names": assigned_meanings_names,
754
+ "assigned_meanings_qnames": assigned_meanings_qnames,
755
+
756
+ "data_class_guids": data_class_guids,
757
+ "data_class_names": data_class_names,
758
+ "data_class_qnames": data_class_qnames,
759
+
760
+ "nested_data_class_guids": nested_data_classes_guids,
761
+ "nested_data_class_names": nested_data_classes_names,
762
+ "nested_data_class_qnames": nested_data_classes_qnames,
763
+
764
+ "specialized_data_class_guids": specialized_data_classes_guids,
765
+ "specialized_data_class_names": specialized_data_classes_names,
766
+ "specialized_data_class_qnames": specialized_data_classes_qnames,
767
+
768
+ "external_references_guids": external_references_guids,
769
+ "external_references_names": external_references_names,
770
+ "external_references_qnames": external_references_qnames,
771
+
772
+ "member_of_data_dicts_guids": member_of_data_dicts_guids,
773
+ "member_of_data_dicts_names": member_of_data_dicts_names,
774
+ "member_of_data_dicts_qnames": member_of_data_dicts_qnames,
775
+
776
+ "member_of_data_spec_guids": member_of_data_spec_guids,
777
+ "member_of_data_spec_names": member_of_data_spec_names,
778
+ "member_of_data_spec_qnames": member_of_data_spec_qnames,
779
+
780
+ "member_data_field_guids": member_data_field_guids,
781
+ "member_data_field_names": member_data_field_names,
782
+ "member_data_field_qnames": member_data_field_qnames,
783
+
784
+ "mermaid" : mermaid,
785
+ }
786
+
787
+
788
+ def get_data_field_rel_elements(self, guid:str)-> dict | str:
789
+ """return the lists of objects related to a data field"""
790
+
791
+ data_field_entry = self.get_data_field_by_guid(guid, output_format="JSON")
792
+ if isinstance(data_field_entry, str):
793
+ return None
794
+ return self.get_data_rel_elements_dict(data_field_entry)
795
+
796
+ def get_data_class_rel_elements(self, guid:str)-> dict | str:
797
+ """return the lists of objects related to a data class"""
798
+
799
+ data_class_entry = self.get_data_class_by_guid(guid, output_format="JSON")
800
+ if isinstance(data_class_entry, str):
801
+ return None
802
+ return self.get_data_rel_elements_dict(data_class_entry)
803
+
804
+
805
+
572
806
  async def _async_link_member_data_field(self, parent_data_struct_guid: str, member_data_field_guid: str,
573
807
  body: dict = None) -> None:
574
808
  """
@@ -1125,6 +1359,8 @@ r replace_all_properties: bool, default = False
1125
1359
  the requesting user is not authorized to issue this request.
1126
1360
 
1127
1361
  """
1362
+ if filter == "*":
1363
+ filter = None
1128
1364
 
1129
1365
  body = {"filter": filter}
1130
1366
  starts_with_s = str(starts_with).lower()
@@ -1918,9 +2154,9 @@ r replace_all_properties: bool, default = False
1918
2154
  Parameters
1919
2155
  ----------
1920
2156
  parent_data_field_guid: str
1921
- - the GUID of the parent data class the nested data class will be connected to.
2157
+ - the GUID of the parent data field the nested data field will be connected to.
1922
2158
  nested_data_field_guid: str
1923
- - the GUID of the nested data class to be connected.
2159
+ - the GUID of the nested data field to be connected.
1924
2160
  body: dict, optional
1925
2161
  - a dictionary containing additional properties.
1926
2162
 
@@ -1977,9 +2213,9 @@ r replace_all_properties: bool, default = False
1977
2213
  Parameters
1978
2214
  ----------
1979
2215
  parent_data_field_guid: str
1980
- - the GUID of the parent data class the nested data class will be connected to.
2216
+ - the GUID of the parent data field the nested data field will be connected to.
1981
2217
  nested_data_field_guid: str
1982
- - the GUID of the nested data class to be connected.
2218
+ - the GUID of the nested data field to be connected.
1983
2219
  body: dict, optional
1984
2220
  - a dictionary containing additional properties.
1985
2221
 
@@ -2352,6 +2588,8 @@ r replace_all_properties: bool, default = False
2352
2588
  }
2353
2589
 
2354
2590
  """
2591
+ if body['filter'] == "*":
2592
+ body['filter'] = None
2355
2593
  starts_with_s = str(starts_with).lower()
2356
2594
  ends_with_s = str(ends_with).lower()
2357
2595
  ignore_case_s = str(ignore_case).lower()
@@ -2469,7 +2707,8 @@ r replace_all_properties: bool, default = False
2469
2707
  the requesting user is not authorized to issue this request.
2470
2708
 
2471
2709
  """
2472
-
2710
+ if filter == "*":
2711
+ filter = None
2473
2712
  body = {"filter": filter}
2474
2713
  starts_with_s = str(starts_with).lower()
2475
2714
  ends_with_s = str(ends_with).lower()
@@ -2708,7 +2947,7 @@ r replace_all_properties: bool, default = False
2708
2947
  if type(elements) is str:
2709
2948
  return NO_ELEMENTS_FOUND
2710
2949
  if output_format != 'JSON': # return other representations
2711
- return self.generate_data_field_output(elements, filter, output_format)
2950
+ return self.generate_data_field_output(elements, None, output_format)
2712
2951
  return elements
2713
2952
 
2714
2953
  def get_data_field_by_guid(self, guid: str, body: str = None, output_format: str = "DICT") -> list | str:
@@ -3217,7 +3456,7 @@ r replace_all_properties: bool, default = False
3217
3456
  """
3218
3457
  replace_all_properties_s = str(replace_all_properties).lower()
3219
3458
 
3220
- url = (f"{base_path(self, self.view_server)}/data-class/{data_class_guid}/update?"
3459
+ url = (f"{base_path(self, self.view_server)}/data-classes/{data_class_guid}/update?"
3221
3460
  f"replaceAllProperties={replace_all_properties_s}")
3222
3461
 
3223
3462
  await self._async_make_request("POST", url, body_slimmer(body))
@@ -3435,7 +3674,7 @@ r replace_all_properties: bool, default = False
3435
3674
  """
3436
3675
 
3437
3676
  url = (f"{base_path(self, self.view_server)}/data-classes/{parent_data_class_guid}"
3438
- f"/member-data-classes/{child_data_class_guid}/detach")
3677
+ f"/nested-data-classes/{child_data_class_guid}/detach")
3439
3678
 
3440
3679
  if body is None:
3441
3680
  await self._async_make_request("POST", url)
@@ -3534,7 +3773,7 @@ r replace_all_properties: bool, default = False
3534
3773
  """
3535
3774
 
3536
3775
  url = (f"{base_path(self, self.view_server)}/data-classes/{parent_data_class_guid}"
3537
- f"/specializeddata-classes/{child_data_class_guid}/attach")
3776
+ f"/specialized-data-classes/{child_data_class_guid}/attach")
3538
3777
 
3539
3778
  if body is None:
3540
3779
  await self._async_make_request("POST", url)
@@ -3633,7 +3872,7 @@ r replace_all_properties: bool, default = False
3633
3872
  """
3634
3873
 
3635
3874
  url = (f"{base_path(self, self.view_server)}/data-classes/{parent_data_class_guid}"
3636
- f"/specializeddata-classes/{child_data_class_guid}/detach")
3875
+ f"/specialized-data-classes/{child_data_class_guid}/detach")
3637
3876
 
3638
3877
  if body is None:
3639
3878
  await self._async_make_request("POST", url)
@@ -3917,6 +4156,7 @@ r replace_all_properties: bool, default = False
3917
4156
  }
3918
4157
 
3919
4158
  """
4159
+
3920
4160
  starts_with_s = str(starts_with).lower()
3921
4161
  ends_with_s = str(ends_with).lower()
3922
4162
  ignore_case_s = str(ignore_case).lower()
@@ -4034,7 +4274,8 @@ r replace_all_properties: bool, default = False
4034
4274
  the requesting user is not authorized to issue this request.
4035
4275
 
4036
4276
  """
4037
-
4277
+ if filter == "*":
4278
+ filter = None
4038
4279
  body = {"filter": filter}
4039
4280
 
4040
4281
  starts_with_s = str(starts_with).lower()
@@ -4042,7 +4283,7 @@ r replace_all_properties: bool, default = False
4042
4283
  ignore_case_s = str(ignore_case).lower()
4043
4284
 
4044
4285
  possible_query_params = query_string(
4045
- [("startFrom", start_from), ("pageSize", page_size), ("startsWith", ends_with_s), ("endsWith", ends_with_s),
4286
+ [("startFrom", start_from), ("pageSize", page_size), ("startsWith", starts_with_s), ("endsWith", ends_with_s),
4046
4287
  ("ignoreCase", ignore_case_s)])
4047
4288
 
4048
4289
  url = (f"{base_path(self, self.view_server)}/data-classes/by-search-string"
@@ -4270,7 +4511,7 @@ r replace_all_properties: bool, default = False
4270
4511
  else:
4271
4512
  response: Response = await self._async_make_request("POST", url)
4272
4513
 
4273
- elements = response.json().get("elements", NO_ELEMENTS_FOUND)
4514
+ elements = response.json().get("element", NO_ELEMENTS_FOUND)
4274
4515
  if type(elements) is str:
4275
4516
  return NO_ELEMENTS_FOUND
4276
4517
  if output_format != 'JSON': # return other representations
@@ -4944,9 +5185,25 @@ r replace_all_properties: bool, default = False
4944
5185
  namespace = properties.get("namespace", "") or ""
4945
5186
  version_id = properties.get("versionIdentifier", "") or ""
4946
5187
 
5188
+ # Get data type from extendedProperties and additionalProperties if available
5189
+ extended_properties = properties.get("extendedProperties", {})
5190
+ additional_properties = properties.get("additionalProperties", {})
5191
+
5192
+ # Now lets get the related elements
5193
+ associated_elements = self.get_data_rel_elements_dict(element)
5194
+ data_specs = associated_elements.get("member_of_data_spec_qnames", [])
5195
+ # data_structures = associated_elements.get("member_of_data_struct_qnames", [])
5196
+ assigned_meanings = associated_elements.get("assigned_meanings_qnames", [])
5197
+ parent_names = associated_elements.get("parent_qnames", [])
5198
+ member_data_fields = associated_elements.get("member_data_field_qnames", [])
5199
+
5200
+ mermaid = element.get('mermaidGraph', "") or ""
5201
+ # mermaid_md = "```mermaid\n" + mermaid + "\n```"
5202
+
4947
5203
  return {
4948
- 'guid': guid, 'properties': properties, 'display_name': display_name, 'description': description,
4949
- 'qualified_name': qualified_name, 'namespace': namespace, 'version_identifier': version_id
5204
+ 'GUID': guid, 'display_name': display_name, 'qualified_name': qualified_name, 'description': description, 'data_fields': member_data_fields,
5205
+ 'data_specification': data_specs, 'namespace': namespace, 'version_identifier': version_id, 'properties': properties,
5206
+ 'extended_properties': extended_properties, 'additional_properties': additional_properties, 'mermaid': mermaid
4950
5207
  }
4951
5208
 
4952
5209
  def _extract_data_class_properties(self, element: dict) -> dict:
@@ -4965,9 +5222,37 @@ r replace_all_properties: bool, default = False
4965
5222
  description = properties.get("description", "") or ""
4966
5223
  qualified_name = properties.get("qualifiedName", "") or ""
4967
5224
 
5225
+ data_type = properties.get('dataType', "") or ""
5226
+ match_property_names = properties.get('matchPropertyNames', []) or []
5227
+ match_threshold = properties.get('matchThreshold', 0)
5228
+ allow_duplicate_values = properties.get('allowDuplicateValues', False)
5229
+ is_case_sensitive = properties.get('isCaseSensitive', False)
5230
+ is_nullable = properties.get('isNullable', False)
5231
+
5232
+ # Get data type from extendedProperties and additionalProperties if available
5233
+ extended_properties = properties.get("extendedProperties", {})
5234
+ additional_properties = properties.get("additionalProperties", {})
5235
+
5236
+ # Now lets get the related elements
5237
+ associated_elements = self.get_data_rel_elements_dict(element)
5238
+ data_dictionaries = associated_elements.get("member_of_data_dicts_qnames", [])
5239
+ assigned_meanings = associated_elements.get("assigned_meanings_qnames", [])
5240
+ parent_names = associated_elements.get("parent_qnames", [])
5241
+ nested_data_classes = associated_elements.get("nested_data_class_qnames", [])
5242
+ specialized_data_classes = associated_elements.get("specialized_data_class_qnames", [])
5243
+ mermaid = element.get('mermaidGraph', "") or ""
5244
+
4968
5245
  return {
4969
- 'guid': guid, 'properties': properties, 'display_name': display_name, 'description': description,
4970
- 'qualified_name': qualified_name
5246
+ 'GUID': guid,'display_name': display_name, 'qualified_name': qualified_name,'description': description,
5247
+ 'assigned_meanings': assigned_meanings,
5248
+ 'data_type': data_type, 'match_property_names': match_property_names,
5249
+ 'match_threshold': match_threshold, 'allow_duplicate_values': allow_duplicate_values,
5250
+ 'is_case_sensitive': is_case_sensitive, 'is_nullable': is_nullable,
5251
+ 'properties': properties, 'parent_names': parent_names, 'nested_data_classes': nested_data_classes,
5252
+ 'specialized_data_classes': specialized_data_classes,
5253
+ 'extended_properties': extended_properties,
5254
+ 'additional_properties': additional_properties, 'data_dictionaries': data_dictionaries,
5255
+ 'mermaid': mermaid
4971
5256
  }
4972
5257
 
4973
5258
  def _extract_data_field_properties(self, element: dict) -> dict:
@@ -4986,13 +5271,34 @@ r replace_all_properties: bool, default = False
4986
5271
  description = properties.get("description", "") or ""
4987
5272
  qualified_name = properties.get("qualifiedName", "") or ""
4988
5273
 
4989
- # Get data type from extendedProperties if available
5274
+ is_nullable = properties.get('isNullable', False)
5275
+ data_type = properties.get('dataType', "") or ""
5276
+ minimum_length = properties.get('minimumLength', 0)
5277
+ length = properties.get('length', 0)
5278
+ precision = properties.get('precision', 0)
5279
+ ordered_values = properties.get('orderedValues', False)
5280
+ sort_order = properties.get('sortOrder', "") or ""
5281
+
5282
+ # Get data type from extendedProperties and additionalProperties if available
4990
5283
  extended_properties = properties.get("extendedProperties", {})
4991
- data_type = extended_properties.get("dataType", "")
5284
+ additional_properties = properties.get("additionalProperties", {})
5285
+
5286
+ # Now lets get the related elements
5287
+ associated_elements = self.get_data_rel_elements_dict(element)
5288
+ data_dictionaries = associated_elements.get("member_of_data_dicts_qnames",[])
5289
+ data_structures = associated_elements.get("data_structure_qnames",[])
5290
+ assigned_meanings = associated_elements.get("assigned_meanings_qnames",[])
5291
+ parent_names = associated_elements.get("parent_qnames",[])
5292
+ data_class = associated_elements.get("data_class_qnames",[])
5293
+ mermaid = element.get('mermaidGraph', "") or ""
4992
5294
 
4993
5295
  return {
4994
- 'guid': guid, 'properties': properties, 'display_name': display_name, 'description': description,
4995
- 'qualified_name': qualified_name, 'data_type': data_type
5296
+ 'GUID': guid,'display_name': display_name, 'qualified_name': qualified_name,'description': description,
5297
+ 'assigned_meanings': assigned_meanings,
5298
+ 'data_type': data_type, 'data_class': data_class, 'properties': properties,
5299
+ 'is_nullable': is_nullable, 'minimum_length': minimum_length, 'length': length, 'precision': precision,
5300
+ 'ordered_values': ordered_values, 'sort_order': sort_order, 'parent_names': parent_names, 'extended_properties': extended_properties,
5301
+ 'additional_properties': additional_properties,'data_dictionaries': data_dictionaries, 'data_structures': data_structures, 'mermaid': mermaid
4996
5302
  }
4997
5303
 
4998
5304
  def generate_basic_structured_output(self, elements, filter, output_format) -> str | list:
@@ -5002,7 +5308,7 @@ r replace_all_properties: bool, default = False
5002
5308
  Args:
5003
5309
  elements: Dictionary or list of dictionaries containing element data
5004
5310
  filter: The search string used to find the elements
5005
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID)
5311
+ output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
5006
5312
 
5007
5313
  Returns:
5008
5314
  Formatted output as string or list of dictionaries
@@ -5012,6 +5318,14 @@ r replace_all_properties: bool, default = False
5012
5318
  return extract_mermaid_only(elements)
5013
5319
  elif output_format == "DICT":
5014
5320
  return extract_basic_dict(elements)
5321
+ elif output_format == "HTML":
5322
+ return generate_output(
5323
+ elements=elements,
5324
+ search_string=filter,
5325
+ entity_type="Data Element",
5326
+ output_format="HTML",
5327
+ extract_properties_func=self._extract_data_structure_properties
5328
+ )
5015
5329
 
5016
5330
  # For other formats (MD, FORM, REPORT, LIST), use generate_output
5017
5331
  elif output_format in ["MD", "FORM", "REPORT", "LIST"]:
@@ -5033,15 +5347,15 @@ r replace_all_properties: bool, default = False
5033
5347
  Args:
5034
5348
  elements: Dictionary or list of dictionaries containing data structure elements
5035
5349
  filter: The search string used to find the elements
5036
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID)
5350
+ output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
5037
5351
 
5038
5352
  Returns:
5039
5353
  Formatted output as string or list of dictionaries
5040
5354
  """
5041
- if output_format in ["MD", "FORM", "REPORT", "LIST"]:
5355
+ if output_format in ["MD", "FORM", "REPORT", "LIST", "MERMAID", "HTML"]:
5042
5356
  # Define columns for LIST format
5043
5357
  columns = [{'name': 'Structure Name', 'key': 'display_name'},
5044
- {'name': 'Qualified Name', 'key': 'qualified_name'}, {'name': 'Namespace', 'key': 'namespace'},
5358
+ {'name': 'Qualified Name', 'key': 'qualified_name','format': True}, {'name': 'Namespace', 'key': 'namespace'},
5045
5359
  {'name': 'Version', 'key': 'version_identifier'},
5046
5360
  {'name': 'Description', 'key': 'description', 'format': True}]
5047
5361
 
@@ -5058,15 +5372,15 @@ r replace_all_properties: bool, default = False
5058
5372
  Args:
5059
5373
  elements: Dictionary or list of dictionaries containing data class elements
5060
5374
  filter: The search string used to find the elements
5061
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID)
5375
+ output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
5062
5376
 
5063
5377
  Returns:
5064
5378
  Formatted output as string or list of dictionaries
5065
5379
  """
5066
- if output_format in ["MD", "FORM", "REPORT", "LIST"]:
5380
+ if output_format in ["DICT", "MD", "FORM", "REPORT", "LIST", "MERMAID", "HTML"]:
5067
5381
  # Define columns for LIST format
5068
5382
  columns = [{'name': 'Class Name', 'key': 'display_name'},
5069
- {'name': 'Qualified Name', 'key': 'qualified_name'},
5383
+ {'name': 'Qualified Name', 'key': 'qualified_name','format': True},
5070
5384
  {'name': 'Description', 'key': 'description', 'format': True}]
5071
5385
 
5072
5386
  return generate_output(elements=elements, search_string=filter, entity_type="Data Class",
@@ -5082,15 +5396,15 @@ r replace_all_properties: bool, default = False
5082
5396
  Args:
5083
5397
  elements: Dictionary or list of dictionaries containing data field elements
5084
5398
  filter: The search string used to find the elements
5085
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID)
5399
+ output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
5086
5400
 
5087
5401
  Returns:
5088
5402
  Formatted output as a string or list of dictionaries
5089
5403
  """
5090
- if output_format in ["MD", "FORM", "REPORT", "LIST", "DICT"]:
5404
+ if output_format in ["MD", "FORM", "REPORT", "LIST", "DICT", "MERMAID", "HTML"]:
5091
5405
  # Define columns for LIST format
5092
5406
  columns = [{'name': 'Field Name', 'key': 'display_name'},
5093
- {'name': 'Qualified Name', 'key': 'qualified_name'}, {'name': 'Data Type', 'key': 'data_type'},
5407
+ {'name': 'Qualified Name', 'key': 'qualified_name','format': True}, {'name': 'Data Type', 'key': 'data_type'},
5094
5408
  {'name': 'Description', 'key': 'description', 'format': True}]
5095
5409
 
5096
5410
  return generate_output(elements=elements, search_string=filter, entity_type="Data Field",
@@ -5100,5 +5414,8 @@ r replace_all_properties: bool, default = False
5100
5414
  return self.generate_basic_structured_output(elements, filter, output_format)
5101
5415
 
5102
5416
 
5417
+
5418
+
5419
+
5103
5420
  if __name__ == "__main__":
5104
5421
  print("Data Designer")
@@ -5,37 +5,17 @@ Copyright Contributors to the ODPi Egeria project.
5
5
  Runtime manager is a view service that supports user interaction with the running platforms.
6
6
 
7
7
  """
8
- from pyegeria.x_action_author_omvs import ActionAuthor
9
- from pyegeria.asset_catalog_omvs import AssetCatalog
10
- from pyegeria.collection_manager_omvs import CollectionManager
11
- from pyegeria.glossary_manager_omvs import GlossaryManager
12
- from pyegeria.project_manager_omvs import ProjectManager
13
8
  from pyegeria.automated_curation_omvs import AutomatedCuration
14
9
  from pyegeria.classification_manager_omvs import ClassificationManager
15
- from pyegeria.template_manager_omvs import TemplateManager
16
- from pyegeria.runtime_manager_omvs import RuntimeManager
17
- from pyegeria.full_omag_server_config import FullServerConfig
18
- from pyegeria.metadata_explorer_omvs import MetadataExplorer
19
- from pyegeria.egeria_my_client import EgeriaMy
20
- from pyegeria.solution_architect_omvs import SolutionArchitect
21
- from pyegeria.server_operations import ServerOps
22
- from pyegeria.registered_info import RegisteredInfo
23
- from pyegeria.valid_metadata_omvs import ValidMetadataManager
10
+ from pyegeria.data_designer_omvs import DataDesigner
24
11
  from pyegeria.egeria_cat_client import EgeriaCat
25
12
  from pyegeria.metadata_explorer_omvs import MetadataExplorer
26
- from pyegeria.feedback_manager_omvs import FeedbackManager
27
- from pyegeria.my_profile_omvs import MyProfile
13
+ from pyegeria.registered_info import RegisteredInfo
14
+ from pyegeria.runtime_manager_omvs import RuntimeManager
28
15
  from pyegeria.solution_architect_omvs import SolutionArchitect
29
- from pyegeria.data_designer_omvs import DataDesigner
30
16
  from pyegeria.template_manager_omvs import TemplateManager
31
- from pyegeria.my_profile_omvs import MyProfile
32
- from pyegeria.utils import body_slimmer
33
- from pyegeria import (
34
- INTEGRATION_GUIDS,
35
- TEMPLATE_GUIDS, # ActionAuthor,
36
- max_paging_size,
37
- )
38
- from pyegeria._exceptions import InvalidParameterException
17
+ from pyegeria.valid_metadata_omvs import ValidMetadataManager
18
+ from pyegeria.governance_officer_omvs import GovernanceOfficer
39
19
 
40
20
 
41
21
  class EgeriaTech(
@@ -50,6 +30,7 @@ class EgeriaTech(
50
30
  SolutionArchitect,
51
31
  DataDesigner,
52
32
  TemplateManager,
33
+ GovernanceOfficer,
53
34
  ):
54
35
  """
55
36
  Client for technical Egeria users.
@@ -110,6 +91,9 @@ class EgeriaTech(
110
91
  TemplateManager.__init__(
111
92
  self, view_server, platform_url, user_id, user_pwd, token
112
93
  )
94
+ GovernanceOfficer.__init__(
95
+ self, view_server, platform_url, user_id, user_pwd, token
96
+ )
113
97
 
114
98
  if __name__ == "__main__":
115
99
  print("Main-Tech Client")