pyegeria 5.4.3.3__py3-none-any.whl → 5.4.3.4__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 (41) hide show
  1. commands/cat/debug_log.2025-09-02_07-44-39_567276.log.zip +0 -0
  2. commands/cat/debug_log.2025-09-03_07-45-21_986388.log.zip +0 -0
  3. commands/cat/debug_log.log +5314 -4140
  4. commands/cat/list_format_set.py +2 -2
  5. commands/tech/list_information_supply_chains.py +1 -1
  6. commands/tech/list_solution_blueprints.py +1 -1
  7. commands/tech/list_solution_components.py +1 -1
  8. commands/tech/list_solution_roles.py +1 -1
  9. md_processing/__init__.py +0 -4
  10. md_processing/data/commands.json +4 -4
  11. md_processing/dr_egeria.py +6 -9
  12. md_processing/dr_egeria_inbox/data_spec_test.md +38 -364
  13. md_processing/dr_egeria_inbox/gov_def.md +3 -3
  14. md_processing/dr_egeria_inbox/product.md +10 -2
  15. md_processing/md_commands/data_designer_commands.py +90 -425
  16. md_processing/md_processing_utils/common_md_utils.py +50 -1
  17. md_processing/md_processing_utils/extraction_utils.py +14 -7
  18. md_processing/md_processing_utils/md_processing_constants.py +1 -1
  19. pyegeria/___external_references.py +2943 -2955
  20. pyegeria/__init__.py +1 -1
  21. pyegeria/_client_new.py +9 -7
  22. pyegeria/_output_formats.py +124 -3
  23. pyegeria/collection_manager.py +17 -56
  24. pyegeria/config.py +10 -1
  25. pyegeria/data_designer.py +166 -117
  26. pyegeria/egeria_client.py +1 -1
  27. pyegeria/egeria_tech_client.py +1 -1
  28. pyegeria/glossary_manager.py +71 -85
  29. pyegeria/governance_officer.py +26 -29
  30. pyegeria/output_formatter.py +127 -1
  31. pyegeria/project_manager.py +33 -36
  32. pyegeria/{solution_architect_omvs.py → solution_architect.py} +443 -388
  33. {pyegeria-5.4.3.3.dist-info → pyegeria-5.4.3.4.dist-info}/METADATA +1 -1
  34. {pyegeria-5.4.3.3.dist-info → pyegeria-5.4.3.4.dist-info}/RECORD +37 -39
  35. md_processing/dr_egeria_outbox/tuesday/processed-2025-09-02 13:07-gov_def.md +0 -492
  36. md_processing/dr_egeria_outbox/tuesday/processed-2025-09-02 13:25-gov_def.md +0 -520
  37. md_processing/dr_egeria_outbox/tuesday/processed-2025-09-02 16:43-gov_def.md +0 -636
  38. md_processing/dr_egeria_outbox/tuesday/processed-2025-09-02 16:46-gov_def.md +0 -636
  39. {pyegeria-5.4.3.3.dist-info → pyegeria-5.4.3.4.dist-info}/LICENSE +0 -0
  40. {pyegeria-5.4.3.3.dist-info → pyegeria-5.4.3.4.dist-info}/WHEEL +0 -0
  41. {pyegeria-5.4.3.3.dist-info → pyegeria-5.4.3.4.dist-info}/entry_points.txt +0 -0
