pyegeria 5.4.0.22__py3-none-any.whl → 5.4.0.24__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.
- commands/cat/.DS_Store +0 -0
- commands/cat/.env +8 -0
- commands/cat/debug_log +2046 -465
- commands/cat/debug_log.2025-08-15_09-14-07_444802.zip +0 -0
- commands/cat/debug_log.2025-08-16_10-21-59_388912.zip +0 -0
- commands/cat/debug_log.log +0 -0
- commands/cat/dr_egeria_md.py +16 -3
- commands/cat/list_collections.py +15 -6
- commands/cat/list_format_set.py +90 -85
- commands/cli/debug_log.log +0 -0
- commands/ops/logs/pyegeria.log +0 -0
- md_processing/.DS_Store +0 -0
- md_processing/__init__.py +5 -3
- md_processing/data/commands.json +8310 -903
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-30-37.md +163 -0
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-35-58.md +474 -0
- md_processing/dr_egeria_inbox/Derive-Dr-Gov-Defs.md +8 -0
- md_processing/dr_egeria_inbox/Dr.Egeria Templates.md +873 -0
- md_processing/dr_egeria_inbox/arch_test.md +57 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +254 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +696 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +254 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +298 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +608 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +94 -0
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +284 -0
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +275 -0
- md_processing/dr_egeria_inbox/archive/test-term.md +110 -0
- md_processing/dr_egeria_inbox/cat_test.md +100 -0
- md_processing/dr_egeria_inbox/collections.md +39 -0
- md_processing/dr_egeria_inbox/data_designer_debug.log +6 -0
- md_processing/dr_egeria_inbox/data_designer_out.md +60 -0
- md_processing/dr_egeria_inbox/data_designer_search_test.md +11 -0
- md_processing/dr_egeria_inbox/data_field.md +54 -0
- md_processing/dr_egeria_inbox/data_spec.md +77 -0
- md_processing/dr_egeria_inbox/data_spec_test.md +2406 -0
- md_processing/dr_egeria_inbox/data_test.md +179 -0
- md_processing/dr_egeria_inbox/data_test2.md +429 -0
- md_processing/dr_egeria_inbox/data_test3.md +462 -0
- md_processing/dr_egeria_inbox/dr_egeria_data_designer_1.md +124 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +168 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +280 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +313 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +1073 -0
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +44 -0
- md_processing/dr_egeria_inbox/generated_help_report.md +9 -0
- md_processing/dr_egeria_inbox/glossary_list.md +5 -0
- md_processing/dr_egeria_inbox/glossary_search_test.md +40 -0
- md_processing/dr_egeria_inbox/glossary_test1.md +324 -0
- md_processing/dr_egeria_inbox/gov_def.md +482 -0
- md_processing/dr_egeria_inbox/gov_def2.md +447 -0
- md_processing/dr_egeria_inbox/img.png +0 -0
- md_processing/dr_egeria_inbox/product.md +162 -0
- md_processing/dr_egeria_inbox/rel.md +8 -0
- md_processing/dr_egeria_inbox/sb.md +119 -0
- md_processing/dr_egeria_inbox/solution-components.md +136 -0
- md_processing/dr_egeria_inbox/solution_blueprints.md +118 -0
- md_processing/dr_egeria_inbox/synonym_test.md +42 -0
- md_processing/dr_egeria_inbox/t2.md +268 -0
- md_processing/dr_egeria_outbox/.obsidian/app.json +1 -0
- md_processing/dr_egeria_outbox/.obsidian/appearance.json +1 -0
- md_processing/dr_egeria_outbox/.obsidian/community-plugins.json +6 -0
- md_processing/dr_egeria_outbox/.obsidian/core-plugins.json +31 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/data.json +10 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/main.js +4459 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/manifest.json +10 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/data.json +3 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/main.js +153 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/manifest.json +11 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/styles.css +1 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/main.js +500 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +12 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/styles.css +1 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/main.js +37 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/manifest.json +11 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/styles.css +220 -0
- md_processing/dr_egeria_outbox/.obsidian/types.json +28 -0
- md_processing/dr_egeria_outbox/.obsidian/workspace.json +220 -0
- md_processing/dr_egeria_outbox/Untitled.canvas +1 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +2744 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +62 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +444 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-08-17 21:04-product.md +97 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 14:55-product.md +77 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:05-product.md +75 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:11-product.md +74 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 20:40-collections.md +49 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:08-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:10-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:53-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:54-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:03-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:06-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:10-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 14:27-gov_def2.md +485 -0
- md_processing/md_commands/governance_officer_commands.py +291 -150
- md_processing/md_commands/product_manager_commands.py +309 -401
- md_processing/md_processing_utils/common_md_proc_utils.py +110 -7
- md_processing/md_processing_utils/common_md_utils.py +112 -26
- md_processing/md_processing_utils/debug_log.log +0 -0
- md_processing/md_processing_utils/md_processing_constants.py +8 -5
- md_processing/md_processing_utils/solution_architect_log.log +0 -0
- pyegeria/.DS_Store +0 -0
- pyegeria/__init__.py +3 -3
- pyegeria/_client_new.py +48 -51
- pyegeria/_exceptions_new.py +6 -0
- pyegeria/_output_format_models.py +22 -17
- pyegeria/_output_formats.py +122 -34
- pyegeria/collection_manager.py +154 -50
- pyegeria/collection_manager_omvs.py +47 -18
- pyegeria/egeria_cat_client.py +1 -1
- pyegeria/egeria_client.py +6 -0
- pyegeria/egeria_tech_client.py +6 -1
- pyegeria/governance_officer.py +2513 -0
- pyegeria/load_config.py +1 -1
- pyegeria/models.py +48 -5
- pyegeria/output_formatter.py +298 -79
- pyegeria/utils.py +1 -1
- {pyegeria-5.4.0.22.dist-info → pyegeria-5.4.0.24.dist-info}/METADATA +1 -1
- {pyegeria-5.4.0.22.dist-info → pyegeria-5.4.0.24.dist-info}/RECORD +130 -30
- {pyegeria-5.4.0.22.dist-info → pyegeria-5.4.0.24.dist-info}/LICENSE +0 -0
- {pyegeria-5.4.0.22.dist-info → pyegeria-5.4.0.24.dist-info}/WHEEL +0 -0
- {pyegeria-5.4.0.22.dist-info → pyegeria-5.4.0.24.dist-info}/entry_points.txt +0 -0
pyegeria/_client_new.py
CHANGED
@@ -476,7 +476,8 @@ class Client2:
|
|
476
476
|
except (HTTPStatusError, httpx.HTTPStatusError, httpx.RequestError) as e:
|
477
477
|
# context["caught_exception"] = e
|
478
478
|
# context['HTTPStatusCode'] = e.response.status_code
|
479
|
-
additional_info = {"userid": self.user_id}
|
479
|
+
additional_info = {"userid": self.user_id, "reason": response.text}
|
480
|
+
|
480
481
|
raise PyegeriaClientException(response, context, additional_info, e)
|
481
482
|
#
|
482
483
|
# except json.JSONDecodeError as e:
|
@@ -736,20 +737,20 @@ class Client2:
|
|
736
737
|
return elements
|
737
738
|
|
738
739
|
def validate_new_element_request(self, body: dict | NewElementRequestBody,
|
739
|
-
prop: str) -> NewElementRequestBody | None:
|
740
|
+
prop: list[str]) -> NewElementRequestBody | None:
|
740
741
|
if isinstance(body, NewElementRequestBody):
|
741
|
-
if body.properties.class_
|
742
|
-
|
743
|
-
else:
|
744
|
-
|
745
|
-
|
742
|
+
# if body.properties.class_ in prop:
|
743
|
+
validated_body = body
|
744
|
+
# else:
|
745
|
+
# raise PyegeriaInvalidParameterException(additional_info=
|
746
|
+
# {"reason": "unexpected property class name"})
|
746
747
|
|
747
748
|
elif isinstance(body, dict):
|
748
|
-
if body.get("properties", {}).get("class", "") == prop:
|
749
|
-
|
750
|
-
else:
|
751
|
-
|
752
|
-
|
749
|
+
# if body.get("properties", {}).get("class", "") == prop:
|
750
|
+
validated_body = self._new_element_request_adapter.validate_python(body)
|
751
|
+
# else:
|
752
|
+
# raise PyegeriaInvalidParameterException(additional_info=
|
753
|
+
# {"reason": "unexpected property class name"})
|
753
754
|
else:
|
754
755
|
return None
|
755
756
|
return validated_body
|
@@ -780,12 +781,12 @@ class Client2:
|
|
780
781
|
validated_body = body
|
781
782
|
elif isinstance(body, dict):
|
782
783
|
validated_body = self._delete_request_adapter.validate_python(body)
|
783
|
-
else:
|
784
|
+
else: # handle case where body not provided
|
784
785
|
body= {
|
785
786
|
"class": "DeleteRequestBody",
|
786
787
|
"cascadeDelete": cascade_delete
|
787
788
|
}
|
788
|
-
validated_body= DeleteRequestBody.
|
789
|
+
validated_body= DeleteRequestBody.model_validate(body)
|
789
790
|
return validated_body
|
790
791
|
|
791
792
|
def validate_update_element_request(self, body: dict | UpdateElementRequestBody,
|
@@ -798,17 +799,17 @@ class Client2:
|
|
798
799
|
{"reason": "unexpected property class name"})
|
799
800
|
|
800
801
|
elif isinstance(body, dict):
|
801
|
-
if body.get("properties", {}).get("class", "") in prop:
|
802
|
-
|
803
|
-
else:
|
804
|
-
|
805
|
-
|
802
|
+
# if body.get("properties", {}).get("class", "") in prop:
|
803
|
+
validated_body = self._update_element_request_adapter.validate_python(body)
|
804
|
+
# else:
|
805
|
+
# raise PyegeriaInvalidParameterException(additional_info=
|
806
|
+
# {"reason": "unexpected property class name"})
|
806
807
|
else:
|
807
808
|
validated_body = None
|
808
809
|
return validated_body
|
809
810
|
|
810
811
|
def validate_update_status_request(self, status: str = None, body: dict | UpdateStatusRequestBody = None,
|
811
|
-
prop: str = None) -> UpdateStatusRequestBody | None:
|
812
|
+
prop: list[str] = None) -> UpdateStatusRequestBody | None:
|
812
813
|
if isinstance(body, UpdateStatusRequestBody):
|
813
814
|
validated_body = body
|
814
815
|
|
@@ -820,33 +821,34 @@ class Client2:
|
|
820
821
|
"class": "UpdateStatusRequestBody",
|
821
822
|
"status": status
|
822
823
|
}
|
823
|
-
validated_body = UpdateStatusRequestBody.
|
824
|
+
validated_body = UpdateStatusRequestBody.model_validate(body)
|
824
825
|
else:
|
825
826
|
raise PyegeriaInvalidParameterException(additional_info={"reason": "invalid parameters"})
|
826
827
|
|
827
828
|
return validated_body
|
828
829
|
|
829
830
|
def validate_update_relationship_request(self, body: dict | UpdateRelationshipRequestBody,
|
830
|
-
prop: str) -> UpdateRelationshipRequestBody | None:
|
831
|
+
prop: [str]) -> UpdateRelationshipRequestBody | None:
|
831
832
|
if isinstance(body, UpdateRelationshipRequestBody):
|
832
|
-
if body.properties.class_ == prop:
|
833
|
-
|
834
|
-
else:
|
835
|
-
|
836
|
-
|
833
|
+
# if body.properties.class_ == prop:
|
834
|
+
validated_body = body
|
835
|
+
# else:
|
836
|
+
# raise PyegeriaInvalidParameterException(additional_info=
|
837
|
+
# {"reason": "unexpected property class name"})
|
837
838
|
|
838
839
|
elif isinstance(body, dict):
|
839
|
-
if body.get("properties", {}).get("class", "") == prop:
|
840
|
-
|
841
|
-
else:
|
842
|
-
|
843
|
-
|
840
|
+
# if body.get("properties", {}).get("class", "") == prop:
|
841
|
+
validated_body = self._update_relationship_request_adapter.validate_python(body)
|
842
|
+
# else:
|
843
|
+
# raise PyegeriaInvalidParameterException(additional_info=
|
844
|
+
# {"reason": "unexpected property class name"})
|
844
845
|
else:
|
845
846
|
validated_body = None
|
846
847
|
return validated_body
|
847
848
|
|
848
849
|
async def _async_find_request(self, url: str, _type: str, _gen_output: Callable[..., Any],
|
849
850
|
search_string: str = '*', classification_names: list[str] = None,
|
851
|
+
metadata_element_types: list[str] = None,
|
850
852
|
starts_with: bool = True, ends_with: bool = False, ignore_case: bool = False,
|
851
853
|
start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
|
852
854
|
output_format_set: str | dict = None,
|
@@ -867,13 +869,14 @@ class Client2:
|
|
867
869
|
"start_from": start_from,
|
868
870
|
"page_size": page_size,
|
869
871
|
"include_only_classified_elements": classification_names,
|
872
|
+
"metadata_element_subtype_names": metadata_element_types,
|
870
873
|
}
|
871
874
|
validated_body = SearchStringRequestBody.model_validate(body)
|
872
875
|
|
873
|
-
classification_names = validated_body.include_only_classified_elements
|
874
|
-
|
876
|
+
# classification_names = validated_body.include_only_classified_elements
|
877
|
+
# element_type_name = classification_names[0] if classification_names else _type
|
875
878
|
|
876
|
-
json_body = validated_body.model_dump_json(indent=2)
|
879
|
+
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
877
880
|
|
878
881
|
response = await self._async_make_request("POST", url, json_body)
|
879
882
|
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
@@ -883,7 +886,7 @@ class Client2:
|
|
883
886
|
|
884
887
|
if output_format != 'JSON': # return a simplified markdown representation
|
885
888
|
# logger.info(f"Found elements, output format: {output_format} and output_format_set: {output_format_set}")
|
886
|
-
return _gen_output(elements, search_string,
|
889
|
+
return _gen_output(elements, search_string, _type,
|
887
890
|
output_format, output_format_set)
|
888
891
|
return elements
|
889
892
|
|
@@ -908,8 +911,8 @@ class Client2:
|
|
908
911
|
}
|
909
912
|
validated_body = FilterRequestBody.model_validate(body)
|
910
913
|
|
911
|
-
classification_names = validated_body.include_only_classified_elements
|
912
|
-
|
914
|
+
# classification_names = validated_body.include_only_classified_elements
|
915
|
+
# element_type_name = classification_names[0] if classification_names else _type
|
913
916
|
|
914
917
|
json_body = validated_body.model_dump_json(indent=2)
|
915
918
|
|
@@ -921,7 +924,7 @@ class Client2:
|
|
921
924
|
|
922
925
|
if output_format != 'JSON': # return a simplified markdown representation
|
923
926
|
logger.info(f"Found elements, output format: {output_format} and output_format_set: {output_format_set}")
|
924
|
-
return _gen_output(elements, filter_string,
|
927
|
+
return _gen_output(elements, filter_string, _type,
|
925
928
|
output_format, output_format_set)
|
926
929
|
return elements
|
927
930
|
|
@@ -972,7 +975,10 @@ class Client2:
|
|
972
975
|
json_body = validated_body.model_dump_json(indent=2)
|
973
976
|
|
974
977
|
response = await self._async_make_request("POST", url, json_body)
|
975
|
-
elements = response.json().get("elements",
|
978
|
+
elements = response.json().get("elements", None)
|
979
|
+
if elements is None:
|
980
|
+
elements = response.json().get("element", NO_ELEMENTS_FOUND)
|
981
|
+
|
976
982
|
if type(elements) is str:
|
977
983
|
logger.info(NO_ELEMENTS_FOUND)
|
978
984
|
return NO_ELEMENTS_FOUND
|
@@ -983,7 +989,7 @@ class Client2:
|
|
983
989
|
output_format, output_format_set)
|
984
990
|
return elements
|
985
991
|
|
986
|
-
async def _async_create_element_body_request(self, url: str, prop: str,
|
992
|
+
async def _async_create_element_body_request(self, url: str, prop: list[str],
|
987
993
|
body: dict | NewElementRequestBody = None) -> str:
|
988
994
|
validated_body = self.validate_new_element_request(body, prop)
|
989
995
|
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
@@ -1008,7 +1014,7 @@ class Client2:
|
|
1008
1014
|
response = await self._async_make_request("POST", url, json_body)
|
1009
1015
|
logger.info(response.json())
|
1010
1016
|
|
1011
|
-
async def _async_new_relationship_request(self, url: str, prop: str,
|
1017
|
+
async def _async_new_relationship_request(self, url: str, prop: list[str],
|
1012
1018
|
body: dict | NewRelationshipRequestBody = None) -> None:
|
1013
1019
|
validated_body = self.validate_new_relationship_request(body, prop)
|
1014
1020
|
if validated_body:
|
@@ -1029,15 +1035,6 @@ class Client2:
|
|
1029
1035
|
await self._async_make_request("POST", url)
|
1030
1036
|
|
1031
1037
|
|
1032
|
-
async def _async_new_relationship_request(self, url: str, prop: str,
|
1033
|
-
body: dict | NewRelationshipRequestBody = None) -> None:
|
1034
|
-
validated_body = self.validate_new_relationship_request(body, prop)
|
1035
|
-
if validated_body:
|
1036
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
1037
|
-
logger.info(json_body)
|
1038
|
-
await self._async_make_request("POST", url, json_body)
|
1039
|
-
else:
|
1040
|
-
await self._async_make_request("POST", url)
|
1041
1038
|
|
1042
1039
|
|
1043
1040
|
|
pyegeria/_exceptions_new.py
CHANGED
@@ -374,6 +374,11 @@ def print_exception_table(e: PyegeriaException):
|
|
374
374
|
def print_basic_exception(e: PyegeriaException):
|
375
375
|
"""Prints the exception response"""
|
376
376
|
related_code = e.related_http_code if hasattr(e, "related_http_code") else ""
|
377
|
+
http_reason = e.response.text if e.response else ""
|
378
|
+
table = Table(title=f"Exception: {e.__class__.__name__}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
|
379
|
+
table.caption = e.pyegeria_code
|
380
|
+
table.add_column("Facet", justify="center")
|
381
|
+
table.add_column("Item", justify="left", width=80)
|
377
382
|
related_response = e.response.json() if e.response else ""
|
378
383
|
table = Table(title=f"Exception: {e.__class__.__name__}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
|
379
384
|
table.caption = e.pyegeria_code
|
@@ -382,6 +387,7 @@ def print_basic_exception(e: PyegeriaException):
|
|
382
387
|
|
383
388
|
if isinstance(e, PyegeriaException):
|
384
389
|
table.add_row("HTTP Code", str(e.response_code))
|
390
|
+
table.add_row("HTTP Reason", str(http_reason))
|
385
391
|
table.add_row("Egeria Code", str(related_code))
|
386
392
|
table.add_row("Caller Method", e.context.get("caller method", "---")) if e.context else ""
|
387
393
|
table.add_row("Request URL", str(e.response_url))
|
@@ -175,14 +175,16 @@ class FormatSet(BaseModel):
|
|
175
175
|
aliases: Alternative names that can be used to reference this format set
|
176
176
|
annotations: Additional metadata, like wiki links
|
177
177
|
formats: A list of format configurations
|
178
|
-
action: Optional
|
178
|
+
action: Optional action associated with the format set
|
179
|
+
get_additional_props: Optional action used to retrieve additional properties for a format set
|
179
180
|
"""
|
180
181
|
heading: str
|
181
182
|
description: str
|
182
183
|
aliases: List[str] = Field(default_factory=list)
|
183
184
|
annotations: Dict[str, List[str]] = Field(default_factory=dict)
|
184
185
|
formats: List[Union[Format, Dict[str, Any]]]
|
185
|
-
action: Optional[
|
186
|
+
action: Optional[Union[ActionParameter, Dict[str, Any]]] = None
|
187
|
+
get_additional_props: Optional[Union[ActionParameter, Dict[str, Any]]] = None
|
186
188
|
|
187
189
|
@validator('formats', pre=True)
|
188
190
|
def validate_formats(cls, v):
|
@@ -195,18 +197,20 @@ class FormatSet(BaseModel):
|
|
195
197
|
result.append(item)
|
196
198
|
return result
|
197
199
|
|
198
|
-
@validator('action', pre=True)
|
199
|
-
def
|
200
|
-
"""Convert dictionary
|
200
|
+
@validator('action', 'get_additional_props', pre=True)
|
201
|
+
def validate_action_like(cls, v):
|
202
|
+
"""Convert dictionary action-like fields to ActionParameter objects. Accepts legacy list shape."""
|
201
203
|
if v is None:
|
202
204
|
return None
|
203
|
-
|
204
|
-
|
205
|
-
if
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
205
|
+
# Backward compatibility: if a list is provided, use the first element
|
206
|
+
if isinstance(v, list):
|
207
|
+
if not v:
|
208
|
+
return None
|
209
|
+
logger.warning("FormatSet.action/get_additional_props provided as a list; coercing first element to dict. This shape is deprecated.")
|
210
|
+
v = v[0]
|
211
|
+
if isinstance(v, dict):
|
212
|
+
return ActionParameter(**v)
|
213
|
+
return v
|
210
214
|
|
211
215
|
def dict(self, *args, **kwargs):
|
212
216
|
"""Override dict method to convert nested objects back to dictionaries."""
|
@@ -215,11 +219,12 @@ class FormatSet(BaseModel):
|
|
215
219
|
format if isinstance(format, dict) else format.dict()
|
216
220
|
for format in self.formats
|
217
221
|
]
|
218
|
-
if self.action:
|
219
|
-
result['action'] =
|
220
|
-
|
221
|
-
|
222
|
-
|
222
|
+
if self.action is not None:
|
223
|
+
result['action'] = self.action if isinstance(self.action, dict) else self.action.dict()
|
224
|
+
if self.get_additional_props is not None:
|
225
|
+
result['get_additional_props'] = (
|
226
|
+
self.get_additional_props if isinstance(self.get_additional_props, dict) else self.get_additional_props.dict()
|
227
|
+
)
|
223
228
|
return result
|
224
229
|
|
225
230
|
def get(self, key, default=None):
|
pyegeria/_output_formats.py
CHANGED
@@ -70,9 +70,11 @@ from pathlib import Path
|
|
70
70
|
from typing import Dict, List, Optional, Union, Any
|
71
71
|
from loguru import logger
|
72
72
|
|
73
|
-
from pyegeria._output_format_models import Column, Format, ActionParameter, FormatSet, FormatSetDict,
|
73
|
+
from pyegeria._output_format_models import (Column, Format, ActionParameter, FormatSet, FormatSetDict,
|
74
|
+
save_format_sets_to_json, load_format_sets_from_json)
|
74
75
|
from pyegeria.load_config import get_app_config
|
75
76
|
|
77
|
+
|
76
78
|
# Get the configured value for the user format sets directory
|
77
79
|
app_config = get_app_config()
|
78
80
|
USER_FORMAT_SETS_DIR = os.path.expanduser(app_config.Environment.pyegeria_user_format_sets_dir)
|
@@ -90,6 +92,7 @@ COMMON_COLUMNS = [
|
|
90
92
|
|
91
93
|
COMMON_METADATA_COLUMNS = [
|
92
94
|
Column(name='GUID', key='guid', format=True),
|
95
|
+
Column(name='Type Name', key='type_name'),
|
93
96
|
Column(name='Metadata Collection ID', key='metadata_collection_id', format=True),
|
94
97
|
Column(name='Metadata Collection Name', key='metadata_collection_name', format=True),
|
95
98
|
]
|
@@ -120,6 +123,8 @@ COMMON_FORMATS_ALL = Format(
|
|
120
123
|
|
121
124
|
|
122
125
|
COLLECTIONS_COLUMNS = COMMON_COLUMNS + [
|
126
|
+
Column(name='Type Name', key='type_name'),
|
127
|
+
Column(name='Classifications', key='classifications'),
|
123
128
|
Column(name="Created By", key='created_by'),
|
124
129
|
Column(name="Create Time", key='create_time'),
|
125
130
|
Column(name="Updated By", key='updated_by'),
|
@@ -127,31 +132,71 @@ COLLECTIONS_COLUMNS = COMMON_COLUMNS + [
|
|
127
132
|
]
|
128
133
|
|
129
134
|
COLLECTIONS_MEMBERS_COLUMNS = COLLECTIONS_COLUMNS + [
|
130
|
-
Column(name="Members", key='
|
135
|
+
Column(name="Containing Members", key='collection_members'),
|
136
|
+
Column(name="Member Of", key='member_of_collections')
|
131
137
|
]
|
132
138
|
|
133
139
|
COLLECTION_DICT = Format(
|
134
140
|
types=["DICT"],
|
135
|
-
columns=
|
141
|
+
columns=COLLECTIONS_MEMBERS_COLUMNS + [
|
142
|
+
Column(name="GUID", key='GUID'),
|
143
|
+
],
|
144
|
+
)
|
145
|
+
|
146
|
+
COLLECTION_REPORT = Format(
|
147
|
+
types=["REPORT"],
|
148
|
+
columns=COLLECTIONS_MEMBERS_COLUMNS + [
|
149
|
+
Column(name="GUID", key='GUID'),
|
150
|
+
Column(name="Mermaid", key='mermaid'),
|
151
|
+
],
|
136
152
|
)
|
137
153
|
|
138
154
|
COLLECTION_TABLE = Format(
|
139
155
|
types=["TABLE"],
|
140
|
-
columns=
|
156
|
+
columns=COLLECTIONS_MEMBERS_COLUMNS,
|
141
157
|
)
|
142
158
|
|
143
159
|
GOVERNANCE_DEFINITIONS_COLUMNS = COMMON_COLUMNS + [
|
144
|
-
Column(name="
|
145
|
-
Column(name="
|
160
|
+
Column(name="Summary", key='summary'),
|
161
|
+
Column(name="Usage", key='usage'),
|
162
|
+
Column(name="Importance", key='importance'),
|
146
163
|
Column(name="Scope", key='scope'),
|
164
|
+
Column(name="Type", key='type_name'),
|
165
|
+
]
|
166
|
+
GOVERNANCE_DEFINITIONS_BASIC = [
|
167
|
+
Column(name="Type", key='type_name'),
|
168
|
+
Column(name='Qualified Name', key='qualified_name', format=True),
|
169
|
+
Column(name="GUID", key='guid', format=True),
|
147
170
|
]
|
148
|
-
|
149
171
|
COMMON_ANNOTATIONS = {
|
150
172
|
"wikilinks": ["[[Commons]]"]
|
151
173
|
}
|
152
174
|
|
153
175
|
# Modularized output_format_sets
|
154
176
|
output_format_sets = FormatSetDict({
|
177
|
+
"Default": FormatSet(
|
178
|
+
heading="Default Base Attributes",
|
179
|
+
description="Was a valid combination of output_format_set and output_format provided?",
|
180
|
+
annotations={}, # No specific annotations
|
181
|
+
formats=[
|
182
|
+
Format(
|
183
|
+
types=["ALL"],
|
184
|
+
columns=COMMON_COLUMNS + COMMON_METADATA_COLUMNS + [
|
185
|
+
Column(name='Version Identifier', key='version_identifier'),
|
186
|
+
Column(name="Classifications", key='classifications'),
|
187
|
+
Column(name="Additional Properties", key='additional_properties'),
|
188
|
+
Column(name="Created By", key='created_by'),
|
189
|
+
Column(name="Create Time", key='create_time'),
|
190
|
+
Column(name="Updated By", key='updated_by'),
|
191
|
+
Column(name="Update Time", key='update_time'),
|
192
|
+
Column(name="Effective From", key='effective_from'),
|
193
|
+
Column(name="Effective To", key='effective_to'),
|
194
|
+
Column(name="Version", key='version'),
|
195
|
+
Column(name="Open Metadata Type Name", key='type_name'),
|
196
|
+
],
|
197
|
+
)
|
198
|
+
],
|
199
|
+
),
|
155
200
|
"Referenceable": FormatSet(
|
156
201
|
heading="Common Attributes",
|
157
202
|
description="Attributes that apply to all Referenceables.",
|
@@ -205,12 +250,12 @@ output_format_sets = FormatSetDict({
|
|
205
250
|
aliases=["Collection", "RootCollection", "Folder", "ReferenceList", "HomeCollection",
|
206
251
|
"ResultSet", "RecentAccess", "WorkItemList", "Namespace"],
|
207
252
|
annotations=COMMON_ANNOTATIONS,
|
208
|
-
formats=[COLLECTION_DICT, COLLECTION_TABLE, COMMON_FORMATS_ALL], # Reusing common formats
|
209
|
-
action=
|
253
|
+
formats=[COLLECTION_DICT, COLLECTION_TABLE, COLLECTION_REPORT, COMMON_FORMATS_ALL], # Reusing common formats
|
254
|
+
action=ActionParameter(
|
210
255
|
function="CollectionManager.find_collections",
|
211
256
|
user_params=["search_string"],
|
212
257
|
spec_params={},
|
213
|
-
)
|
258
|
+
)
|
214
259
|
),
|
215
260
|
|
216
261
|
"CollectionMembers": FormatSet(
|
@@ -219,11 +264,11 @@ output_format_sets = FormatSetDict({
|
|
219
264
|
aliases=["CollectionMember", "Member", "Members"],
|
220
265
|
annotations= {"wikilinks": ["[[CollectionMembers]]"]},
|
221
266
|
formats = [COLLECTION_DICT, COLLECTION_TABLE],
|
222
|
-
action=
|
267
|
+
action=ActionParameter(
|
223
268
|
function="CollectionManager.get_collection_members",
|
224
269
|
user_params=["collection_guid"],
|
225
270
|
spec_params={"output_format": "DICT"},
|
226
|
-
)
|
271
|
+
)
|
227
272
|
),
|
228
273
|
"DigitalProducts": FormatSet(
|
229
274
|
heading="Digital Product Information",
|
@@ -232,7 +277,7 @@ output_format_sets = FormatSetDict({
|
|
232
277
|
annotations={},
|
233
278
|
formats=[
|
234
279
|
Format(
|
235
|
-
types=["REPORT"],
|
280
|
+
types=["REPORT", "DICT", "TABLE"],
|
236
281
|
columns=COMMON_COLUMNS + [
|
237
282
|
Column(name="Status", key='status'),
|
238
283
|
Column(name='Product Name', key='product_name'),
|
@@ -242,35 +287,65 @@ output_format_sets = FormatSetDict({
|
|
242
287
|
Column(name='Next Version', key='next_version'),
|
243
288
|
Column(name='Withdraw Date', key='withdraw_date'),
|
244
289
|
Column(name='Members', key='members', format=True),
|
290
|
+
Column(name='Uses Products', key='uses_digital_products'),
|
291
|
+
Column(name='Used by Products', key='used_by_digital_products'),
|
245
292
|
],
|
246
293
|
)
|
247
294
|
],
|
248
|
-
action=
|
295
|
+
action=ActionParameter(
|
249
296
|
function="CollectionManager.find_collections",
|
250
297
|
user_params=["search_string"],
|
251
|
-
spec_params={
|
252
|
-
)
|
298
|
+
spec_params={},
|
299
|
+
),
|
300
|
+
get_additional_props=ActionParameter(
|
301
|
+
function="CollectionManager._extract_digital_product_properties",
|
302
|
+
user_params = [],
|
303
|
+
spec_params={},
|
304
|
+
)
|
253
305
|
),
|
254
306
|
|
255
307
|
"Agreements": FormatSet(
|
256
308
|
heading="General Agreement Information",
|
257
309
|
description="Attributes generic to all Agreements.",
|
258
|
-
aliases=["DataSharingAgreement"],
|
310
|
+
aliases=["DataSharingAgreement", "Agreement"],
|
259
311
|
annotations={"wikilinks": ["[[Agreements]]", "[[Egeria]]"]},
|
260
|
-
formats=[
|
312
|
+
formats=[
|
313
|
+
Format(
|
314
|
+
types=["REPORT", "DICT", "TABLE"],
|
315
|
+
columns=COMMON_COLUMNS + COMMON_HEADER_COLUMNS + [
|
316
|
+
Column(name='Identifier', key='identifier'),
|
317
|
+
Column(name='Support Level', key='support_level'),
|
318
|
+
Column(name='service Levels', key='service_levels'),
|
319
|
+
Column(name='Agreement Items', key='agreement_items', format=True),
|
320
|
+
Column(name='Members', key='members', format=True),
|
321
|
+
]
|
322
|
+
)
|
323
|
+
],
|
324
|
+
action=ActionParameter(
|
325
|
+
function="CollectionManager.find_collections",
|
326
|
+
user_params=["search_string"],
|
327
|
+
spec_params={"metadata_element_types": ["Agreement"]},
|
328
|
+
# spec_params={},
|
329
|
+
),
|
330
|
+
get_additional_props=ActionParameter(
|
331
|
+
function="CollectionManager._extract_agreement_properties",
|
332
|
+
user_params=[],
|
333
|
+
spec_params={},
|
334
|
+
),
|
261
335
|
),
|
262
336
|
|
337
|
+
|
263
338
|
"DataDictionary": FormatSet(
|
264
339
|
heading="Data Dictionary Information",
|
265
340
|
description="Attributes useful to Data Dictionary.",
|
266
341
|
aliases=["Data Dict", "Data Dictionary"],
|
267
342
|
annotations={"wikilinks": ["[[Data Dictionary]]"]},
|
268
343
|
formats=[COMMON_FORMATS_ALL], # Reusing common formats and columns
|
269
|
-
action=
|
344
|
+
action=ActionParameter(
|
270
345
|
function="CollectionManager.find_collections",
|
271
346
|
user_params=["search_string"],
|
272
347
|
spec_params={"initial_classifications": "DataDictionary"},
|
273
|
-
)
|
348
|
+
)
|
274
349
|
),
|
275
350
|
|
276
351
|
"Data Specification": FormatSet(
|
@@ -285,11 +360,11 @@ output_format_sets = FormatSetDict({
|
|
285
360
|
Column(name="Mermaid", key='mermaid'),
|
286
361
|
]),
|
287
362
|
Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
288
|
-
action=
|
363
|
+
action=ActionParameter(
|
289
364
|
function="CollectionManager.find_collections",
|
290
365
|
user_params=["search_string"],
|
291
366
|
spec_params={"initial_classifications": "DataSpec"},
|
292
|
-
)
|
367
|
+
)
|
293
368
|
),
|
294
369
|
|
295
370
|
"DataStruct": FormatSet(
|
@@ -298,11 +373,11 @@ output_format_sets = FormatSetDict({
|
|
298
373
|
aliases=["Data Structure", "DataStructures", "Data Structures", "Data Struct", "DataStructure"],
|
299
374
|
annotations={"wikilinks": ["[[Data Structure]]"]},
|
300
375
|
formats=[Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
301
|
-
action=
|
376
|
+
action=ActionParameter(
|
302
377
|
function="DataDesigner.find_data_structures",
|
303
378
|
user_params=["search_string"],
|
304
379
|
spec_params={},
|
305
|
-
)
|
380
|
+
)
|
306
381
|
),
|
307
382
|
|
308
383
|
"DataField": FormatSet(
|
@@ -311,11 +386,11 @@ output_format_sets = FormatSetDict({
|
|
311
386
|
aliases=["Data Field", "Data Fields", "DataFields"],
|
312
387
|
annotations={"wikilinks": ["[[Data Field]]"]},
|
313
388
|
formats=[Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
314
|
-
action=
|
389
|
+
action=ActionParameter(
|
315
390
|
function="DataDesigner.find_data_fields",
|
316
391
|
user_params=["search_string"],
|
317
392
|
spec_params={},
|
318
|
-
)
|
393
|
+
)
|
319
394
|
),
|
320
395
|
|
321
396
|
"Mandy-DataStruct": FormatSet(
|
@@ -329,24 +404,35 @@ output_format_sets = FormatSetDict({
|
|
329
404
|
Format(types=["REPORT","MERMAID", "HTML"], columns=[Column(name='Display Name', key='display_name'),
|
330
405
|
Column(name='Mermaid', key='mermaid'),]),
|
331
406
|
],
|
332
|
-
action=
|
407
|
+
action=ActionParameter(
|
333
408
|
function="DataDesigner.find_data_structures",
|
334
409
|
user_params=["search_string"],
|
335
410
|
spec_params={"output_format":"DICT"},
|
336
|
-
)
|
411
|
+
)
|
412
|
+
),
|
413
|
+
"Governance Basics": FormatSet(
|
414
|
+
heading="Basic Governance-Definitions Information",
|
415
|
+
description="Core Attributes useful to Governance-Definitions.",
|
416
|
+
aliases=["BasicGovernance"],
|
417
|
+
annotations={"wikilinks": ["[[Governance]]"]},
|
418
|
+
formats=[Format(types=["ALL"], columns=GOVERNANCE_DEFINITIONS_BASIC)],
|
419
|
+
action=ActionParameter(
|
420
|
+
function="GovernanceOfficer.find_governance_definitions",
|
421
|
+
user_params=["search_string"],
|
422
|
+
spec_params={},
|
423
|
+
)
|
337
424
|
),
|
338
|
-
|
339
425
|
"Governance Definitions": FormatSet(
|
340
426
|
heading="Governance-Definitions Information",
|
341
427
|
description="Attributes useful to Governance-Definitions.",
|
342
428
|
aliases=["GovernanceDefinitions"],
|
343
429
|
annotations={"wikilinks": ["[[Governance]]"]},
|
344
430
|
formats=[Format(types=["ALL"], columns=GOVERNANCE_DEFINITIONS_COLUMNS)],
|
345
|
-
action=
|
431
|
+
action=ActionParameter(
|
346
432
|
function="GovernanceOfficer.find_governance_definitions",
|
347
|
-
user_params=["
|
348
|
-
spec_params={
|
349
|
-
)
|
433
|
+
user_params=["search_string"],
|
434
|
+
spec_params={},
|
435
|
+
)
|
350
436
|
),
|
351
437
|
})
|
352
438
|
|
@@ -390,7 +476,9 @@ def select_output_format_set(kind: str, output_type: str) -> dict | None:
|
|
390
476
|
output_struct["annotations"] = element.annotations
|
391
477
|
if element.action:
|
392
478
|
# Convert ActionParameter to dictionary for backward compatibility
|
393
|
-
output_struct["action"] =
|
479
|
+
output_struct["action"] = element.action.dict()
|
480
|
+
if element.get_additional_props:
|
481
|
+
output_struct["get_additional_props"] = element.get_additional_props.dict()
|
394
482
|
|
395
483
|
# If this was just a validation that the format set could be found then the output type is ANY - so just return.
|
396
484
|
if output_type == "ANY":
|