pyegeria 5.4.0.25__py3-none-any.whl → 5.4.0.27__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 (52) hide show
  1. commands/cat/debug_log +868 -7794
  2. commands/cat/debug_log.2025-08-18_11-34-38_088636.zip +0 -0
  3. commands/cat/list_collections.py +1 -1
  4. commands/cat/list_format_set.py +6 -8
  5. commands/cli/egeria.py +2 -2
  6. commands/cli/egeria_cat.py +3 -2
  7. commands/ops/load_archive.py +2 -2
  8. md_processing/data/commands.json +7 -7
  9. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +7 -7
  10. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +36 -31
  11. md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:22-dr_egeria_intro_part1.md +312 -0
  12. md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:23-dr_egeria_intro_part1.md +265 -0
  13. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:06-dr_egeria_intro_part1.md +230 -0
  14. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:30-dr_egeria_intro_part1.md +296 -0
  15. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:31-dr_egeria_intro_part1.md +253 -0
  16. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:08-dr_egeria_intro_part2.md +343 -0
  17. md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:12-dr_egeria_intro_part2.md +343 -0
  18. md_processing/md_commands/glossary_commands.py +888 -951
  19. md_processing/md_commands/product_manager_commands.py +8 -270
  20. md_processing/md_commands/project_commands.py +1 -1
  21. md_processing/md_processing_utils/common_md_proc_utils.py +138 -64
  22. md_processing/md_processing_utils/common_md_utils.py +2 -1
  23. pyegeria/__init__.py +5 -302
  24. pyegeria/_client_new.py +5 -4
  25. pyegeria/_output_formats.py +23 -3
  26. pyegeria/collection_manager.py +31 -28
  27. pyegeria/{load_config.py → config.py} +7 -2
  28. pyegeria/data_designer.py +154 -194
  29. pyegeria/egeria_cat_client.py +48 -30
  30. pyegeria/egeria_client.py +74 -75
  31. pyegeria/egeria_config_client.py +37 -7
  32. pyegeria/egeria_my_client.py +45 -10
  33. pyegeria/egeria_tech_client.py +69 -58
  34. pyegeria/glossary_manager.py +494 -122
  35. pyegeria/governance_officer.py +2 -2
  36. pyegeria/logging_configuration.py +1 -4
  37. pyegeria/models.py +1 -1
  38. pyegeria/project_manager.py +381 -741
  39. pyegeria/solution_architect_omvs.py +1 -1
  40. pyegeria/utils.py +1 -3
  41. {pyegeria-5.4.0.25.dist-info → pyegeria-5.4.0.27.dist-info}/METADATA +1 -1
  42. {pyegeria-5.4.0.25.dist-info → pyegeria-5.4.0.27.dist-info}/RECORD +45 -44
  43. commands/cat/debug_log.2025-08-15_09-14-07_444802.zip +0 -0
  44. commands/cat/debug_log.2025-08-16_10-21-59_388912.zip +0 -0
  45. commands/cat/debug_log.2025-08-17_11-34-27_981852.zip +0 -0
  46. md_processing/md_processing_utils/solution_architect_log.log +0 -0
  47. pyegeria/collection_manager_omvs.py +0 -6541
  48. pyegeria/glossary_browser.py +0 -1259
  49. pyegeria/project_manager_omvs.py +0 -1933
  50. {pyegeria-5.4.0.25.dist-info → pyegeria-5.4.0.27.dist-info}/LICENSE +0 -0
  51. {pyegeria-5.4.0.25.dist-info → pyegeria-5.4.0.27.dist-info}/WHEEL +0 -0
  52. {pyegeria-5.4.0.25.dist-info → pyegeria-5.4.0.27.dist-info}/entry_points.txt +0 -0
pyegeria/data_designer.py CHANGED
@@ -21,7 +21,6 @@ from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequ
21
21
  from pyegeria.output_formatter import (extract_mermaid_only, extract_basic_dict)
