pyegeria 5.2.1.1__py3-none-any.whl → 5.3__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/Dr-Egeria_md-orig.py +166 -0
- commands/cat/__init__.py +23 -0
- commands/cat/dr_egeria_jupyter.py +122 -0
- commands/cat/dr_egeria_md.py +247 -0
- {pyegeria/commands → commands}/cat/exp_list_glossaries.py +3 -4
- {pyegeria/commands → commands}/cat/get_asset_graph.py +4 -4
- {pyegeria/commands → commands}/cat/get_collection.py +8 -9
- {pyegeria/commands → commands}/cat/get_project_dependencies.py +6 -8
- {pyegeria/commands → commands}/cat/get_project_structure.py +6 -8
- {pyegeria/commands → commands}/cat/get_tech_type_elements.py +13 -15
- {pyegeria/commands → commands}/cat/glossary_actions.py +184 -34
- {pyegeria/commands → commands}/cat/list_assets.py +9 -6
- commands/cat/list_categories.py +192 -0
- {pyegeria/commands → commands}/cat/list_cert_types.py +6 -6
- {pyegeria/commands → commands}/cat/list_collections.py +62 -19
- commands/cat/list_data_structures.py +223 -0
- {pyegeria/commands → commands}/cat/list_deployed_catalogs.py +9 -8
- {pyegeria/commands → commands}/cat/list_deployed_database_schemas.py +10 -9
- {pyegeria/commands → commands}/cat/list_deployed_databases.py +9 -8
- pyegeria/commands/cat/list_servers_deployed_imp.py → commands/cat/list_deployed_servers.py +3 -3
- {pyegeria/commands → commands}/cat/list_glossaries.py +57 -15
- {pyegeria/commands → commands}/cat/list_projects.py +5 -5
- {pyegeria/commands → commands}/cat/list_tech_type_elements.py +3 -3
- {pyegeria/commands → commands}/cat/list_tech_types.py +4 -4
- {pyegeria/commands → commands}/cat/list_terms.py +93 -45
- {pyegeria/commands → commands}/cat/list_todos.py +3 -3
- {pyegeria/commands → commands}/cat/list_user_ids.py +9 -8
- {pyegeria/commands → commands}/cli/__init__.py +1 -1
- {pyegeria/commands → commands}/cli/egeria.py +506 -250
- {pyegeria/commands → commands}/cli/egeria_cat.py +127 -50
- {pyegeria/commands → commands}/cli/egeria_login_tui.py +15 -17
- {pyegeria/commands → commands}/cli/egeria_my.py +22 -15
- {pyegeria/commands → commands}/cli/egeria_ops.py +54 -55
- {pyegeria/commands → commands}/cli/egeria_tech.py +364 -152
- {pyegeria/commands → commands}/cli/ops_config.py +11 -4
- commands/cli/txt_custom_v2.tcss +19 -0
- commands/my/__init__.py +22 -0
- {pyegeria/commands → commands}/my/list_my_profile.py +6 -8
- {pyegeria/commands → commands}/my/list_my_roles.py +4 -4
- {pyegeria/commands → commands}/my/monitor_my_todos.py +7 -7
- {pyegeria/commands → commands}/my/monitor_open_todos.py +7 -7
- {pyegeria/commands → commands}/my/todo_actions.py +3 -2
- commands/ops/__init__.py +23 -0
- {pyegeria/commands → commands}/ops/gov_server_actions.py +5 -4
- {pyegeria/commands → commands}/ops/list_archives.py +7 -6
- {pyegeria/commands → commands}/ops/list_catalog_targets.py +4 -4
- {pyegeria/commands → commands}/ops/load_archive.py +4 -2
- {pyegeria/commands → commands}/ops/monitor_asset_events.py +8 -7
- {pyegeria/commands → commands}/ops/monitor_engine_activity.py +5 -5
- {pyegeria/commands → commands}/ops/monitor_engine_activity_c.py +3 -3
- {pyegeria/commands → commands}/ops/monitor_gov_eng_status.py +3 -2
- {pyegeria/commands → commands}/ops/monitor_integ_daemon_status.py +23 -15
- {pyegeria/commands → commands}/ops/monitor_platform_status.py +5 -4
- {pyegeria/commands → commands}/ops/monitor_server_startup.py +7 -7
- {pyegeria/commands → commands}/ops/monitor_server_status.py +16 -11
- {pyegeria/commands → commands}/ops/orig_monitor_server_list.py +2 -2
- {pyegeria/commands → commands}/ops/orig_monitor_server_status.py +3 -3
- {pyegeria/commands → commands}/ops/refresh_integration_daemon.py +4 -4
- {pyegeria/commands → commands}/ops/restart_integration_daemon.py +3 -3
- {pyegeria/commands → commands}/ops/table_integ_daemon_status.py +3 -3
- commands/tech/__init__.py +22 -0
- commands/tech/generic_actions.py +74 -0
- {pyegeria/commands → commands}/tech/get_element_info.py +5 -7
- {pyegeria/commands → commands}/tech/get_guid_info.py +4 -5
- {pyegeria/commands → commands}/tech/get_tech_details.py +8 -9
- {pyegeria/commands → commands}/tech/get_tech_type_template.py +4 -4
- pyegeria/commands/tech/list_elements.py → commands/tech/list_all_om_type_elements.py +11 -10
- pyegeria/commands/tech/list_elements_x.py → commands/tech/list_all_om_type_elements_x.py +11 -12
- pyegeria/commands/tech/list_related_elements.py → commands/tech/list_all_related_elements.py +11 -9
- {pyegeria/commands → commands}/tech/list_anchored_elements.py +16 -16
- {pyegeria/commands → commands}/tech/list_asset_types.py +4 -4
- commands/tech/list_elements_by_classification_by_property_value.py +200 -0
- commands/tech/list_elements_by_property_value.py +180 -0
- commands/tech/list_elements_by_property_value_x.py +201 -0
- {pyegeria/commands → commands}/tech/list_elements_for_classification.py +11 -9
- {pyegeria/commands → commands}/tech/list_gov_action_processes.py +5 -6
- commands/tech/list_information_supply_chains.py +167 -0
- {pyegeria/commands → commands}/tech/list_registered_services.py +3 -3
- commands/tech/list_related_elements_with_prop_value.py +221 -0
- {pyegeria/commands → commands}/tech/list_related_specification.py +3 -3
- {pyegeria/commands → commands}/tech/list_relationship_types.py +4 -5
- {pyegeria/commands → commands}/tech/list_relationships.py +3 -3
- commands/tech/list_solution_blueprints.py +181 -0
- commands/tech/list_solution_components.py +185 -0
- commands/tech/list_solution_roles.py +184 -0
- {pyegeria/commands → commands}/tech/list_tech_templates.py +3 -3
- {pyegeria/commands → commands}/tech/list_valid_metadata_values.py +5 -6
- {pyegeria/commands → commands}/tech/table_tech_templates.py +16 -13
- {pyegeria/commands → commands}/tech/x_list_related_elements.py +6 -4
- md_processing/__init__.py +49 -0
- md_processing/data/commands.json +3252 -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/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 +86 -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/glossary_creation_experiment.ipynb +341 -0
- md_processing/dr_egeria_inbox/glossary_test1.md +324 -0
- md_processing/dr_egeria_inbox/rel.md +8 -0
- md_processing/dr_egeria_inbox/sb.md +119 -0
- md_processing/dr_egeria_inbox/search_test.md +39 -0
- md_processing/dr_egeria_inbox/solution-components.md +154 -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/processed-2025-05-15 19:52-data_test.md +94 -0
- md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +88 -0
- md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +56 -0
- md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +103 -0
- md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +94 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +96 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +100 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +88 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +91 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +91 -0
- md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +91 -0
- md_processing/md_commands/__init__.py +3 -0
- md_processing/md_commands/blueprint_commands.py +303 -0
- md_processing/md_commands/data_designer_commands.py +1182 -0
- md_processing/md_commands/glossary_commands.py +1144 -0
- md_processing/md_commands/project_commands.py +163 -0
- md_processing/md_processing_utils/__init__.py +4 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +724 -0
- md_processing/md_processing_utils/common_md_utils.py +172 -0
- md_processing/md_processing_utils/extraction_utils.py +486 -0
- md_processing/md_processing_utils/md_processing_constants.py +128 -0
- md_processing/md_processing_utils/message_constants.py +19 -0
- pyegeria/.DS_Store +0 -0
- pyegeria/__init__.py +231 -146
- pyegeria/_client.py +36 -13
- pyegeria/_exceptions.py +55 -46
- pyegeria/_globals.py +11 -1
- pyegeria/_validators.py +5 -5
- pyegeria/asset_catalog_omvs.py +78 -21
- pyegeria/automated_curation_omvs.py +11 -6
- pyegeria/classification_manager_omvs.py +41 -37
- pyegeria/collection_manager_omvs.py +722 -705
- pyegeria/core_omag_server_config.py +1 -1
- pyegeria/create_tech_guid_lists.py +13 -13
- pyegeria/data_designer_omvs.py +5104 -0
- pyegeria/dr.egeria spec.md +9 -0
- pyegeria/egeria_cat_client.py +5 -8
- pyegeria/egeria_client.py +39 -24
- pyegeria/egeria_config_client.py +2 -1
- pyegeria/egeria_my_client.py +4 -4
- pyegeria/egeria_tech_client.py +40 -18
- pyegeria/feedback_manager_omvs.py +1 -1
- pyegeria/full_omag_server_config.py +5 -3
- pyegeria/glossary_browser_omvs.py +1915 -694
- pyegeria/glossary_manager_omvs.py +685 -1842
- pyegeria/m_test.py +118 -0
- pyegeria/md_processing_helpers.py +58 -0
- pyegeria/md_processing_utils.py +2147 -0
- pyegeria/md_processing_utils_orig.py +1103 -0
- pyegeria/mermaid_utilities.py +1194 -14
- pyegeria/metadata_explorer_omvs.py +5 -50
- pyegeria/my_profile_omvs.py +3 -2
- pyegeria/output_formatter.py +389 -0
- pyegeria/platform_services.py +5 -5
- pyegeria/project_manager_omvs.py +97 -18
- pyegeria/runtime_manager_omvs.py +8 -10
- pyegeria/server_operations.py +2 -2
- pyegeria/solution_architect_omvs.py +2156 -0
- pyegeria/template_manager_omvs.py +13 -13
- pyegeria/utils.py +3 -1
- pyegeria/valid_metadata_omvs.py +5 -4
- pyegeria/x_action_author_omvs.py +3 -6
- {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/METADATA +9 -8
- pyegeria-5.3.dist-info/RECORD +196 -0
- {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/WHEEL +1 -1
- pyegeria-5.3.dist-info/entry_points.txt +99 -0
- pyegeria/commands/README.md +0 -47
- pyegeria/commands/__init__.py +0 -22
- pyegeria/commands/cat/__init__.py +0 -1
- pyegeria/commands/doc/README.md +0 -145
- pyegeria/commands/doc/Visual Command Reference/README.md +0 -511
- pyegeria/commands/doc/Visual Command Reference/cat/show/assets/asset-graph 2024-11-20 at 15.56.42.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/assets/assets-in-domain 2024-11-20 at 15.49.55@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/assets/elements-of-type 2024-11-20 at 16.01.35.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/assets/tech-type-elements 2024-11-20 at 16.05.05.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-data-catalogs 2024-12-17 at 15.43.27@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-data-catalogs-2024-11-20 at 16.17.43@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-schemas 2024-11-25 at 20.14.50@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-schemas 2024-12-17 at 15.48.38@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-servers 2024-11-25 at 20.21.25@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-servers 2024-12-17 at 15.52.16@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed_databases 2024-12-16 at 16.40.31@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/glossary/list-glossaries 2024-11-25 at 20.30.02.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/glossary/list-terms 2024-11-25 at 20.32.11.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/asset-types 2024-11-25 at 20.34.19@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/certification-types 2024-11-25 at 20.37.07.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/collection-graph 2024-12-12 at 11.33.18@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-collections 2024-12-10 at 14.25.51@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-todos 2024-12-12 at 11.46.30@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-user-ids 2024-12-12 at 11.51.09@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/info/tech-types 2024-12-12 at 11.37.20@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/projects/project_dependencies 2024-12-14 at 16.24.39@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/projects/project_structure 2024-12-14 at 16.21.35@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/projects/projects 2024-12-14 at 16.18.10@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/hey_egeria tui 2024-12-16 at 16.58.22@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/my/show/my_profile 2024-12-14 at 16.29.27@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/my/show/my_roles 2024-12-14 at 16.32.10@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/my/show/my_todos 2024-12-15 at 16.24.13@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/my/show/open_todos 2024-12-14 at 16.36.12@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/engines/list_engine_activity compressed 2024-12-15 at 16.48.48@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_activity 2024-12-15 at 16.32.55@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_activity compressed 2024-12-15 at 16.38.29@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_status 2024-12-15 at 16.51.26.jpeg +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/integrations/monitor_integration_daemon_status 2024-12-15 at 16.57.12@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/integrations/monitor_integration_targets 2024-12-15 at 17.02.19@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/platforms/monitor_platform_status 2024-12-15 at 19.53.18@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_server_status 2024-12-15 at 19.59.39@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_server_status full 2024-12-15 at 20.01.57@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_startup_servers 2024-12-15 at 19.56.07@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/get_anchored_elements 2024-12-15 at 21.25.41@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/get_elements_of_om_type 2024-12-16 at 14.39.59@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/info_for_guid 2024-12-16 at 11.35.29@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_by_om-type 2024-12-16 at 14.24.18@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_by_om-type extended 2024-12-16 at 14.28.46@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_of_om_type_by_classification 2024-12-16 at 14.35.26@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/related_elements 2024-12-16 at 14.55.01@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/elements/show_related_specifications 2024-12-16 at 15.04.55@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/asset_types 2024-12-16 at 15.10.16@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/detailed_governance_action_processes 2024-12-16 at 15.16.26@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/governance_action_processes 2024-12-16 at 15.13.01@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/registered_services 2024-12-16 at 16.44.54@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/relationship_types 2024-12-16 at 16.20.34@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/relationship_types 2024-12-19 at 10.51.54@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/valid_metadata_values 2024-12-16 at 15.31.56@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/list_tech_type_template_specs 2024-12-16 at 16.03.22@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/list_technology_types 2024-12-16 at 15.39.20@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/tech_type_details 2024-12-16 at 15.37.21@2x.png +0 -0
- pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/tech_type_templates 2024-12-16 at 16.11.48@2x.png +0 -0
- pyegeria/commands/doc/glossary/basic-glossary-tui.md +0 -109
- pyegeria/commands/doc/glossary/images/delete-glossary-step1 2024-11-06 at 15.47.23@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/delete-glossary-step2 2024-11-06 at 15.51.29@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/delete-glossary-step3 2024-11-06 at 15.53.19@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/delete-glossary-step4 2024-11-06 at 15.55.11@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/out-create-glossary example 2024-11-05 at 20.38.04@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/out-create-term 2024-11-06 at 20.48.29.png +0 -0
- pyegeria/commands/doc/glossary/images/out-delete-term 2024-11-07 at 03.57.25.png +0 -0
- pyegeria/commands/doc/glossary/images/out-display-terms-for-glossary-test 2024-11-06 at 20.51.28.png +0 -0
- pyegeria/commands/doc/glossary/images/out-export-example 2024-11-07 at 09.54.57.png +0 -0
- pyegeria/commands/doc/glossary/images/out-exported-terms 2024-11-06 at 21.06.32.png +0 -0
- pyegeria/commands/doc/glossary/images/out-glossary-list example 2024-11-05 at 20.41.02@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/out-import-terms 2024-11-07 at 08.15.18.png +0 -0
- pyegeria/commands/doc/glossary/images/out-list-all-terms 2024-11-06 at 16.22.20@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/out-list-terms-for-example 2024-11-06 at 16.40.12.png +0 -0
- pyegeria/commands/doc/glossary/images/out-list-terms-second 2024-11-06 at 16.45.13.png +0 -0
- pyegeria/commands/doc/glossary/images/out-pipx install pyegeria 2024-11-10 at 18.12.21.png +0 -0
- pyegeria/commands/doc/glossary/images/out-server-status-full 2024-11-10 at 18.25.14.png +0 -0
- pyegeria/commands/doc/glossary/images/out-servers-status 2024-11-10 at 18.15.42.png +0 -0
- pyegeria/commands/doc/glossary/images/out-upsert-import 2024-11-07 at 19.37.00.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-2024-11-10 at 18.26.29.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-create-glossary example 2024-11-05 at 20.34.24@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-create-term 2024-11-06 at 20.46.35.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-delete-term 2024-11-07 at 03.51.57.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-display-terms-for-example 2024-11-06 at 20.56.49.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-export-example 2024-11-07 at 09.52.59.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-hey-egeria 2024-11-10 at 18.31.01.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-import-upsert-example 2024-11-07 at 10.08.37.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-list-terms-second 2024-11-06 at 16.46.34.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-load-archive.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-server-status-full 2024-11-10 at 19.14.36.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-show-glossaries 2024-11-07 at 20.00.05.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-show-glossary-terms 2024-11-05 at 19.37.53@2x.png +0 -0
- pyegeria/commands/doc/glossary/images/tui-upsert 2024-11-07 at 11.49.04.png +0 -0
- pyegeria/commands/doc/glossary/images/upsert-example.om-terms 2024-11-07 at 11.44.05.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/README.md +0 -346
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/CleanShot 2024-11-18 at 21.32.03@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/Xmind 1731421782704.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/Xmind 1731422134920.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/hey_egeria 2024-11-12 at 20.38.43.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/hey_egeria cat 2024-11-12 at 21.41.43.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-integ-status-list 2024-11-12 at 16.45.26.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-integ-status-live 2024-11-12 at 16.44.12@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-server-status 2024-11-10 at 18.15.42@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-server-status-full 2024-11-10 at 18.25.14@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/short-cut commands 2024-11-12 at 22.22.13.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-hey-egeria.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-integration-status-paging.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-load-archive 2024-11-10 at 19.19.09@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-show-server-status 2024-11-10 at 18.52.01@2x.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-show-server-status-full 2024-11-10.png +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-status-paging 2024-11-12 at 16.26.14@2x.png +0 -0
- pyegeria/commands/ops/__init__.py +0 -22
- pyegeria/commands/tech/__init__.py +0 -0
- pyegeria-5.2.1.1.dist-info/RECORD +0 -231
- pyegeria-5.2.1.1.dist-info/entry_points.txt +0 -81
- {pyegeria/commands → commands}/cat/README.md +0 -0
- {pyegeria/commands → commands}/my/README.md +0 -0
- {pyegeria/commands → commands}/ops/README.md +0 -0
- {pyegeria/commands → commands}/ops/x_engine_actions.py +0 -0
- {pyegeria/commands → commands}/tech/README.md +0 -0
- /pyegeria/commands/my/__init__.py → /md_processing/dr_egeria_inbox/t1.md +0 -0
- {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/LICENSE +0 -0
@@ -0,0 +1,1103 @@
|
|
1
|
+
"""
|
2
|
+
|
3
|
+
This file contains functions to parse and process Egeria Markdown (Freddie)
|
4
|
+
|
5
|
+
|
6
|
+
"""
|
7
|
+
|
8
|
+
import json
|
9
|
+
from jupyter_notebook_parser import JupyterNotebookParser
|
10
|
+
import nbformat
|
11
|
+
from typing import List, Optional
|
12
|
+
|
13
|
+
import os
|
14
|
+
import re
|
15
|
+
|
16
|
+
from rich import box, print
|
17
|
+
from rich.console import Console
|
18
|
+
from rich.markdown import Markdown
|
19
|
+
|
20
|
+
from pyegeria import body_slimmer
|
21
|
+
from pyegeria._globals import NO_TERMS_FOUND, NO_GLOSSARIES_FOUND, NO_TERMS_FOUND, NO_ELEMENTS_FOUND, NO_PROJECTS_FOUND, NO_CATEGORIES_FOUND
|
22
|
+
from pyegeria.egeria_tech_client import EgeriaTech
|
23
|
+
from pyegeria.project_manager_omvs import ProjectManager
|
24
|
+
from pyegeria.glossary_manager_omvs import GlossaryManager
|
25
|
+
|
26
|
+
from datetime import datetime
|
27
|
+
EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "200"))
|
28
|
+
console = Console(width=EGERIA_WIDTH)
|
29
|
+
|
30
|
+
command_list = ["Provenance",
|
31
|
+
"Create Glossary", "Update Glossary",
|
32
|
+
"Create Term", "Update Term",
|
33
|
+
"Create Personal Project", "Update Personal Project",
|
34
|
+
"Create Category", "Update Category",
|
35
|
+
"Create Solution Blueprint", "Update Solution Blueprint"]
|
36
|
+
|
37
|
+
ERROR = "ERROR-> "
|
38
|
+
INFO = "INFO- "
|
39
|
+
WARNING = "WARNING-> "
|
40
|
+
pre_command = "\n---\n==> Processing object_action:"
|
41
|
+
|
42
|
+
element_dictionary = {}
|
43
|
+
|
44
|
+
def render_markdown(markdown_text: str) -> None:
|
45
|
+
"""Renders the given markdown text in the console."""
|
46
|
+
console.print(Markdown(markdown_text))
|
47
|
+
|
48
|
+
|
49
|
+
def is_valid_iso_date(date_text) -> bool:
|
50
|
+
"""Checks if the given string is a valid ISO date."""
|
51
|
+
try:
|
52
|
+
datetime.strptime(date_text, '%Y-%m-%d')
|
53
|
+
return True
|
54
|
+
except ValueError:
|
55
|
+
return False
|
56
|
+
|
57
|
+
|
58
|
+
def get_current_datetime_string():
|
59
|
+
"""Returns the current date and time as a human-readable string."""
|
60
|
+
now = datetime.now().strftime('%Y-%m-%d %H:%M')
|
61
|
+
return now
|
62
|
+
|
63
|
+
|
64
|
+
def add_term_to_categories(egeria_client: GlossaryManager, term_guid: str, categories_exist: bool,
|
65
|
+
categories_list: List[str], element_dictionary: dict) -> None:
|
66
|
+
if categories_exist is True and categories_list is not None:
|
67
|
+
for category in categories_list:
|
68
|
+
cat_guid = None
|
69
|
+
cat_el = category.strip()
|
70
|
+
if cat_el in element_dictionary:
|
71
|
+
cat= element_dictionary.get(cat_el, None)
|
72
|
+
cat_guid = cat.get('guid', None) if cat else None
|
73
|
+
if cat_guid is None:
|
74
|
+
cat_guid = egeria_client.__get_guid__(qualified_name=cat_el)
|
75
|
+
egeria_client.add_term_to_category(term_guid, cat_guid)
|
76
|
+
|
77
|
+
|
78
|
+
def extract_command_plus(block: str) -> tuple[str, str] | None:
|
79
|
+
match = re.search(r"#(.*?)(?:##|\n|$)", block) # Using a non capturing group
|
80
|
+
if match:
|
81
|
+
clean_match = match.group(1).strip()
|
82
|
+
parts = clean_match.split(' ')
|
83
|
+
object_action = parts[0].strip()
|
84
|
+
# Join the rest of the parts to allow object_type to be one or two words
|
85
|
+
object_type = ' '.join(parts[1:]).strip()
|
86
|
+
return object_type, object_action
|
87
|
+
return None
|
88
|
+
|
89
|
+
def extract_command(block: str) -> str | None:
|
90
|
+
match = re.search(r"#(.*?)(?:##|\n|$)", block) # Using a non capturing group
|
91
|
+
if match:
|
92
|
+
return match.group(1).strip()
|
93
|
+
return None
|
94
|
+
|
95
|
+
def extract_attribute(text: str, labels: List[str]) -> Optional[str]:
|
96
|
+
"""
|
97
|
+
Extracts the glossary name from a string.
|
98
|
+
|
99
|
+
Args:
|
100
|
+
text: The input string.
|
101
|
+
labels: List of equivalent labels to search for
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
The glossary name, or None if not found.
|
105
|
+
"""
|
106
|
+
# Iterate over the list of labels
|
107
|
+
for label in labels:
|
108
|
+
# Construct pattern for the current label
|
109
|
+
pattern = rf"## {re.escape(label)}\n(.*?)(?:#|---|$)"
|
110
|
+
match = re.search(pattern, text, re.DOTALL)
|
111
|
+
if match:
|
112
|
+
# Extract matched text and replace consecutive \n with a single \n
|
113
|
+
extracted_text = re.sub(r'\n+', '\n', match.group(1).strip())
|
114
|
+
if not extracted_text.isspace() and extracted_text:
|
115
|
+
return extracted_text # Return the cleaned text
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
def update_a_command(txt: str, command: str, obj_type: str, q_name: str, u_guid: str) -> str:
|
120
|
+
u_guid = u_guid if u_guid else " "
|
121
|
+
verb = command.split(' ')[0].strip()
|
122
|
+
action = "Update" if (verb == "Create" and u_guid is not None) else "Create"
|
123
|
+
txt = txt.replace(f"{command}", f'{action} {obj_type}\n') # update the object_action
|
124
|
+
txt = txt.replace('<GUID>', f'GUID\n{u_guid}') # update with GUID
|
125
|
+
txt = txt.replace('<Qualified Name>', f"Qualified Name\n{q_name}")
|
126
|
+
if "Qualified Name" not in txt:
|
127
|
+
txt += f"\n## Qualified Name\n{q_name}\n"
|
128
|
+
if "GUID" not in txt:
|
129
|
+
txt += f"\n## GUID\n{u_guid}\n"
|
130
|
+
|
131
|
+
# if (object_action in {"Update Term", "Update Category", 'Update Glossary'}) and ("Update Description" not in txt):
|
132
|
+
# txt += '\n** Update Description\n\n\n'
|
133
|
+
# elif "Update Description" in txt:
|
134
|
+
# pattern = r"(## Update Description\n).*?(#)"
|
135
|
+
# replacement = r"\1\n\n\2"
|
136
|
+
# txt += re.sub(pattern, replacement, txt)
|
137
|
+
|
138
|
+
status = extract_attribute(txt, ["Status"])
|
139
|
+
if command in ["Create Term", "Update Term"] and status is None:
|
140
|
+
pattern = r"(## Status\s*\n)(.*?)(#)"
|
141
|
+
replacement = r"\1\n DRAFT\n\n\3"
|
142
|
+
txt = re.sub(pattern, replacement, txt)
|
143
|
+
return txt
|
144
|
+
|
145
|
+
def process_provenance_command(file_path: str, txt: [str]) -> str:
|
146
|
+
"""This md_commands processes a provenence object_action by pre-pending the current file name and time to the provenance
|
147
|
+
output"""
|
148
|
+
output = (f"* Derived from processing file {file_path} on "
|
149
|
+
f"{get_current_datetime_string()}\n")
|
150
|
+
pattern = rf"# {re.escape('Provenance')}\n(.*?)(?:#|---|$)"
|
151
|
+
match = re.search(pattern, txt, re.DOTALL)
|
152
|
+
if match:
|
153
|
+
# Extract matched text and replace consecutive \n with a single \n
|
154
|
+
extracted_text = re.sub(r'\n+', '\n', match.group(1).strip())
|
155
|
+
if not extracted_text.isspace() and extracted_text:
|
156
|
+
existing_prov = extracted_text # Return the cleaned text
|
157
|
+
else:
|
158
|
+
existing_prov = None
|
159
|
+
print(f"txt is: {txt}, existing_prov: {existing_prov}")
|
160
|
+
existing_prov = existing_prov if existing_prov else " "
|
161
|
+
return f"\n# Provenance:\n{existing_prov}\n{output}\n"
|
162
|
+
|
163
|
+
def process_element_identifiers(egeria_client: EgeriaTech, txt: str) -> tuple[str, str, str, bool, bool]:
|
164
|
+
"""
|
165
|
+
Processes element identifiers by extracting display name and qualified name from the input text,
|
166
|
+
checking if the element exists in Egeria, and validating the information.
|
167
|
+
|
168
|
+
Parameters:
|
169
|
+
egeria_client: EgeriaTech
|
170
|
+
Client object for interacting with Egeria.
|
171
|
+
txt: str
|
172
|
+
A string representing the input text to be processed for extracting element identifiers.
|
173
|
+
|
174
|
+
Returns: tuple[str, str, str, bool, bool]
|
175
|
+
A tuple containing:
|
176
|
+
- qualified_name: Empty string or element identifier
|
177
|
+
- guid: Empty string or additional element information
|
178
|
+
- msg: Information or error messages about the processing
|
179
|
+
- Valid: Boolean indicating if the element information is valid
|
180
|
+
- Exists: Boolean indicating if the element exists in Egeria
|
181
|
+
"""
|
182
|
+
|
183
|
+
msg = ""
|
184
|
+
known_guid = None
|
185
|
+
valid = True
|
186
|
+
exists = False
|
187
|
+
display_name = extract_attribute(txt, ["Display Name"])
|
188
|
+
if display_name is None:
|
189
|
+
msg = f"* {ERROR}Display name is missing\n"
|
190
|
+
valid = False
|
191
|
+
return "","", msg, valid, exists
|
192
|
+
qualified_name = extract_attribute(txt, ["Qualified Name"])
|
193
|
+
if qualified_name:
|
194
|
+
element_details = egeria_client.get_terms_by_name(qualified_name)
|
195
|
+
else:
|
196
|
+
element_details = egeria_client.get_terms_by_name(display_name)
|
197
|
+
|
198
|
+
if element_details == NO_TERMS_FOUND:
|
199
|
+
exists = False
|
200
|
+
else:
|
201
|
+
exists = True
|
202
|
+
|
203
|
+
if len(element_details) > 1 and exists:
|
204
|
+
msg += (f"* {ERROR}More than one element with name {display_name} found, please specify a "
|
205
|
+
f"**Qualified Name**\n")
|
206
|
+
valid = False
|
207
|
+
elif len(element_details) == 1:
|
208
|
+
known_guid = element_details[0]['elementHeader'].get('guid', None)
|
209
|
+
known_q_name = element_details[0]['glossaryTermProperties'].get('qualifiedName', None)
|
210
|
+
if qualified_name != known_q_name:
|
211
|
+
msg += (f"* {ERROR}Element {display_name} qualifiedName mismatch between {qualified_name} and {known_q_name}\n")
|
212
|
+
valid = False
|
213
|
+
else:
|
214
|
+
msg += f"\n--> * Element {display_name} exists and can be updated\n"
|
215
|
+
# msg += term_display
|
216
|
+
# element_dictionary[known_q_name] = {'display_name': display_name, 'guid': known_guid}
|
217
|
+
return qualified_name, known_guid, msg, valid, exists
|
218
|
+
|
219
|
+
def process_blueprint_upsert_command(egeria_client: EgeriaTech, element_dictionary: dict, txt: str,
|
220
|
+
directive: str = "display") -> Optional[str]:
|
221
|
+
"""
|
222
|
+
Processes a blueprint create or update object_action by extracting key attributes such as
|
223
|
+
blueprint name, description, and version from the given cell.
|
224
|
+
|
225
|
+
Parameters:
|
226
|
+
egeria_client: SolutionArchitect
|
227
|
+
Client object for interacting with Egeria.
|
228
|
+
txt: str
|
229
|
+
A string representing the input cell to be processed for
|
230
|
+
extracting glossary-related attributes.
|
231
|
+
directive: str, optional, default "display"
|
232
|
+
An optional string indicating the directive to be used - display, validate or execute
|
233
|
+
|
234
|
+
Returns: str
|
235
|
+
A string summarizing the outcome of the processing.
|
236
|
+
"""
|
237
|
+
|
238
|
+
object_type, object_action = extract_command_plus(txt)
|
239
|
+
element_display = ""
|
240
|
+
display_name = extract_attribute(txt, ['Display Name','Blueprint Name'])
|
241
|
+
description = extract_attribute(txt, ['Description'])
|
242
|
+
version = extract_attribute(txt, ['Version', "Version Identifier", "Published Version"])
|
243
|
+
|
244
|
+
print(Markdown(f"{pre_command} `{object_type}{object_action}` for Blueprint: `\'{display_name}\'` with directive: `{directive}`"))
|
245
|
+
|
246
|
+
def validate_blueprint(obj_action: str) -> tuple[bool, bool, Optional[str], Optional[str]]:
|
247
|
+
nonlocal display_name, description, version, element_dictionary, element_display
|
248
|
+
|
249
|
+
known_q_name, known_guid, msg, valid, exists = process_element_identifiers(egeria_client, txt)
|
250
|
+
|
251
|
+
if description is None:
|
252
|
+
msg += f"* {INFO}Description is missing\n"
|
253
|
+
|
254
|
+
if version is None:
|
255
|
+
msg += f"* {INFO}Term version is missing\n"
|
256
|
+
|
257
|
+
update_description = extract_attribute(txt, ['Update Description'])
|
258
|
+
if update_description is None:
|
259
|
+
msg += f"* {INFO}Update Description is missing\n"
|
260
|
+
update_description = "---"
|
261
|
+
element_display = (f"\n* Command: {object_type}{object_action}\n\t* Blueprint: {display_name}\n\t"
|
262
|
+
f"* Term Name: {display_name}\n\t* Description: {description}\n\t"
|
263
|
+
f"* Version: {version}\n\t* Qualified Name:{known_q_name}\n\t* GUID: {known_guid} "
|
264
|
+
f"\n\t* Update Description: {update_description}\n")
|
265
|
+
|
266
|
+
if obj_action == "Update": # check to see if provided information exists and is consistent with existing info
|
267
|
+
if not exists:
|
268
|
+
msg += f"* {ERROR}Element {display_name} does not exist\n"
|
269
|
+
valid = False
|
270
|
+
element_dictionary[known_q_name] = {'display_name': display_name, 'guid': known_guid}
|
271
|
+
|
272
|
+
elif obj_action == 'Create': # if the object_action is create, check that it doesn't already exist
|
273
|
+
if exists:
|
274
|
+
msg += f"\n{WARNING}Element \'{display_name}\' already exists.\n"
|
275
|
+
elif not valid:
|
276
|
+
msg += f"\n-->Validation checks failed in creating element \'{display_name}\' with: {element_display}\n"
|
277
|
+
else: # valid to create - update element_dictionary
|
278
|
+
msg += f"\n-->It is valid to create element \'{display_name}\' with: {element_display}\n"
|
279
|
+
if known_q_name is None:
|
280
|
+
known_q_name = egeria_client.__create_qualified_name__(object_type, display_name)
|
281
|
+
element_dictionary[known_q_name] = {'display_name': display_name}
|
282
|
+
print(Markdown(msg))
|
283
|
+
return valid, exists, known_guid, known_q_name
|
284
|
+
|
285
|
+
|
286
|
+
if directive == "display":
|
287
|
+
print(Markdown(element_display))
|
288
|
+
return None
|
289
|
+
elif directive == "validate":
|
290
|
+
is_valid, exists, known_guid, known_q_name = validate_blueprint(object_action)
|
291
|
+
valid = is_valid if is_valid else None
|
292
|
+
return valid
|
293
|
+
elif directive == "process":
|
294
|
+
try:
|
295
|
+
is_valid, exists, known_guid, known_q_name = validate_blueprint(object_action)
|
296
|
+
if not is_valid: # First validate the term before we process it
|
297
|
+
return None
|
298
|
+
|
299
|
+
if object_action == "Update" and directive == "process":
|
300
|
+
if not exists:
|
301
|
+
print(f"\n-->Blueprint {display_name} does not exist")
|
302
|
+
return None
|
303
|
+
|
304
|
+
# call update blueprint here
|
305
|
+
|
306
|
+
print(f"\n-->Updated Blueprint {display_name} with GUID {known_guid}")
|
307
|
+
# update with get blueprint by guid
|
308
|
+
return 'Would return get blueprint by guid and return md' #egeria_client.get_terms_by_guid(known_guid, 'md')
|
309
|
+
|
310
|
+
elif object_action == "Update" and directive == "validate":
|
311
|
+
return 'Would call get_blueprint_by_guid and return md' #egeria_client.get_terms_by_guid(known_guid, 'md')
|
312
|
+
|
313
|
+
elif object_action == "Create":
|
314
|
+
if exists:
|
315
|
+
print(f"\n{WARNING}Blueprint {display_name} exists and result document updated")
|
316
|
+
return update_a_command(txt, f"{object_type}{object_action}",
|
317
|
+
object_type, known_q_name, known_guid)
|
318
|
+
else:
|
319
|
+
# create the blueprint
|
320
|
+
#term_guid = egeria_client.create_controlled_glossary_term(glossary_guid, term_body)
|
321
|
+
# if term_guid == NO_ELEMENTS_FOUND:
|
322
|
+
# print(f"{ERROR}Term {term_name} not created")
|
323
|
+
# return None
|
324
|
+
|
325
|
+
print(f"\n-->Created Blueprint {display_name} with GUID {known_guid}")
|
326
|
+
element_dictionary[known_q_name] = {'guid': known_guid, 'display_name': display_name}
|
327
|
+
return 'Would return get blueprint by guid results as md' #egeria_client.get_terms_by_guid(term_guid, 'MD')
|
328
|
+
|
329
|
+
except Exception as e:
|
330
|
+
print(f"{ERROR}Error creating term {display_name}: {e}")
|
331
|
+
console.print_exception(show_locals=True)
|
332
|
+
return None
|
333
|
+
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
def process_glossary_upsert_command(egeria_client: GlossaryManager, element_dictionary: dict, txt: str,
|
339
|
+
directive: str = "display") -> Optional[str]:
|
340
|
+
"""
|
341
|
+
Processes a glossary create or update object_action by extracting key attributes such as
|
342
|
+
glossary name, language, description, and usage from the given text.
|
343
|
+
|
344
|
+
:param txt: A string representing the input cell to be processed for
|
345
|
+
extracting glossary-related attributes.
|
346
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
347
|
+
:return: A string summarizing the outcome of the processing.
|
348
|
+
"""
|
349
|
+
command = extract_command(txt)
|
350
|
+
object_type = command.split(' ')[1].strip()
|
351
|
+
object_action = command.split(' ')[0].strip()
|
352
|
+
|
353
|
+
glossary_name = extract_attribute(txt, ['Glossary Name'])
|
354
|
+
print(Markdown(f"{pre_command} `{command}` for glossary: `\'{glossary_name}\'` with directive: `{directive}` "))
|
355
|
+
language = extract_attribute(txt, ['Language'])
|
356
|
+
description = extract_attribute(txt, ['Description'])
|
357
|
+
usage = extract_attribute(txt, ['Usage'])
|
358
|
+
|
359
|
+
glossary_display = (f"\n* Command: {command}\n\t* Glossary Name: {glossary_name}\n\t"
|
360
|
+
f"* Language: {language}\n\t* Description:\n{description}\n"
|
361
|
+
f"* Usage: {usage}\n")
|
362
|
+
|
363
|
+
if object_action == 'Update':
|
364
|
+
q_name = extract_attribute(txt, ['Qualified Name'])
|
365
|
+
guid = extract_attribute(txt, ['GUID', 'guid', 'Guid'])
|
366
|
+
glossary_display += f"* Qualified Name: {q_name}\n\t* GUID: {guid}\n\n"
|
367
|
+
|
368
|
+
def validate_glossary(obj_action: str) -> tuple[bool, bool, Optional[str], Optional[str]]:
|
369
|
+
valid = True
|
370
|
+
msg = ""
|
371
|
+
known_glossary_guid = None
|
372
|
+
known_q_name = None
|
373
|
+
|
374
|
+
glossary_details = egeria_client.get_glossaries_by_name(glossary_name)
|
375
|
+
if glossary_details == NO_GLOSSARIES_FOUND:
|
376
|
+
glossary_exists = False
|
377
|
+
else:
|
378
|
+
glossary_exists = True
|
379
|
+
|
380
|
+
if glossary_name is None:
|
381
|
+
msg = f"* {ERROR}Glossary name is missing\n"
|
382
|
+
valid = False
|
383
|
+
if language is None:
|
384
|
+
msg += f"* {ERROR}Language is missing\n"
|
385
|
+
valid = False
|
386
|
+
if description is None:
|
387
|
+
msg += f"* {INFO}Description is missing\n"
|
388
|
+
|
389
|
+
if len(glossary_details) > 1 and glossary_exists:
|
390
|
+
msg += f"* {ERROR}More than one glossary with name {glossary_name} found\n"
|
391
|
+
valid = False
|
392
|
+
if len(glossary_details) == 1:
|
393
|
+
known_glossary_guid = glossary_details[0]['elementHeader'].get('guid', None)
|
394
|
+
known_q_name = glossary_details[0]['glossaryProperties'].get('qualifiedName', None).strip()
|
395
|
+
|
396
|
+
if obj_action == "Update":
|
397
|
+
|
398
|
+
if not glossary_exists:
|
399
|
+
msg += f"* {ERROR}Glossary {glossary_name} does not exist\n"
|
400
|
+
valid = False
|
401
|
+
|
402
|
+
if q_name is None:
|
403
|
+
msg += f"* {INFO}Qualified Name is missing => can use known qualified name of {known_q_name}\n"
|
404
|
+
valid = True
|
405
|
+
elif q_name != known_q_name:
|
406
|
+
msg += (
|
407
|
+
f"* {ERROR}Glossary `{glossary_name}` qualifiedName mismatch between {q_name} and {known_q_name}\n")
|
408
|
+
valid = False
|
409
|
+
if valid:
|
410
|
+
msg += glossary_display
|
411
|
+
msg += f"* -->Glossary `{glossary_name}` exists and can be updated\n"
|
412
|
+
element_dictionary[known_q_name] = {'display_name': glossary_name, 'guid': known_glossary_guid}
|
413
|
+
else:
|
414
|
+
msg += f"* --> validation failed\n"
|
415
|
+
|
416
|
+
print(Markdown(msg))
|
417
|
+
return valid, glossary_exists, known_glossary_guid, known_q_name
|
418
|
+
|
419
|
+
elif obj_action == "Create":
|
420
|
+
if glossary_exists:
|
421
|
+
msg += f"{ERROR}Glossary {glossary_name} already exists\n"
|
422
|
+
|
423
|
+
elif valid:
|
424
|
+
msg += f"-->It is valid to create Glossary \'{glossary_name}\' with:\n"
|
425
|
+
msg += glossary_display
|
426
|
+
expected_q_name = egeria_client.__create_qualified_name__('Glossary', glossary_name)
|
427
|
+
element_dictionary[expected_q_name] = {'display_name': glossary_name}
|
428
|
+
|
429
|
+
print(Markdown(msg))
|
430
|
+
return valid, glossary_exists, known_glossary_guid, known_q_name
|
431
|
+
|
432
|
+
if directive == "display":
|
433
|
+
print(Markdown(glossary_display))
|
434
|
+
return None
|
435
|
+
|
436
|
+
elif directive == "validate":
|
437
|
+
is_valid, exists, known_guid, known_q_name = validate_glossary(object_action)
|
438
|
+
valid = is_valid if is_valid else None
|
439
|
+
return valid
|
440
|
+
|
441
|
+
elif directive == "process":
|
442
|
+
is_valid, exists, known_guid, known_q_name = validate_glossary(object_action)
|
443
|
+
if not is_valid:
|
444
|
+
return None
|
445
|
+
if object_action == "Update":
|
446
|
+
if not exists:
|
447
|
+
print(
|
448
|
+
f"\n{ERROR}Glossary {glossary_name} does not exist! Updating result document with Create object_action\n")
|
449
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
450
|
+
|
451
|
+
body = {
|
452
|
+
"class": "ReferenceableRequestBody", "elementProperties": {
|
453
|
+
"class": "GlossaryProperties", "qualifiedName": known_q_name, "description": description,
|
454
|
+
"language": language, "usage": usage
|
455
|
+
}
|
456
|
+
}
|
457
|
+
egeria_client.update_glossary(known_guid, body)
|
458
|
+
print(f"\n-->Updated Glossary {glossary_name} with GUID {known_guid}")
|
459
|
+
element_dictionary[known_q_name] = {
|
460
|
+
'guid': known_guid, 'display_name': glossary_name
|
461
|
+
}
|
462
|
+
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
463
|
+
return egeria_client.get_glossary_by_guid(known_guid, output_format='MD')
|
464
|
+
elif object_action == "Create":
|
465
|
+
glossary_guid = None
|
466
|
+
|
467
|
+
if exists:
|
468
|
+
print(f"\nGlossary {glossary_name} already exists and result document updated\n")
|
469
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
470
|
+
else:
|
471
|
+
glossary_guid = egeria_client.create_glossary(glossary_name, description, language, usage)
|
472
|
+
glossary = egeria_client.get_glossary_by_guid(glossary_guid)
|
473
|
+
if glossary == NO_GLOSSARIES_FOUND:
|
474
|
+
print(f"{ERROR}Just created with GUID {glossary_guid} but Glossary not found\n")
|
475
|
+
return None
|
476
|
+
qualified_name = glossary['glossaryProperties']["qualifiedName"]
|
477
|
+
element_dictionary[qualified_name] = {
|
478
|
+
'guid': glossary_guid, 'display_name': glossary_name
|
479
|
+
}
|
480
|
+
# return update_a_command(txt, object_action, object_type, qualified_name, glossary_guid)
|
481
|
+
return egeria_client.get_glossary_by_guid(glossary_guid, output_format = 'MD')
|
482
|
+
|
483
|
+
|
484
|
+
def process_categories_upsert_command(egeria_client: GlossaryManager, element_dictionary: dict, txt: str,
|
485
|
+
directive: str = "display") -> Optional[str]:
|
486
|
+
"""
|
487
|
+
Processes a glossary category create or update object_action by extracting key attributes such as
|
488
|
+
category name, qualified, description, and anchor glossary from the given txt..
|
489
|
+
|
490
|
+
:param txt: A string representing the input cell to be processed for
|
491
|
+
extracting category-related attributes.
|
492
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
493
|
+
:return: A string summarizing the outcome of the processing.
|
494
|
+
"""
|
495
|
+
command = extract_command(txt)
|
496
|
+
object_type = command.split(' ')[1].strip()
|
497
|
+
object_action = command.split(' ')[0].strip()
|
498
|
+
|
499
|
+
category_name = extract_attribute(txt, ['Category Name', 'category_name', 'Cat'])
|
500
|
+
print(Markdown(f"{pre_command} `{command}` for category: `\'{category_name}\'` with directive: `{directive}` "))
|
501
|
+
owning_glossary_qn = extract_attribute(txt, ['Owning Glossary', '[In Glossary'])
|
502
|
+
description = extract_attribute(txt, ['Description'])
|
503
|
+
q_name = extract_attribute(txt, ['Qualified Name'])
|
504
|
+
|
505
|
+
category_display = (f"\n* Command: {command}\n\t* Category: {category_name}\n\t* In Glossary: {owning_glossary_qn}\n\t"
|
506
|
+
f"* Description:\n{description}\n\t* Qualified Name: {q_name}\n\t")
|
507
|
+
update_description = None
|
508
|
+
|
509
|
+
if object_action == 'Update':
|
510
|
+
guid = extract_attribute(txt, ['GUID','guid','Guid'])
|
511
|
+
update_description = extract_attribute(txt, 'Update Description')
|
512
|
+
category_display += (f"* GUID: {guid}\n\n"
|
513
|
+
f"* Update Description: \n {update_description}\n\t")
|
514
|
+
|
515
|
+
def validate_category(obj_action: str) -> tuple[bool, bool, Optional[str], Optional[str], Optional[str]]:
|
516
|
+
valid = True
|
517
|
+
msg = ""
|
518
|
+
known_category_guid = None
|
519
|
+
known_q_name = None
|
520
|
+
glossary_guid = None
|
521
|
+
|
522
|
+
category_details = egeria_client.get_categories_by_name(category_name)
|
523
|
+
if category_details == NO_CATEGORIES_FOUND:
|
524
|
+
category_exists = False
|
525
|
+
else:
|
526
|
+
category_exists = True
|
527
|
+
|
528
|
+
if owning_glossary_qn is None:
|
529
|
+
msg += f"* {ERROR}Owning Glossary Qualified Name is missing\n"
|
530
|
+
valid = False
|
531
|
+
|
532
|
+
elif owning_glossary_qn in element_dictionary: # Check to see if we already know about this glossary
|
533
|
+
glossary_name = element_dictionary[owning_glossary_qn].get('display_name', None)
|
534
|
+
glossary_guid = element_dictionary[owning_glossary_qn].get('guid', None)
|
535
|
+
|
536
|
+
else:
|
537
|
+
# need to ask Egeria if it knows the Glossary Name
|
538
|
+
glossary = egeria_client.get_glossaries_by_name(owning_glossary_qn)
|
539
|
+
if glossary == NO_GLOSSARIES_FOUND:
|
540
|
+
msg += f"* {ERROR}Glossary `{owning_glossary_qn}` does not exist\n\n"
|
541
|
+
valid = False
|
542
|
+
else:
|
543
|
+
msg += f"* {INFO}Glossary `{owning_glossary_qn}` exists\n\n"
|
544
|
+
glossary_guid = glossary[0]['elementHeader'].get('guid', None)
|
545
|
+
glossary_name = glossary[0]['glossaryProperties'].get('displayName', None)
|
546
|
+
glossary_qn = glossary[0]['glossaryProperties'].get('qualifiedName', None)
|
547
|
+
if glossary_qn != owning_glossary_qn: # we were given the right qualified name - maybe a display_name
|
548
|
+
msg += f"* {ERROR}Glossary `{owning_glossary_qn}` is known by qualifiedName `{glossary_qn}`\n\n"
|
549
|
+
valid = False
|
550
|
+
else:
|
551
|
+
element_dictionary[owning_glossary_qn] = {
|
552
|
+
'guid': glossary_guid, 'display_name': glossary_name
|
553
|
+
}
|
554
|
+
|
555
|
+
if category_name is None:
|
556
|
+
msg = f"* {ERROR}Category name is missing\n"
|
557
|
+
valid = False
|
558
|
+
|
559
|
+
if description is None:
|
560
|
+
msg += f"* {INFO}Description is missing\n"
|
561
|
+
|
562
|
+
if len(category_details) > 1 and category_exists:
|
563
|
+
msg += f"* {ERROR}More than one category with name `{category_name}` found\n"
|
564
|
+
valid = False
|
565
|
+
if len(category_details) == 1:
|
566
|
+
known_category_guid = category_details[0]['elementHeader'].get('guid', None)
|
567
|
+
known_q_name = category_details[0]['glossaryCategoryProperties'].get('qualifiedName', None)
|
568
|
+
|
569
|
+
if obj_action == "Update":
|
570
|
+
if not category_exists:
|
571
|
+
msg += f"* {ERROR}category `{category_name}` does not exist\n"
|
572
|
+
valid = False
|
573
|
+
if q_name is None:
|
574
|
+
msg += f"* {INFO}Qualified Name is missing => can use known qualified name of {known_q_name}\n"
|
575
|
+
valid = True
|
576
|
+
elif q_name != known_q_name:
|
577
|
+
msg += (
|
578
|
+
f"* {ERROR}category `{category_name}` qualifiedName mismatch between {q_name} and {known_q_name}\n")
|
579
|
+
valid = False
|
580
|
+
if valid:
|
581
|
+
msg += category_display
|
582
|
+
msg += f"* -->category `{category_name}` exists and can be updated\n"
|
583
|
+
element_dictionary[known_q_name] = {'display_name': glossary_name, 'guid': known_category_guid}
|
584
|
+
else:
|
585
|
+
msg += f"* --> validation failed\n"
|
586
|
+
|
587
|
+
print(Markdown(msg))
|
588
|
+
return valid, category_exists, known_category_guid, known_q_name, glossary_guid
|
589
|
+
|
590
|
+
elif obj_action == "Create":
|
591
|
+
if category_exists:
|
592
|
+
msg += f"{ERROR}category `{category_name}` already exists\n"
|
593
|
+
|
594
|
+
elif valid:
|
595
|
+
msg += f"-->It is valid to create category `{category_name}` with:\n"
|
596
|
+
msg += category_display
|
597
|
+
expected_q_name = egeria_client.__create_qualified_name__('Category', category_name)
|
598
|
+
element_dictionary[expected_q_name] = {'display_name': category_name}
|
599
|
+
|
600
|
+
print(Markdown(msg))
|
601
|
+
return valid, category_exists, known_category_guid, known_q_name, glossary_guid
|
602
|
+
|
603
|
+
if directive == "display":
|
604
|
+
print(Markdown(category_display))
|
605
|
+
return None
|
606
|
+
|
607
|
+
elif directive == "validate":
|
608
|
+
is_valid, exists, known_guid, known_q_name, glossary_guid = validate_category(object_action)
|
609
|
+
valid = is_valid if is_valid else None
|
610
|
+
return valid
|
611
|
+
|
612
|
+
elif directive == "process":
|
613
|
+
is_valid, exists, known_guid, known_q_name, glossary_guid = validate_category(object_action)
|
614
|
+
if not is_valid:
|
615
|
+
print(f"{ERROR}Validation checks failed in creating category `{category_name}`")
|
616
|
+
return None
|
617
|
+
|
618
|
+
if object_action == "Update":
|
619
|
+
if not exists:
|
620
|
+
print(
|
621
|
+
f"\n{ERROR}category `{category_name}` does not exist! Updating result document with Create "
|
622
|
+
f"object_action\n")
|
623
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
624
|
+
|
625
|
+
egeria_client.update_category(glossary_guid, category_name, description, known_q_name, None,
|
626
|
+
update_description)
|
627
|
+
print(f"\n-->Updated category `{category_name}`with GUID {known_guid}")
|
628
|
+
element_dictionary[known_q_name] = {
|
629
|
+
'guid': known_guid, 'display_name': category_name
|
630
|
+
}
|
631
|
+
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
632
|
+
return egeria_client.get_category_by_guid(known_guid, output_format='FORM')
|
633
|
+
|
634
|
+
elif object_action == "Create":
|
635
|
+
is_root = False
|
636
|
+
|
637
|
+
if exists:
|
638
|
+
print(f"\ncategory `{category_name}` already exists and result document updated\n")
|
639
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
640
|
+
else:
|
641
|
+
category_guid = egeria_client.create_category(glossary_guid, category_name, description, is_root)
|
642
|
+
category = egeria_client.get_category_by_guid(category_guid)
|
643
|
+
|
644
|
+
if category == NO_CATEGORIES_FOUND:
|
645
|
+
print(f"{ERROR}Just created with GUID {category_guid} but category not found\n")
|
646
|
+
return None
|
647
|
+
qualified_name = category['glossaryCategoryProperties']["qualifiedName"]
|
648
|
+
element_dictionary[qualified_name] = {
|
649
|
+
'guid': category_guid, 'display_name': category_name
|
650
|
+
}
|
651
|
+
# return update_a_command(txt, object_action, object_type, qualified_name, category_guid)
|
652
|
+
return egeria_client.get_category_by_guid(category_guid, output_format='MD')
|
653
|
+
|
654
|
+
|
655
|
+
def process_term_upsert_command(egeria_client: GlossaryManager, element_dictionary: dict, txt: str,
|
656
|
+
directive: str = "display") -> Optional[str]:
|
657
|
+
"""
|
658
|
+
Processes a term create or update object_action by extracting key attributes such as
|
659
|
+
term name, summary, description, abbreviation, examples, usage, version, and status from the given cell.
|
660
|
+
|
661
|
+
:param txt: A string representing the input cell to be processed for
|
662
|
+
extracting glossary-related attributes.
|
663
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
664
|
+
:return: A string summarizing the outcome of the processing.
|
665
|
+
"""
|
666
|
+
|
667
|
+
command = extract_command(txt)
|
668
|
+
object_type = command.split(' ')[1].strip()
|
669
|
+
object_action = command.split(' ')[0].strip()
|
670
|
+
|
671
|
+
term_name = extract_attribute(txt, ['Term Name'])
|
672
|
+
summary = extract_attribute(txt, ['Summary'])
|
673
|
+
description = extract_attribute(txt, ['Description'])
|
674
|
+
abbreviation = extract_attribute(txt, ['Abbreviation'])
|
675
|
+
examples = extract_attribute(txt, ['Examples'])
|
676
|
+
usage = extract_attribute(txt, ['Usage'])
|
677
|
+
status = extract_attribute(txt, ['Status'])
|
678
|
+
version = extract_attribute(txt, ['Version', "Version Identifier", "Published Version"])
|
679
|
+
categories = extract_attribute(txt, ['Categories'])
|
680
|
+
q_name = extract_attribute(txt, ['Qualified Name'])
|
681
|
+
# q_name = q_name if q_name else " "
|
682
|
+
|
683
|
+
categories_list = None
|
684
|
+
cats_exist = True
|
685
|
+
|
686
|
+
glossary_qn = extract_attribute(txt, ['In Glossary','Owning Glossary'])
|
687
|
+
|
688
|
+
print(Markdown(f"{pre_command} `{command}` for term: `\'{term_name}\'` with directive: `{directive}`"))
|
689
|
+
|
690
|
+
def validate_term(obj_action: str) -> tuple[bool, bool, Optional[str], Optional[str]]:
|
691
|
+
nonlocal version, status, categories, categories_list, cats_exist, q_name, glossary_qn
|
692
|
+
valid = True
|
693
|
+
msg = ""
|
694
|
+
known_term_guid = None
|
695
|
+
known_q_name = None
|
696
|
+
|
697
|
+
# If the user has specified a qualified_name then use it to look for matching terms.
|
698
|
+
# If not, use the display_name.
|
699
|
+
if q_name:
|
700
|
+
term_details = egeria_client.get_terms_by_name(q_name)
|
701
|
+
else:
|
702
|
+
term_details = egeria_client.get_terms_by_name(term_name)
|
703
|
+
|
704
|
+
if term_details == NO_TERMS_FOUND:
|
705
|
+
term_exists = False
|
706
|
+
else:
|
707
|
+
term_exists = True
|
708
|
+
|
709
|
+
if status is None:
|
710
|
+
msg += f"* {INFO}Term status is missing - will default to DRAFT\n"
|
711
|
+
status = 'DRAFT'
|
712
|
+
|
713
|
+
|
714
|
+
if term_name is None:
|
715
|
+
msg = f"* {ERROR}Term name is missing\n"
|
716
|
+
valid = False
|
717
|
+
if glossary_qn is None:
|
718
|
+
msg += f"* {ERROR}Glossary qualified name is missing\n"
|
719
|
+
valid = False
|
720
|
+
else:
|
721
|
+
print(f"* {INFO}Glossary qualified name is `{glossary_qn}`")
|
722
|
+
if glossary_qn not in element_dictionary:
|
723
|
+
glossary = egeria_client.get_glossaries_by_name(glossary_qn) #assuming q_name?
|
724
|
+
if isinstance(glossary,str):
|
725
|
+
msg += f"* {ERROR}Glossary `{glossary_qn}` is unknown\n "
|
726
|
+
valid = False
|
727
|
+
elif len(glossary) != 1:
|
728
|
+
msg += f"* {ERROR}Glossary `{glossary_qn}` is ambiguous or not found\n "
|
729
|
+
valid = False
|
730
|
+
else:
|
731
|
+
glossary_qn = glossary[0]['glossaryProperties'].get('qualifiedName', None)
|
732
|
+
if glossary_qn is None:
|
733
|
+
msg += f"* {ERROR}Glossary `{glossary_qn}` has no qualifiedName\n "
|
734
|
+
valid = False
|
735
|
+
else:
|
736
|
+
element_dictionary[glossary_qn] = {
|
737
|
+
'guid': glossary[0]['elementHeader'].get('guid', None),
|
738
|
+
'display_name': glossary[0]['glossaryProperties'].get('displayName', None)
|
739
|
+
}
|
740
|
+
|
741
|
+
|
742
|
+
if categories is None:
|
743
|
+
msg += f"* {INFO} No categories found\n"
|
744
|
+
else:
|
745
|
+
categories_list = re.split(r'[,\n]+', categories)
|
746
|
+
categories = ""
|
747
|
+
new_cat_list = []
|
748
|
+
for category in categories_list:
|
749
|
+
category_el = category.strip()
|
750
|
+
if category_el not in element_dictionary:
|
751
|
+
cat = egeria_client.get_categories_by_name(category_el) # assuming qualified name?
|
752
|
+
if isinstance(cat,str):
|
753
|
+
msg += (f"* {WARNING}Category `{category_el}` not found -> "
|
754
|
+
f"categories for this term won't be processed!\n")
|
755
|
+
cats_exist = False
|
756
|
+
break
|
757
|
+
cat_qname = cat[0]['glossaryCategoryProperties'].get('qualifiedName', None)
|
758
|
+
category = cat_qname # use the qualified name if found
|
759
|
+
if cat_qname not in element_dictionary:
|
760
|
+
cat_guid = cat[0]['elementHeader']['guid']
|
761
|
+
cat_display_name = cat[0]['glossaryCategoryProperties'].get('displayName', None)
|
762
|
+
element_dictionary[cat_qname] = {
|
763
|
+
'guid' : cat_guid,
|
764
|
+
'displayName': cat_display_name
|
765
|
+
}
|
766
|
+
categories = f"{category}, {categories}"
|
767
|
+
new_cat_list.append(category)
|
768
|
+
if cats_exist:
|
769
|
+
categories +='\n'
|
770
|
+
categories_list = new_cat_list
|
771
|
+
else:
|
772
|
+
categories = None
|
773
|
+
|
774
|
+
|
775
|
+
if summary is None:
|
776
|
+
msg += f"* {INFO}Term summary is missing\n"
|
777
|
+
|
778
|
+
if description is None:
|
779
|
+
msg += f"* {INFO}Term description is missing\n"
|
780
|
+
|
781
|
+
if abbreviation is None:
|
782
|
+
msg += f"* {INFO}Term abbreviation is missing\n"
|
783
|
+
if examples is None:
|
784
|
+
msg += f"* {INFO}Term examples is missing\n"
|
785
|
+
if usage is None:
|
786
|
+
msg += f"* {INFO}Term usage is missing\n"
|
787
|
+
if version is None:
|
788
|
+
msg += f"* {INFO}Term version is missing\n"
|
789
|
+
# version = "0.0.1"
|
790
|
+
|
791
|
+
|
792
|
+
if obj_action == "Update": # check to see if provided information exists and is consistent with existing info
|
793
|
+
if not term_exists:
|
794
|
+
msg += f"* {ERROR}Term {term_name} does not exist\n"
|
795
|
+
valid = False
|
796
|
+
|
797
|
+
if len(term_details) > 1 and term_exists:
|
798
|
+
msg += (f"* {ERROR}More than one term with name {term_name} found, please specify a "
|
799
|
+
f"**Qualified Name**\n")
|
800
|
+
valid = False
|
801
|
+
elif len(term_details) == 1:
|
802
|
+
known_term_guid = term_details[0]['elementHeader'].get('guid', None)
|
803
|
+
known_q_name = term_details[0]['glossaryTermProperties'].get('qualifiedName', None)
|
804
|
+
if q_name != known_q_name:
|
805
|
+
msg += (f"* {ERROR}Term {term_name} qualifiedName mismatch between {q_name} and {known_q_name}\n")
|
806
|
+
valid = False
|
807
|
+
else:
|
808
|
+
msg += f"\n--> * Term {term_name} exists and can be updated\n"
|
809
|
+
msg += term_display
|
810
|
+
element_dictionary[known_q_name] = {'display_name': term_name, 'guid': known_term_guid}
|
811
|
+
|
812
|
+
print(Markdown(msg))
|
813
|
+
return valid, term_exists, known_term_guid, known_q_name
|
814
|
+
|
815
|
+
elif obj_action == 'Create': # if the object_action is create, check that it doesn't already exist
|
816
|
+
if term_exists:
|
817
|
+
msg += f"\n{WARNING}Term \'{term_name}\' already exists.\n"
|
818
|
+
elif not valid:
|
819
|
+
msg += f"\n-->Validation checks failed in creating Term \'{term_name}\' with: {term_display}\n"
|
820
|
+
else:
|
821
|
+
msg += f"\n-->It is valid to create Term \'{term_name}\' with: {term_display}\n"
|
822
|
+
if q_name is None:
|
823
|
+
expected_q_name = egeria_client.__create_qualified_name__('Term', term_name)
|
824
|
+
element_dictionary[expected_q_name] = {'display_name': term_name}
|
825
|
+
else:
|
826
|
+
element_dictionary[q_name] = {'display_name': term_name}
|
827
|
+
print(Markdown(msg))
|
828
|
+
return valid, term_exists, known_term_guid, known_q_name
|
829
|
+
|
830
|
+
# Continue processing the upsert
|
831
|
+
if object_action == "Update":
|
832
|
+
term_guid = extract_attribute(txt, 'GUID')
|
833
|
+
term_guid = term_guid if term_guid else None
|
834
|
+
|
835
|
+
|
836
|
+
update_description = extract_attribute(txt, 'Update Description')
|
837
|
+
update_description = update_description if update_description else " "
|
838
|
+
term_display = (f"\n* Command: {command}\n\t* Glossary: {glossary_qn}\n\t"
|
839
|
+
f"* Term Name: {term_name}\n\t* Qualified Name: {q_name}\n\t* Categories: {categories}\n\t"
|
840
|
+
f"* Summary: {summary}\n\t* Description: {description}\n\t"
|
841
|
+
f"* Abbreviation: {abbreviation}\n\t* Examples: {examples}\n\t* Usage: {usage}\n\t"
|
842
|
+
f"* Version: {version}\n\t* Status: {status}\n\t* GUID: {term_guid}\n\t* Qualified Name: "
|
843
|
+
f"{q_name}"
|
844
|
+
f"\n\t* Update Description: {update_description}\n")
|
845
|
+
else:
|
846
|
+
term_display = (f"\n* Command: {command}\n\t* Glossary: {glossary_qn}\n\t"
|
847
|
+
f"* Term Name: {term_name}\n\t* Categories: {categories}\n\t* Summary: {summary}\n\t"
|
848
|
+
f"* Qualified Name: {q_name}\n\t* Description: {description}\n\t"
|
849
|
+
f"* Abbreviation: {abbreviation}\n\t* Examples: {examples}\n\t* Usage: {usage}\n\t"
|
850
|
+
f"* Version: {version}\n\t* Status: {status}\n")
|
851
|
+
|
852
|
+
if directive == "display":
|
853
|
+
print(Markdown(term_display))
|
854
|
+
return None
|
855
|
+
elif directive == "validate":
|
856
|
+
is_valid, exists, known_guid, known_q_name = validate_term(object_action)
|
857
|
+
valid = is_valid if is_valid else None
|
858
|
+
return valid
|
859
|
+
elif directive == "process":
|
860
|
+
try:
|
861
|
+
is_valid, exists, known_guid, known_q_name = validate_term(object_action)
|
862
|
+
if not is_valid: # First validate the term before we process it
|
863
|
+
return None
|
864
|
+
|
865
|
+
if object_action == "Update" and directive == "process":
|
866
|
+
if not exists:
|
867
|
+
print(f"\n-->Term {term_name} does not exist")
|
868
|
+
return None
|
869
|
+
body = {
|
870
|
+
"class": "ReferenceableRequestBody",
|
871
|
+
"elementProperties": {
|
872
|
+
"class": "GlossaryTermProperties",
|
873
|
+
"qualifiedName": known_q_name,
|
874
|
+
"summary": summary,
|
875
|
+
"description": description,
|
876
|
+
"abbreviation": abbreviation,
|
877
|
+
"examples": examples,
|
878
|
+
"usage": usage,
|
879
|
+
"publishVersionIdentifier": version,
|
880
|
+
"status": status
|
881
|
+
},
|
882
|
+
"updateDescription": update_description
|
883
|
+
}
|
884
|
+
egeria_client.update_term(known_guid, body_slimmer(body))
|
885
|
+
# if cats_exist is True and categories_list is not None:
|
886
|
+
# for category in categories_list:
|
887
|
+
# cat_guid = element_dictionary.get(f"category.{category}", None)
|
888
|
+
# if cat_guid is None:
|
889
|
+
# cat_guid = egeria_client.__get_guid__(display_name=category)
|
890
|
+
# egeria_client.add_term_to_category(known_guid, cat_guid)
|
891
|
+
add_term_to_categories(
|
892
|
+
egeria_client, known_guid, cats_exist , categories_list,
|
893
|
+
element_dictionary)
|
894
|
+
print(f"\n-->Updated Term {term_name} with GUID {known_guid} and categories {categories_list}")
|
895
|
+
return egeria_client.get_terms_by_guid(known_guid, 'md')
|
896
|
+
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
897
|
+
elif object_action == "Update" and directive == "validate":
|
898
|
+
return egeria_client.get_terms_by_guid(known_guid, 'md')
|
899
|
+
|
900
|
+
elif object_action == "Create":
|
901
|
+
guid = None
|
902
|
+
if q_name is None:
|
903
|
+
q_name = egeria_client.__create_qualified_name__("Term",term_name)
|
904
|
+
if exists:
|
905
|
+
print(f"\n{WARNING}Term {term_name} exists and result document updated")
|
906
|
+
return update_a_command(txt, command, object_type, q_name, known_guid)
|
907
|
+
else:
|
908
|
+
## get the guid for the glossary from the name - first look locally
|
909
|
+
glossary = element_dictionary.get(glossary_qn, None)
|
910
|
+
|
911
|
+
if glossary is not None:
|
912
|
+
glossary_guid = glossary.get('guid', None)
|
913
|
+
if glossary_guid is None:
|
914
|
+
print(f"{ERROR}Glossary reference {glossary_qn} not found")
|
915
|
+
return None
|
916
|
+
else:
|
917
|
+
glossary_guid = egeria_client.__get_guid__(qualified_name=glossary_qn)
|
918
|
+
if glossary_guid == NO_ELEMENTS_FOUND:
|
919
|
+
print(f"{ERROR}Glossary {glossary_qn} not found")
|
920
|
+
return None
|
921
|
+
term_body = {
|
922
|
+
"class": "ReferenceableRequestBody", "elementProperties": {
|
923
|
+
"class": "GlossaryTermProperties",
|
924
|
+
"qualifiedName": q_name,
|
925
|
+
"displayName": term_name,
|
926
|
+
"summary": summary,
|
927
|
+
"description": description,
|
928
|
+
"abbreviation": abbreviation,
|
929
|
+
"examples": examples,
|
930
|
+
"usage": usage,
|
931
|
+
"publishVersionIdentifier": version
|
932
|
+
# "additionalProperties":
|
933
|
+
# {
|
934
|
+
# "propertyName1": "xxxx",
|
935
|
+
# "propertyName2": "xxxx"
|
936
|
+
# }
|
937
|
+
}, "initialStatus": status
|
938
|
+
}
|
939
|
+
term_guid = egeria_client.create_controlled_glossary_term(glossary_guid, term_body)
|
940
|
+
if term_guid == NO_ELEMENTS_FOUND:
|
941
|
+
print(f"{ERROR}Term {term_name} not created")
|
942
|
+
return None
|
943
|
+
if cats_exist and categories is not None:
|
944
|
+
add_term_to_categories(
|
945
|
+
egeria_client, term_guid, cats_exist, categories_list,
|
946
|
+
element_dictionary)
|
947
|
+
print(f"\n-->Created Term {term_name} with GUID {term_guid}")
|
948
|
+
element_dictionary[q_name] = {'guid': term_guid, 'display_name': term_name}
|
949
|
+
return egeria_client.get_terms_by_guid(term_guid, 'MD')
|
950
|
+
# return update_a_command(txt, object_action, object_type, q_name, term_guid)
|
951
|
+
except Exception as e:
|
952
|
+
print(f"{ERROR}Error creating term {term_name}: {e}")
|
953
|
+
console.print_exception(show_locals=True)
|
954
|
+
return None
|
955
|
+
|
956
|
+
def process_per_proj_upsert_command(egeria_client: ProjectManager, element_dictionary: dict, txt: str,
|
957
|
+
directive: str = "display") -> str | None:
|
958
|
+
"""
|
959
|
+
Processes a personal project create or update object_action by extracting key attributes such as
|
960
|
+
glossary name, language, description, and usage from the given cell.
|
961
|
+
|
962
|
+
:param txt: A string representing the input cell to be processed for
|
963
|
+
extracting glossary-related attributes.
|
964
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
965
|
+
:return: A string summarizing the outcome of the processing.
|
966
|
+
"""
|
967
|
+
command = extract_command(txt)
|
968
|
+
object = command.split()
|
969
|
+
object_type = f"{object[1]} {object[2]}"
|
970
|
+
object_action = object[0]
|
971
|
+
|
972
|
+
project_name = extract_attribute(txt, ['Project Name'])
|
973
|
+
description = extract_attribute(txt, ['Description'])
|
974
|
+
project_identifier = extract_attribute(txt, ['Project Identifier'])
|
975
|
+
project_status = extract_attribute(txt, ['Project Status'])
|
976
|
+
project_phase = extract_attribute(txt, ['Project Phase'])
|
977
|
+
project_health = extract_attribute(txt, ['Project Health'])
|
978
|
+
start_date = extract_attribute(txt, ['Start Date'])
|
979
|
+
planned_end_date = extract_attribute(txt, ['Planned End Date'])
|
980
|
+
print(Markdown(f"{pre_command} `\'{command}\'` for project: `{project_name}` with directive: `{directive}` "))
|
981
|
+
|
982
|
+
project_display = (f"\n* Command: {command}\n\t* Project: {project_name}\n\t"
|
983
|
+
f"* Status: {project_status}\n\t* Description: {description}\n\t"
|
984
|
+
f"* Phase: {project_phase}\n\t* Health: {project_health}\n\t"
|
985
|
+
f"* Start Date: {start_date}\n\t* Planned End Date: {planned_end_date}\n")
|
986
|
+
|
987
|
+
def validate_project(obj_action: str) -> tuple[bool, bool, str, str]:
|
988
|
+
valid = True
|
989
|
+
msg = ""
|
990
|
+
known_guid = None
|
991
|
+
known_q_name = None
|
992
|
+
|
993
|
+
project_details = egeria_client.get_projects_by_name(project_name)
|
994
|
+
if project_details == NO_PROJECTS_FOUND:
|
995
|
+
project_exists = False
|
996
|
+
else:
|
997
|
+
project_exists = True
|
998
|
+
|
999
|
+
if project_name is None:
|
1000
|
+
msg = f"* {ERROR}Project name is missing\n"
|
1001
|
+
valid = False
|
1002
|
+
if project_status is None:
|
1003
|
+
msg += f"* {INFO}No Project status found\n"
|
1004
|
+
|
1005
|
+
if description is None:
|
1006
|
+
msg += f"* {INFO}No Description found\n"
|
1007
|
+
|
1008
|
+
if project_identifier is None:
|
1009
|
+
msg += f"* {INFO}No Project Identifier found\n"
|
1010
|
+
|
1011
|
+
if project_phase is None:
|
1012
|
+
msg += f"* {INFO}No Project Phase found\n"
|
1013
|
+
|
1014
|
+
if project_health is None:
|
1015
|
+
msg += f"* {INFO}No Project Health found\n"
|
1016
|
+
|
1017
|
+
if start_date is None:
|
1018
|
+
msg += f"* {INFO}No Start Date found\n"
|
1019
|
+
elif not is_valid_iso_date(start_date):
|
1020
|
+
msg += f"* {ERROR}Start Date is not a valid ISO date of form YYYY-MM-DD\n"
|
1021
|
+
valid = False
|
1022
|
+
|
1023
|
+
if planned_end_date is None:
|
1024
|
+
msg += f"* {INFO} No Planned End Date found\n"
|
1025
|
+
elif not is_valid_iso_date(planned_end_date):
|
1026
|
+
msg += f"* {ERROR}Planned End Date is not a valid ISO date of form YYYY-MM-DD\n"
|
1027
|
+
valid = False
|
1028
|
+
|
1029
|
+
if obj_action == "Update":
|
1030
|
+
q_name = extract_attribute(txt, 'Qualified Name')
|
1031
|
+
|
1032
|
+
if not project_exists:
|
1033
|
+
msg += f"* {ERROR}Project {project_name} does not exist\n"
|
1034
|
+
valid = False
|
1035
|
+
if len(project_details) > 1 and project_exists:
|
1036
|
+
msg += f"* {ERROR}More than one project with name {project_name} found\n"
|
1037
|
+
valid = False
|
1038
|
+
if len(project_details) == 1:
|
1039
|
+
known_guid = project_details[0]['elementHeader'].get('guid', None)
|
1040
|
+
known_q_name = project_details[0]['glossaryProperties'].get('qualifiedName', None)
|
1041
|
+
if q_name is None:
|
1042
|
+
msg += f"* {INFO}Qualified Name is missing => can use known qualified name of {known_q_name}\n"
|
1043
|
+
valid = True
|
1044
|
+
elif q_name != known_q_name:
|
1045
|
+
msg += (f"* {ERROR}Project {project_name} qualifiedName mismatch between {q_name} and {known_q_name}\n")
|
1046
|
+
valid = False
|
1047
|
+
if valid:
|
1048
|
+
msg += project_display
|
1049
|
+
msg += f"* -->Project {project_name} exists and can be updated\n"
|
1050
|
+
else:
|
1051
|
+
msg += f"* --> validation failed\n"
|
1052
|
+
msg += '---'
|
1053
|
+
print(Markdown(msg))
|
1054
|
+
return valid, project_exists, known_guid, known_q_name
|
1055
|
+
|
1056
|
+
elif obj_action == "Create":
|
1057
|
+
if project_exists:
|
1058
|
+
msg += f"\n{ERROR}Project {project_name} already exists"
|
1059
|
+
else:
|
1060
|
+
msg += f"\n-->It is valid to create Project \'{project_name}\' with:\n"
|
1061
|
+
print(Markdown(msg))
|
1062
|
+
return valid, project_exists, known_guid, known_q_name
|
1063
|
+
|
1064
|
+
if directive == "display":
|
1065
|
+
print(Markdown(project_display))
|
1066
|
+
return None
|
1067
|
+
|
1068
|
+
elif directive == "validate":
|
1069
|
+
is_valid, exists, known_guid, known_q_name = validate_project(object_action)
|
1070
|
+
valid = is_valid if is_valid else None
|
1071
|
+
return valid
|
1072
|
+
|
1073
|
+
elif directive == "process":
|
1074
|
+
is_valid, exists, known_guid, known_q_name = validate_project(object_action)
|
1075
|
+
if not is_valid:
|
1076
|
+
return None
|
1077
|
+
if object_action == "Update":
|
1078
|
+
if not exists:
|
1079
|
+
print(f"\n\n-->Project {project_name} does not exist")
|
1080
|
+
return None
|
1081
|
+
|
1082
|
+
egeria_client.update_project(known_guid, known_q_name, project_identifier, project_name, description,
|
1083
|
+
project_status, project_phase, project_health, start_date, planned_end_date,
|
1084
|
+
False)
|
1085
|
+
print(f"\n-->Updated Project {project_name} with GUID {known_guid}")
|
1086
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
1087
|
+
elif object_action == "Create":
|
1088
|
+
guid = None
|
1089
|
+
if exists:
|
1090
|
+
print(f"Project {project_name} already exists and update document created")
|
1091
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
1092
|
+
else:
|
1093
|
+
guid = egeria_client.create_project(None, None, None, False, project_name, description,
|
1094
|
+
"PersonalProject", project_identifier, True, project_status,
|
1095
|
+
project_phase, project_health, start_date, planned_end_date)
|
1096
|
+
project_g = egeria_client.get_project_by_guid(guid)
|
1097
|
+
if project_g == NO_GLOSSARIES_FOUND:
|
1098
|
+
print(f"Just created with GUID {guid} but Project not found")
|
1099
|
+
return None
|
1100
|
+
|
1101
|
+
q_name = project_g['projectProperties']["qualifiedName"]
|
1102
|
+
element_dictionary[q_name] = {'guid': guid, 'display_name': project_name}
|
1103
|
+
return update_a_command(txt, command, object_type, q_name, guid)
|