@@ -677,7 +677,7 @@ def generate_entity_dict(elements: List[Dict],
677
677
  value = format_for_markdown_table(value, guid or props.get('GUID'))
678
678
  entity_dict[name] = value
679
679
  else:
680
- props = extract_properties_func(element)
680
+ props = extract_properties_func(element, columns_struct)
681
681
  # Add properties based on include/exclude lists
682
682
  for key, value in props.items():
683
683
  if key not in ['properties', 'mermaid']: # Skip the raw properties object
@@ -721,6 +721,127 @@ def generate_entity_dict(elements: List[Dict],
721
721
 
722
722
  return result
723
723
 
724
+ def resolve_output_formats(entity_type: str,
725
+ output_format: str,
726
+ output_format_set: Optional[Union[str, dict]] = None,
727
+ default_label: Optional[str] = None) -> Optional[dict]:
728
+ """
729
+ Resolve an output format set structure given an entity type, the desired output format
730
+ (e.g., DICT, LIST, MD, REPORT, FORM), and either a label (str) or a dict of format sets.
731
+
732
+ Selection order:
733
+ - If output_format_set is a str: select by label.
734
+ - If output_format_set is a dict: use get_output_format_type_match to pick a matching format.
735
+ - Else: try selecting by entity_type or default_label.
736
+ - Fallback: select "Default".
737
+ """
738
+ from pyegeria._output_formats import select_output_format_set, get_output_format_type_match
739
+
740
+ if isinstance(output_format_set, str):
741
+ return select_output_format_set(output_format_set, output_format)
742
+ if isinstance(output_format_set, dict):
743
+ return get_output_format_type_match(output_format_set, output_format)
744
+
745
+ label = default_label or entity_type
746
+ fmt = select_output_format_set(label, output_format)
747
+ if fmt is None:
748
+ fmt = select_output_format_set("Default", output_format)
749
+ return fmt
750
+
751
+
752
+ def overlay_additional_values(columns_struct: dict, extra: Optional[dict]) -> dict:
753
+ """
754
+ Overlay extra values into columns_struct only where the column's value is empty or missing.
755
+ Returns the modified columns_struct.
756
+ """
757
+ if not isinstance(columns_struct, dict) or not extra:
758
+ return columns_struct
759
+ columns = columns_struct.get('formats', {}).get('columns')
760
+ if not isinstance(columns, list):
761
+ return columns_struct
762
+ for col in columns:
763
+ if not isinstance(col, dict):
764
+ continue
765
+ key = col.get('key')
766
+ if not key:
767
+ continue
768
+ if col.get('value') in (None, "") and key in extra:
769
+ col['value'] = extra[key]
770
+ return columns_struct
771
+
772
+
773
+ def populate_common_columns(
774
+ element: dict,
775
+ columns_struct: dict,
776
+ *,
777
+ include_header: bool = True,
778
+ include_relationships: bool = True,
779
+ include_subject_area: bool = True,
780
+ mermaid_source_key: str = 'mermaidGraph',
781
+ mermaid_dest_key: str = 'mermaid'
782
+ ) -> dict:
783
+ """
784
+ Populate the common columns in columns_struct based on a standard Egeria element shape.
785
+
786
+ Steps:
787
+ - Populate from element.properties (camelCase mapped from snake_case keys)
788
+ - Optionally overlay header-derived values (GUID, type_name, times, etc.)
789
+ - Optionally populate relationship-based columns via get_required_relationships
790
+ - Optionally populate subject_area from element.elementHeader.subjectArea.classificationProperties.subjectAreaName
791
+ - If a column with key == mermaid_dest_key is present, set it from mermaid_source_key
792
+ - Do not overwrite non-empty values already set
793
+ """
794
+ # 1) Base properties
795
+ col_data = populate_columns_from_properties(element, columns_struct)
796
+ columns_list = col_data.get('formats', {}).get('columns', [])
797
+
798
+ # 2) Header overlay
799
+ header_props = _extract_referenceable_properties(element) if include_header else {}
800
+ guid = header_props.get('GUID') if include_header else None
801
+ if include_header:
802
+ for column in columns_list:
803
+ if not isinstance(column, dict):
804
+ continue
805
+ key = column.get('key')
806
+ if not key:
807
+ continue
808
+ if column.get('value') not in (None, ""):
809
+ continue
810
+ if key in header_props:
811
+ column['value'] = header_props.get(key)
812
+ elif isinstance(key, str) and key.lower() == 'guid':
813
+ column['value'] = guid
814
+
815
+ # 3) Relationships
816
+ if include_relationships:
817
+ col_data = get_required_relationships(element, col_data)
818
+
819
+ # 4) Subject area
820
+ if include_subject_area:
821
+ try:
822
+ subject_area = element.get('elementHeader', {}).get('subjectArea') or ""
823
+ subj_val = ""
824
+ if isinstance(subject_area, dict):
825
+ subj_val = subject_area.get('classificationProperties', {}).get('subjectAreaName', '')
826
+ for column in columns_list:
827
+ if column.get('key') == 'subject_area' and column.get('value') in (None, ""):
828
+ column['value'] = subj_val
829
+ except Exception as e:
830
+ logger.debug(f"populate_common_columns: subject_area handling error: {e}")
831
+
832
+ # 5) Mermaid
833
+ try:
834
+ mermaid_val = element.get(mermaid_source_key, '') or ''
835
+ for column in columns_list:
836
+ if column.get('key') == mermaid_dest_key and column.get('value') in (None, ""):
837
+ column['value'] = mermaid_val
838
+ break
839
+ except Exception as e:
840
+ logger.debug(f"populate_common_columns: mermaid handling error: {e}")
841
+
842
+ return col_data
843
+
844
+
724
845
  def extract_mermaid_only(elements: Union[Dict, List[Dict]]) -> Union[str, List[str]]:
725
846
  """
726
847
  Extract mermaid graph data from elements.
@@ -810,6 +931,11 @@ def generate_output(elements: Union[Dict, List[Dict]],
810
931
  Formatted output as string or list of dictionaries
811
932
  """
812
933
  columns = columns_struct['formats'].get('columns',None) if columns_struct else None
934
+ if not columns:
935
+ columns_struct = select_output_format_set("Default",output_format)
936
+ if columns_struct:
937
+ columns = columns_struct.get('formats', {}).get('columns', None)
938
+
813
939
  target_type = columns_struct.get('target_type', entity_type) if columns_struct else entity_type
814
940
  if target_type is None:
815
941
  target_type = entity_type
@@ -17,7 +17,7 @@ from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequ
17
17
  TemplateRequestBody, DeleteRequestBody, UpdateElementRequestBody,
18
18
  NewRelationshipRequestBody)
19
19
  from pyegeria.output_formatter import generate_output, populate_columns_from_properties, \
20
- _extract_referenceable_properties, get_required_relationships
20
+ _extract_referenceable_properties, get_required_relationships, populate_common_columns, overlay_additional_values
21
21
  from pyegeria.utils import body_slimmer, dynamic_catch
22
22
 
23
23
  EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
@@ -28,20 +28,33 @@ PROJECT_TYPES = ["Project", "Campaign", "StudyProject", "Task", "PersonalProject
28
28
 
29
29
  class ProjectManager(Client2):
30
30
  """
31
- Create and manage projects. Projects may be organized in a hierarchy.
32
- See https://egeria-project.org/types/1/0130-Projects
33
-
34
- Attributes:
35
-
36
- server_name: str
37
- The name of the View Server to connect to.
38
- platform_url : str
39
- URL of the server platform to connect to
40
- user_id : str
41
- The identity of the user calling the method - this sets a default optionally used by the methods
42
- when the user doesn't pass the user_id on a method call.
43
- user_pwd: str
44
- The password associated with the user_id. Defaults to None
31
+ Manage Open Metadata Projects via the Project Manager OMVS.
32
+
33
+ This client provides asynchronous and synchronous helpers to create, update, search,
34
+ and relate Project elements and their subtypes (Campaign, StudyProject, Task, PersonalProject).
35
+
36
+ References
37
+ - Egeria concept: https://egeria-project.org/concepts/project
38
+ - Type lineage: https://egeria-project.org/types/1/0130-Projects
39
+
40
+ Parameters
41
+ -----------
42
+ view_server : str
43
+ The name of the View Server to connect to.
44
+ platform_url : str
45
+ URL of the server platform to connect to.
46
+ user_id : str
47
+ Default user identity for calls (can be overridden per call).
48
+ user_pwd : str, optional
49
+ Password for the user_id. If a token is supplied, this may be None.
50
+
51
+ Notes
52
+ -----
53
+ - Most high-level list/report methods accept an `output_format` and an optional `output_format_set` and
54
+ delegate rendering to `pyegeria.output_formatter.generate_output` along with shared helpers such as
55
+ `populate_common_columns`.
56
+ - Private extractor methods follow the convention: `_extract_<entity>_properties(element, columns_struct)` and
57
+ must return the same `columns_struct` with per-column `value` fields populated.
45
58
  """
46
59
 
47
60
  def __init__(
@@ -88,28 +101,12 @@ class ProjectManager(Client2):
88
101
  'properties': props,
89
102
  'elementHeader': element.get('elementHeader', {}),
90
103
  }
91
- col_data = populate_columns_from_properties(element, columns_struct)
92
- # col_data = populate_columns_from_properties(normalized, columns_struct)
104
+ # Common population pipeline
105
+ col_data = populate_common_columns(element, columns_struct)
93
106
  columns_list = col_data.get('formats', {}).get('columns', [])
94
- header_props = _extract_referenceable_properties(element)
95
- # Populate requested relationship-based columns generically
96
- col_data = get_required_relationships(element, col_data)
97
- additional_props = self._extract_additional_project_properties(element, columns_struct)
98
- guid = header_props.get('GUID')
99
-
100
- for column in columns_list:
101
- key = column.get('key')
102
- if key in header_props:
103
- column['value'] = header_props.get(key)
104
- elif key == 'project_roles':
105
- column['value'] = additional_props.get('project_roles', '')
106
- elif isinstance(key, str) and key.lower() == 'guid':
107
- column['value'] = guid
108
-
109
- for column in columns_list:
110
- if column.get('key') == 'mermaid' and not column.get('value'):
111
- column['value'] = element.get('mermaidGraph', '') or ''
112
- break
107
+ # Overlay extras (project roles) only where empty
108
+ extra = self._extract_additional_project_properties(element, columns_struct)
109
+ col_data = overlay_additional_values(col_data, extra)
113
110
  return col_data
114
111
 
115
112