22
22
  from pyegeria.output_formatter import (generate_output,
23
23
  _extract_referenceable_properties)
24
- from pyegeria.output_formatter import (populate_columns_from_properties, get_required_relationships)
25
24
  from pyegeria.utils import body_slimmer, dynamic_catch
26
25
 
27
26
 
@@ -4683,136 +4682,118 @@ class DataDesigner(Client2):
4683
4682
 
4684
4683
 
4685
4684
 
4686
- def _extract_data_structure_properties(self, element: dict, columns_struct: dict) -> dict:
4685
+ def _extract_data_structure_properties(self, element: dict) -> dict:
4687
4686
  """
4688
- Populate columns_struct values for a Data Structure element using a standardized approach.
4687
+ Extract common properties from a data structure element.
4689
4688
 
4690
- - Populate values from element.properties via populate_columns_from_properties
4691
- - Overlay header-derived values using _extract_referenceable_properties
4692
- - Derive classifications as a comma-separated list
4693
- - Populate relationship-based columns using get_required_relationships
4694
- - Populate mermaid graph if requested
4689
+ Args:
4690
+ element (dict): The data structure element
4691
+
4692
+ Returns:
4693
+ dict: Dictionary of extracted properties
4694
+ """
4695
+ props = _extract_referenceable_properties(element)
4696
+
4697
+ props['properties'] = element.get('properties', {})
4698
+
4699
+ props['namespace'] = props['properties'].get("namespace", "") or ""
4700
+
4701
+ classification_names = []
4702
+ for c in props['classifications']:
4703
+ classification_names.append(c.get("classificationName", None))
4704
+ props['classifications'] = classification_names
4705
+
4706
+ # Now lets get the related elements
4707
+ associated_elements = self.get_data_rel_elements_dict(element)
4708
+ props['data_specs'] = associated_elements.get("member_of_data_spec_qnames", [])
4709
+
4710
+ # data_structures = associated_elements.get("member_of_data_struct_qnames", [])
4711
+ props['assigned_meanings'] = associated_elements.get("assigned_meanings_qnames", [])
4712
+ props['parent_names'] = associated_elements.get("parent_qnames", [])
4713
+ props['member_data_fields'] = associated_elements.get("member_data_field_qnames", [])
4695
4714
 
4696
- Returns the updated columns_struct.
4697
- """
4698
- # Start with properties-based values
4699
- col_data = populate_columns_from_properties(element, columns_struct)
4700
- columns_list = col_data.get("formats", {}).get("columns", [])
4701
-
4702
- # Header-derived values
4703
- header_props = _extract_referenceable_properties(element)
4704
- for column in columns_list:
4705
- key = column.get('key')
4706
- if key in header_props:
4707
- column['value'] = header_props.get(key)
4708
- elif isinstance(key, str) and key.lower() == 'guid':
4709
- column['value'] = header_props.get('GUID')
4710
-
4711
- # Classifications (names only)
4712
- cl_names = []
4713
- for c in element.get('elementHeader', {}).get('classifications', []) or []:
4714
- nm = c.get('classificationName')
4715
- if nm:
4716
- cl_names.append(nm)
4717
- if cl_names:
4718
- for column in columns_list:
4719
- if column.get('key') == 'classifications':
4720
- column['value'] = ", ".join(cl_names)
4721
- break
4722
-
4723
- # Relationship-derived values (generic)
4724
- col_data = get_required_relationships(element, col_data)
4725
-
4726
- # Mermaid graph
4727
- mermaid_val = element.get('mermaidGraph', "") or ""
4728
- for column in columns_list:
4729
- if column.get('key') == 'mermaid':
4730
- column['value'] = mermaid_val
4731
- break
4732
-
4733
- return col_data
4734
-
4735
- def _extract_data_class_properties(self, element: dict, columns_struct: dict) -> dict:
4736
- """
4737
- Populate columns_struct values for a Data Class element using the standardized approach.
4738
-
4739
- Uses properties population, header overlay, classifications, generic relationships,
4740
- and mermaid graph assignment similar to collection_manager.
4741
- """
4742
- col_data = populate_columns_from_properties(element, columns_struct)
4743
- columns_list = col_data.get("formats", {}).get("columns", [])
4744
-
4745
- header_props = _extract_referenceable_properties(element)
4746
- for column in columns_list:
4747
- key = column.get('key')
4748
- if key in header_props:
4749
- column['value'] = header_props.get(key)
4750
- elif isinstance(key, str) and key.lower() == 'guid':
4751
- column['value'] = header_props.get('GUID')
4752
-
4753
- # Classifications from header
4754
- cl_names = []
4755
- for c in element.get('elementHeader', {}).get('classifications', []) or []:
4756
- nm = c.get('classificationName')
4757
- if nm:
4758
- cl_names.append(nm)
4759
- if cl_names:
4760
- for column in columns_list:
4761
- if column.get('key') == 'classifications':
4762
- column['value'] = ", ".join(cl_names)
4763
- break
4764
-
4765
- # Relationships and mermaid
4766
- col_data = get_required_relationships(element, col_data)
4767
-
4768
- mermaid_val = element.get('mermaidGraph', "") or ""
4769
- for column in columns_list:
4770
- if column.get('key') == 'mermaid':
4771
- column['value'] = mermaid_val
4772
- break
4773
-
4774
- return col_data
4775
-
4776
- def _extract_data_field_properties(self, element: dict, columns_struct: dict) -> dict:
4777
- """
4778
- Populate columns_struct values for a Data Field element using the standardized approach.
4779
-
4780
- Populates from properties, overlays header values, derives classifications, uses
4781
- get_required_relationships for relationships, and adds mermaid graph.
4782
- """
4783
- col_data = populate_columns_from_properties(element, columns_struct)
4784
- columns_list = col_data.get("formats", {}).get("columns", [])
4785
-
4786
- header_props = _extract_referenceable_properties(element)
4787
- for column in columns_list:
4788
- key = column.get('key')
4789
- if key in header_props:
4790
- column['value'] = header_props.get(key)
4791
- elif isinstance(key, str) and key.lower() == 'guid':
4792
- column['value'] = header_props.get('GUID')
4793
-
4794
- # Classifications from header
4795
- cl_names = []
4796
- for c in element.get('elementHeader', {}).get('classifications', []) or []:
4797
- nm = c.get('classificationName')
4798
- if nm:
4799
- cl_names.append(nm)
4800
- if cl_names:
4801
- for column in columns_list:
4802
- if column.get('key') == 'classifications':
4803
- column['value'] = ", ".join(cl_names)
4804
- break
4805
-
4806
- # Relationships and mermaid
4807
- col_data = get_required_relationships(element, col_data)
4808
-
4809
- mermaid_val = element.get('mermaidGraph', "") or ""
4810
- for column in columns_list:
4811
- if column.get('key') == 'mermaid':
4812
- column['value'] = mermaid_val
4813
- break
4814
-
4815
- return col_data
4715
+ props['mermaid'] = element.get('mermaidGraph', "") or ""
4716
+
4717
+ return props
4718
+
4719
+ def _extract_data_class_properties(self, element: dict) -> dict:
4720
+ """
4721
+ Extract common properties from a data class element.
4722
+
4723
+ Args:
4724
+ element (dict): The data class element
4725
+
4726
+ Returns:
4727
+ dict: Dictionary of extracted properties
4728
+ """
4729
+ props = _extract_referenceable_properties(element)
4730
+ properties = element.get('properties', {})
4731
+ props['properties'] = properties
4732
+
4733
+ classification_names = []
4734
+ for c in props['classifications']:
4735
+ classification_names.append(c.get("classificationName", None))
4736
+ props['classifications'] = classification_names
4737
+
4738
+ props['namespace'] = props['properties'].get("namespace", "") or ""
4739
+
4740
+ props['data_type'] = properties.get('dataType', "") or ""
4741
+ props['match_property_names'] = properties.get('matchPropertyNames', []) or []
4742
+ props['match_threshold'] = properties.get('matchThreshold', 0)
4743
+ props['allow_duplicate_values'] = properties.get('allowDuplicateValues', False)
4744
+ props['is_case_sensitive'] = properties.get('isCaseSensitive', False)
4745
+ props['is_nullable'] = properties.get('isNullable', False)
4746
+
4747
+ # Now lets get the related elements
4748
+ associated_elements = self.get_data_rel_elements_dict(element)
4749
+ props['data_dictionaries'] = associated_elements.get("member_of_data_dicts_qnames", [])
4750
+ props['assigned_meanings'] = associated_elements.get("assigned_meanings_qnames", [])
4751
+ props['parent_names'] = associated_elements.get("parent_qnames", [])
4752
+ props['nested_data_classes'] = associated_elements.get("nested_data_class_qnames", [])
4753
+ props['specialized_data_classes'] = associated_elements.get("specialized_data_class_qnames", [])
4754
+ props['mermaid'] = element.get('mermaidGraph', "") or ""
4755
+
4756
+ return props
4757
+
4758
+ def _extract_data_field_properties(self, element: dict) -> dict:
4759
+ """
4760
+ Extract common properties from a data field element.
4761
+
4762
+ Args:
4763
+ element (dict): The data field element
4764
+
4765
+ Returns:
4766
+ dict: Dictionary of extracted properties
4767
+ """
4768
+ props = _extract_referenceable_properties(element)
4769
+
4770
+ props['properties'] = element.get('properties', {})
4771
+ props['namespace'] = props['properties'].get("namespace", "") or ""
4772
+ properties = element.get('properties', {})
4773
+
4774
+ classification_names = []
4775
+ for c in props['classifications']:
4776
+ classification_names.append(c.get("classificationName", None))
4777
+ props['classifications'] = classification_names
4778
+
4779
+ props['is_nullable'] = properties.get('isNullable', False)
4780
+ props['data_type'] = properties.get('dataType', "") or ""
4781
+ props['minimum_length'] = properties.get('minimumLength', 0)
4782
+ props['length'] = properties.get('length', 0)
4783
+ props['precision'] = properties.get('precision', 0)
4784
+ props['ordered_values'] = properties.get('orderedValues', False)
4785
+ props['sort_order'] = properties.get('sortOrder', "") or ""
4786
+
4787
+ # Now lets get the related elements
4788
+ associated_elements = self.get_data_rel_elements_dict(element)
4789
+ props['data_dictionaries'] = associated_elements.get("member_of_data_dicts_qnames", [])
4790
+ props['data_structures'] = associated_elements.get("data_structure_qnames", [])
4791
+ props['assigned_meanings'] = associated_elements.get("assigned_meanings_qnames", [])
4792
+ props['parent_names'] = associated_elements.get("parent_qnames", [])
4793
+ props['data_class'] = associated_elements.get("data_class_qnames", [])
4794
+ props['mermaid'] = element.get('mermaidGraph', "") or ""
4795
+
4796
+ return props
4816
4797
 
4817
4798
  def _generate_basic_structured_output(self, elements: dict, filter: str, output_format: str,
4818
4799
  columns_struct: dict = None) -> str | list:
@@ -4857,7 +4838,6 @@ class DataDesigner(Client2):
4857
4838
  )
4858
4839
 
4859
4840
  def _generate_data_structure_output(self, elements: dict | list[dict], filter: str = None,
4860
- element_type_name: str | None = None,
4861
4841
  output_format: str = "DICT",
4862
4842
  output_format_set: str | dict = None) -> str | list:
4863
4843
  """
@@ -4866,43 +4846,33 @@ class DataDesigner(Client2):
4866
4846
  Args:
4867
4847
  elements: Dictionary or list of dictionaries containing data structure elements
4868
4848
  filter: The search string used to find the elements
4869
- element_type_name: Optional specific subtype name to drive output format selection
4870
4849
  output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
4871
4850
 
4872
4851
  Returns:
4873
4852
  Formatted output as string or list of dictionaries
4874
4853
  """
4875
- entity_type = element_type_name or "Data Structure"
4854
+ entity_type = "Data Structure"
4855
+ if output_format_set is None:
4856
+ output_format_set = select_output_format_set(entity_type, output_format)
4876
4857
 
4877
- # First see if the user has specified an output_format_set - either a label or a dict
4878
4858
  if output_format_set:
4879
4859
  if isinstance(output_format_set, str):
4880
4860
  output_formats = select_output_format_set(output_format_set, output_format)
4881
- elif isinstance(output_format_set, dict):
4861
+ if isinstance(output_format_set, dict):
4882
4862
  output_formats = get_output_format_type_match(output_format_set, output_format)
4883
- # If no output_format was set, then use the element_type_name to lookup the output format
4884
- elif element_type_name:
4885
- output_formats = select_output_format_set(element_type_name, output_format)
4886
4863
  else:
4887
- # fallback to entity type
4888
- output_formats = select_output_format_set(entity_type, output_format)
4889
- if output_formats is None:
4890
- output_formats = select_output_format_set("Default", output_format)
4891
-
4864
+ output_formats = None
4892
4865
  logger.trace(f"Executing _generate_data_structure_output for {entity_type}: {output_formats}")
4893
- return generate_output(
4894
- elements,
4895
- filter,
4896
- entity_type,
4897
- output_format,
4898
- self._extract_data_structure_properties,
4899
- None,
4900
- output_formats,
4901
- )
4902
-
4903
- def _generate_data_class_output(self, elements: dict | list[dict], filter: str = None,
4904
- element_type_name: str | None = None,
4905
- output_format: str = "DICT",
4866
+ return generate_output(elements,
4867
+ filter,
4868
+ entity_type,
4869
+ output_format,
4870
+ self._extract_data_structure_properties,
4871
+ None,
4872
+ output_formats,
4873
+ )
4874
+
4875
+ def _generate_data_class_output(self, elements: dict | list[dict], filter: str = None, output_format: str = "DICT",
4906
4876
  output_format_set: str | dict = None) -> str | list:
4907
4877
  """
4908
4878
  Generate output for data classes in the specified format.
@@ -4910,40 +4880,34 @@ class DataDesigner(Client2):
4910
4880
  Args:
4911
4881
  elements: Dictionary or list of dictionaries containing data class elements
4912
4882
  filter: The search string used to find the elements
4913
- element_type_name: Optional specific subtype name to drive output format selection
4914
4883
  output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
4915
4884
  output_format_set: Optional output format set
4916
4885
  - Option column/attribute selection and definition.
4917
4886
  Returns:
4918
4887
  Formatted output as either a string or list of dictionaries
4919
4888
  """
4920
- entity_type = element_type_name or "Data Class"
4889
+ entity_type = "Data Class"
4890
+ if output_format_set is None:
4891
+ output_format_set = select_output_format_set(entity_type, output_format)
4892
+
4921
4893
  if output_format_set:
4922
4894
  if isinstance(output_format_set, str):
4923
4895
  output_formats = select_output_format_set(output_format_set, output_format)
4924
- elif isinstance(output_format_set, dict):
4896
+ if isinstance(output_format_set, dict):
4925
4897
  output_formats = get_output_format_type_match(output_format_set, output_format)
4926
- elif element_type_name:
4927
- output_formats = select_output_format_set(element_type_name, output_format)
4928
4898
  else:
4929
- output_formats = select_output_format_set(entity_type, output_format)
4930
- if output_formats is None:
4931
- output_formats = select_output_format_set("Default", output_format)
4932
-
4899
+ output_formats = None
4933
4900
  logger.trace(f"Executing _generate_data_class_output for {entity_type}: {output_formats}")
4934
- return generate_output(
4935
- elements,
4936
- filter,
4937
- entity_type,
4938
- output_format,
4939
- self._extract_data_class_properties,
4940
- None,
4941
- output_formats,
4942
- )
4943
-
4944
- def _generate_data_field_output(self, elements: dict | list[dict], filter: str = None,
4945
- element_type_name: str | None = None,
4946
- output_format: str = "DICT",
4901
+ return generate_output(elements,
4902
+ filter,
4903
+ entity_type,
4904
+ output_format,
4905
+ self._extract_data_class_properties,
4906
+ None,
4907
+ output_formats,
4908
+ )
4909
+
4910
+ def _generate_data_field_output(self, elements: dict | list[dict], filter: str = None, output_format: str = "DICT",
4947
4911
  output_format_set: str | dict = None) -> str | list:
4948
4912
  """
4949
4913
  Generate output for data fields in the specified format.
@@ -4951,7 +4915,6 @@ class DataDesigner(Client2):
4951
4915
  Args:
4952
4916
  elements: Dictionary or list of dictionaries containing data field elements
4953
4917
  filter: The search string used to find the elements
4954
- element_type_name: Optional specific subtype name to drive output format selection
4955
4918
  output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
4956
4919
  output_format_set: str|dict, Optional, default = None
4957
4920
  - Option column/attribute selection and definition.
@@ -4959,29 +4922,26 @@ class DataDesigner(Client2):
4959
4922
  Returns:
4960
4923
  Formatted output as a string or list of dictionaries
4961
4924
  """
4962
- entity_type = element_type_name or "Data Field"
4925
+ entity_type = "Data Field"
4926
+ if output_format_set is None:
4927
+ output_format_set = select_output_format_set(entity_type, output_format)
4928
+
4963
4929
  if output_format_set:
4964
4930
  if isinstance(output_format_set, str):
4965
4931
  output_formats = select_output_format_set(output_format_set, output_format)
4966
- elif isinstance(output_format_set, dict):
4932
+ if isinstance(output_format_set, dict):
4967
4933
  output_formats = get_output_format_type_match(output_format_set, output_format)
4968
- elif element_type_name:
4969
- output_formats = select_output_format_set(element_type_name, output_format)
4970
4934
  else:
4971
- output_formats = select_output_format_set(entity_type, output_format)
4972
- if output_formats is None:
4973
- output_formats = select_output_format_set("Default", output_format)
4974
-
4935
+ output_formats = None
4975
4936
  logger.trace(f"Executing _generate_data_field_output for {entity_type}: {output_formats}")
4976
- return generate_output(
4977
- elements,
4978
- filter,
4979
- entity_type,
4980
- output_format,
4981
- self._extract_data_field_properties,
4982
- None,
4983
- output_formats,
4984
- )
4937
+ return generate_output(elements,
4938
+ filter,
4939
+ entity_type,
4940
+ output_format,
4941
+ self._extract_data_field_properties,
4942
+ None,
4943
+ output_formats,
4944
+ )
4985
4945
 
4986
4946
 
4987
4947
  if __name__ == "__main__":
@@ -8,39 +8,29 @@ AssetCatalog, CollectionManager, GlossaryManager, and ProjectManager.
8
8
  """
9
9
  from pyegeria.egeria_my_client import EgeriaMy
10
10
  from pyegeria.asset_catalog_omvs import AssetCatalog
11
- from pyegeria.collection_manager import CollectionManager
12
- from pyegeria.glossary_manager_omvs import GlossaryManager
13
- from pyegeria.project_manager_omvs import ProjectManager
11
+ # from pyegeria.collection_manager import CollectionManager
12
+ from pyegeria.glossary_manager import GlossaryManager
13
+ from pyegeria.project_manager import ProjectManager
14
14
 
15
15
 
16
- class EgeriaCat(
17
- AssetCatalog,
18
- CollectionManager,
19
- EgeriaMy,
20
- GlossaryManager,
21
- # GovernanceAuthor,
22
- # PeopleOrganizer,
23
- ProjectManager,
24
- ):
16
+ class EgeriaCat:
25
17
  """
26
- Client to issue Runtime status requests.
18
+ Catalog-oriented client using composition of AssetCatalog, EgeriaMy, GlossaryManager, and ProjectManager.
27
19
 
28
20
  Attributes:
29
-
30
- server_name: str
31
- Name of the server to use.
21
+ view_server: str
22
+ Name of the view server to use.
32
23
  platform_url : str
33
24
  URL of the server platform to connect to
34
25
  user_id : str
35
- The identity of the user calling the method - this sets a default optionally used by the methods
36
- when the user doesn't pass the user_id on a method call.
26
+ The identity of the user calling the method.
37
27
  user_pwd: str
38
28
  The password associated with the user_id. Defaults to None
39
29
  token: str
40
30
  An optional bearer token
41
31
 
42
32
  Methods:
43
-
33
+ Methods are provided by composed sub-clients via delegation.
44
34
  """
45
35
 
46
36
  def __init__(
@@ -56,19 +46,47 @@ class EgeriaCat(
56
46
  self.user_id = user_id
57
47
  self.user_pwd = user_pwd
58
48
 
59
- AssetCatalog.__init__(self, view_server, platform_url, user_id, user_pwd, token)
60
- CollectionManager.__init__(
61
- self, view_server, platform_url, user_id, user_pwd, token
62
- )
63
- EgeriaMy.__init__(self, view_server, platform_url, user_id, user_pwd, token)
49
+ # Compose sub-clients
50
+ self._asset_catalog = AssetCatalog(view_server, platform_url, user_id, user_pwd, token)
51
+ self._my = EgeriaMy(view_server, platform_url, user_id, user_pwd, token)
52
+ self._glossary = GlossaryManager(view_server, platform_url, user_id, user_pwd, token)
53
+ self._projects = ProjectManager(view_server, platform_url, user_id, user_pwd, token)
54
+ self._subclients = [
55
+ self._asset_catalog,
56
+ self._my,
57
+ self._glossary,
58
+ self._projects,
59
+ ]
60
+
61
+ def __getattr__(self, name):
62
+ for sub in self._subclients:
63
+ if hasattr(sub, name):
64
+ return getattr(sub, name)
65
+ raise AttributeError(f"{self.__class__.__name__!s} object has no attribute {name!r}")
66
+
67
+ def create_egeria_bearer_token(self, user_id: str = None, user_pwd: str = None):
68
+ token_val = None
69
+ for sub in self._subclients:
70
+ token_val = sub.create_egeria_bearer_token(user_id, user_pwd)
71
+ return token_val
72
+
73
+ def set_bearer_token(self, token: str) -> None:
74
+ for sub in self._subclients:
75
+ sub.set_bearer_token(token)
64
76
 
65
- GlossaryManager.__init__(
66
- self, view_server, platform_url, user_id, user_pwd, token
67
- )
77
+ def get_token(self) -> str:
78
+ for sub in self._subclients:
79
+ if hasattr(sub, "get_token"):
80
+ return sub.get_token()
81
+ return None
68
82
 
69
- ProjectManager.__init__(
70
- self, view_server, platform_url, user_id, user_pwd, token
71
- )
83
+ def close_session(self) -> None:
84
+ for sub in self._subclients:
85
+ if hasattr(sub, "close_session"):
86
+ try:
87
+ sub.close_session()
88
+ except Exception:
89
+ pass
72
90
 
73
91
 
74
92
  if __name__ == "__main__":