pyegeria 5.4.0.28__py3-none-any.whl → 5.5.3.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.
Potentially problematic release.
This version of pyegeria might be problematic. Click here for more details.
- commands/__init__.py +24 -0
- commands/cat/Dr-Egeria_md-orig.py +2 -2
- commands/cat/collection_actions.py +197 -0
- commands/cat/dr_egeria_command_help.py +137 -38
- commands/cat/dr_egeria_jupyter.py +7 -7
- commands/cat/dr_egeria_md.py +10 -267
- commands/cat/exp_list_glossaries.py +11 -14
- commands/cat/get_asset_graph.py +37 -267
- commands/cat/{get_collection.py → get_collection_tree.py} +10 -18
- commands/cat/get_project_dependencies.py +14 -14
- commands/cat/get_project_structure.py +15 -14
- commands/cat/get_tech_type_elements.py +16 -116
- commands/cat/glossary_actions.py +145 -298
- commands/cat/list_assets.py +3 -11
- commands/cat/list_cert_types.py +17 -63
- commands/cat/list_collections.py +17 -139
- commands/cat/list_deployed_catalogs.py +15 -27
- commands/cat/list_deployed_database_schemas.py +27 -43
- commands/cat/list_deployed_databases.py +16 -31
- commands/cat/list_deployed_servers.py +35 -54
- commands/cat/list_glossaries.py +18 -17
- commands/cat/list_projects.py +10 -12
- commands/cat/list_tech_type_elements.py +21 -37
- commands/cat/list_tech_types.py +13 -25
- commands/cat/list_terms.py +38 -79
- commands/cat/list_todos.py +4 -11
- commands/cat/list_user_ids.py +3 -10
- commands/cat/my_reports.py +559 -0
- commands/cat/run_report.py +394 -0
- commands/cat/{list_format_set.py → run_report_orig.py} +136 -44
- commands/cli/egeria.py +182 -219
- commands/cli/egeria_cat.py +32 -59
- commands/cli/egeria_my.py +13 -0
- commands/cli/egeria_ops.py +69 -74
- commands/cli/egeria_tech.py +17 -93
- commands/{cat → deprecated}/list_data_designer.py +2 -4
- commands/{cat → deprecated}/list_data_structures_full.py +3 -6
- commands/deprecated/old_get_asset_graph.py +315 -0
- commands/my/__init__.py +0 -2
- commands/my/list_my_profile.py +27 -34
- commands/my/list_my_roles.py +1 -7
- commands/my/monitor_my_todos.py +1 -7
- commands/my/monitor_open_todos.py +6 -7
- commands/my/todo_actions.py +4 -5
- commands/ops/__init__.py +0 -2
- commands/ops/gov_server_actions.py +17 -21
- commands/ops/list_archives.py +17 -38
- commands/ops/list_catalog_targets.py +33 -40
- commands/ops/load_archive.py +14 -11
- commands/ops/{monitor_engine_activity_c.py → monitor_active_engine_activity.py} +51 -82
- commands/ops/{monitor_integ_daemon_status.py → monitor_daemon_status.py} +35 -55
- commands/ops/monitor_engine_activity.py +79 -77
- commands/ops/{monitor_gov_eng_status.py → monitor_engine_status.py} +10 -7
- commands/ops/monitor_platform_status.py +38 -50
- commands/ops/monitor_server_startup.py +6 -11
- commands/ops/monitor_server_status.py +7 -11
- commands/ops/orig_monitor_server_list.py +8 -8
- commands/ops/orig_monitor_server_status.py +1 -5
- commands/ops/refresh_integration_daemon.py +5 -5
- commands/ops/restart_integration_daemon.py +5 -5
- commands/ops/table_integ_daemon_status.py +6 -6
- commands/ops/x_engine_actions.py +7 -7
- commands/tech/__init__.py +0 -2
- commands/tech/{generic_actions.py → element_actions.py} +6 -11
- commands/tech/get_element_info.py +20 -29
- commands/tech/get_guid_info.py +23 -42
- commands/tech/get_tech_details.py +20 -35
- commands/tech/get_tech_type_template.py +28 -39
- commands/tech/list_all_om_type_elements.py +24 -30
- commands/tech/list_all_om_type_elements_x.py +22 -28
- commands/tech/list_all_related_elements.py +19 -28
- commands/tech/list_anchored_elements.py +22 -30
- commands/tech/list_asset_types.py +19 -24
- commands/tech/list_elements_by_classification_by_property_value.py +26 -32
- commands/tech/list_elements_by_property_value.py +19 -25
- commands/tech/list_elements_by_property_value_x.py +20 -28
- commands/tech/list_elements_for_classification.py +28 -41
- commands/tech/list_gov_action_processes.py +16 -27
- commands/tech/list_information_supply_chains.py +22 -30
- commands/tech/list_registered_services.py +14 -26
- commands/tech/list_related_elements_with_prop_value.py +15 -25
- commands/tech/list_related_specification.py +1 -4
- commands/tech/list_relationship_types.py +15 -25
- commands/tech/list_relationships.py +20 -36
- commands/tech/list_solution_blueprints.py +28 -33
- commands/tech/list_solution_components.py +23 -29
- commands/tech/list_solution_roles.py +21 -32
- commands/tech/list_tech_templates.py +51 -54
- commands/tech/list_valid_metadata_values.py +5 -9
- commands/tech/table_tech_templates.py +2 -6
- commands/tech/x_list_related_elements.py +1 -4
- examples/GeoSpatial Products Example.py +524 -0
- examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
- examples/Jupyter Notebooks/README.md +2 -0
- examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
- examples/Jupyter Notebooks/common/__init__.py +14 -0
- examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
- examples/Jupyter Notebooks/common/environment-check.ipynb +52 -0
- examples/Jupyter Notebooks/common/globals.ipynb +184 -0
- examples/Jupyter Notebooks/common/globals.py +154 -0
- examples/Jupyter Notebooks/common/orig_globals.py +152 -0
- examples/format_sets/all_format_sets.json +910 -0
- examples/format_sets/custom_format_sets.json +268 -0
- examples/format_sets/subset_format_sets.json +187 -0
- examples/format_sets_save_load_example.py +291 -0
- examples/jacquard_data_sets.py +129 -0
- examples/output_formats_example.py +193 -0
- examples/test_jacquard_data_sets.py +54 -0
- examples/test_jacquard_data_sets_scenarios.py +94 -0
- md_processing/__init__.py +33 -24
- md_processing/command_dispatcher.py +33 -0
- md_processing/command_mapping.py +221 -0
- md_processing/data/commands/commands_data_designer.json +537 -0
- md_processing/data/commands/commands_external_reference.json +733 -0
- md_processing/data/commands/commands_feedback.json +155 -0
- md_processing/data/commands/commands_general.json +204 -0
- md_processing/data/commands/commands_glossary.json +218 -0
- md_processing/data/commands/commands_governance.json +3678 -0
- md_processing/data/commands/commands_product_manager.json +865 -0
- md_processing/data/commands/commands_project.json +642 -0
- md_processing/data/commands/commands_solution_architect.json +366 -0
- md_processing/data/commands.json +6489 -30060
- md_processing/data/{commands-working.json → commands_working.json} +9304 -13513
- md_processing/data/gened_report_specs.py +6584 -0
- md_processing/data/generated_format_sets.json +6533 -0
- md_processing/data/generated_format_sets_old.json +4137 -0
- md_processing/data/generated_format_sets_old.py +45 -0
- md_processing/dr_egeria.py +182 -0
- md_processing/md_commands/data_designer_commands.py +195 -583
- md_processing/md_commands/ext_ref_commands.py +530 -0
- md_processing/md_commands/feedback_commands.py +726 -0
- md_processing/md_commands/glossary_commands.py +106 -490
- md_processing/md_commands/governance_officer_commands.py +129 -18
- md_processing/md_commands/product_manager_commands.py +362 -115
- md_processing/md_commands/project_commands.py +351 -134
- md_processing/md_commands/solution_architect_commands.py +276 -232
- md_processing/md_commands/view_commands.py +295 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +258 -166
- md_processing/md_processing_utils/common_md_utils.py +138 -43
- md_processing/md_processing_utils/determine_width.py +103 -0
- md_processing/md_processing_utils/extraction_utils.py +100 -39
- md_processing/md_processing_utils/gen_report_specs.py +643 -0
- md_processing/md_processing_utils/generate_dr_help.py +61 -33
- md_processing/md_processing_utils/generate_md_cmd_templates.py +20 -19
- md_processing/md_processing_utils/generate_md_templates.py +3 -12
- md_processing/md_processing_utils/md_processing_constants.py +1053 -72
- pyegeria/__init__.py +203 -158
- pyegeria/core/__init__.py +40 -0
- pyegeria/core/_base_platform_client.py +574 -0
- pyegeria/core/_base_server_client.py +573 -0
- pyegeria/{_exceptions_new.py → core/_exceptions.py} +62 -30
- pyegeria/{_globals.py → core/_globals.py} +14 -3
- pyegeria/core/_server_client.py +6073 -0
- pyegeria/{_validators.py → core/_validators.py} +7 -8
- pyegeria/core/config.py +654 -0
- pyegeria/{create_tech_guid_lists.py → core/create_tech_guid_lists.py} +0 -1
- pyegeria/core/load_config.py +37 -0
- pyegeria/{logging_configuration.py → core/logging_configuration.py} +1 -1
- pyegeria/core/mcp_adapter.py +144 -0
- pyegeria/core/mcp_server.py +212 -0
- pyegeria/core/utils.py +405 -0
- pyegeria/{_client.py → deprecated/_client.py} +24 -25
- pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
- pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1987 -1877
- pyegeria/{output_formatter.py → deprecated/output_formatter_with_machine_keys.py} +298 -45
- pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +155 -171
- pyegeria/{valid_metadata_omvs.py → deprecated/valid_metadata_omvs.py} +93 -93
- pyegeria/{x_action_author_omvs.py → deprecated/x_action_author_omvs.py} +2 -3
- pyegeria/egeria_cat_client.py +26 -70
- pyegeria/egeria_client.py +130 -93
- pyegeria/egeria_config_client.py +40 -46
- pyegeria/egeria_tech_client.py +141 -54
- pyegeria/models/__init__.py +150 -0
- pyegeria/{models.py → models/models.py} +156 -20
- pyegeria/omvs/__init__.py +84 -0
- pyegeria/omvs/action_author.py +342 -0
- pyegeria/omvs/actor_manager.py +5980 -0
- pyegeria/omvs/asset_catalog.py +842 -0
- pyegeria/omvs/asset_maker.py +2736 -0
- pyegeria/omvs/automated_curation.py +4403 -0
- pyegeria/omvs/classification_manager.py +11213 -0
- pyegeria/{collection_manager.py → omvs/collection_manager.py} +1334 -1160
- pyegeria/omvs/community_matters_omvs.py +468 -0
- pyegeria/{core_omag_server_config.py → omvs/core_omag_server_config.py} +157 -157
- pyegeria/{data_designer.py → omvs/data_designer.py} +1115 -660
- pyegeria/omvs/data_discovery.py +869 -0
- pyegeria/omvs/data_engineer.py +372 -0
- pyegeria/omvs/digital_business.py +1133 -0
- pyegeria/omvs/external_links.py +1752 -0
- pyegeria/omvs/feedback_manager.py +834 -0
- pyegeria/{full_omag_server_config.py → omvs/full_omag_server_config.py} +73 -69
- pyegeria/{glossary_manager.py → omvs/glossary_manager.py} +857 -519
- pyegeria/{governance_officer.py → omvs/governance_officer.py} +964 -468
- pyegeria/omvs/lineage_linker.py +314 -0
- pyegeria/omvs/location_arena.py +1525 -0
- pyegeria/omvs/metadata_expert.py +668 -0
- pyegeria/omvs/metadata_explorer_omvs.py +2943 -0
- pyegeria/omvs/my_profile.py +1042 -0
- pyegeria/omvs/notification_manager.py +358 -0
- pyegeria/omvs/people_organizer.py +394 -0
- pyegeria/{platform_services.py → omvs/platform_services.py} +113 -193
- pyegeria/omvs/product_manager.py +1825 -0
- pyegeria/omvs/project_manager.py +1907 -0
- pyegeria/omvs/reference_data.py +1140 -0
- pyegeria/omvs/registered_info.py +334 -0
- pyegeria/omvs/runtime_manager.py +2817 -0
- pyegeria/omvs/schema_maker.py +446 -0
- pyegeria/{server_operations.py → omvs/server_operations.py} +27 -26
- pyegeria/{solution_architect_omvs.py → omvs/solution_architect.py} +1886 -1505
- pyegeria/omvs/specification_properties.py +37 -0
- pyegeria/omvs/subject_area.py +1042 -0
- pyegeria/omvs/template_manager_omvs.py +236 -0
- pyegeria/omvs/time_keeper.py +1761 -0
- pyegeria/omvs/valid_metadata.py +3221 -0
- pyegeria/omvs/valid_metadata_lists.py +37 -0
- pyegeria/omvs/valid_type_lists.py +37 -0
- pyegeria/view/__init__.py +28 -0
- pyegeria/{_output_format_models.py → view/_output_format_models.py} +160 -24
- pyegeria/view/_output_formats.py +14 -0
- pyegeria/view/base_report_formats.py +2719 -0
- pyegeria/view/dr_egeria_reports.py +56 -0
- pyegeria/view/format_set_executor.py +397 -0
- pyegeria/{md_processing_utils.py → view/md_processing_utils.py} +5 -5
- pyegeria/{mermaid_utilities.py → view/mermaid_utilities.py} +2 -154
- pyegeria/view/output_formatter.py +1297 -0
- pyegeria-5.5.3.3.dist-info/METADATA +218 -0
- pyegeria-5.5.3.3.dist-info/RECORD +241 -0
- {pyegeria-5.4.0.28.dist-info → pyegeria-5.5.3.3.dist-info}/WHEEL +2 -1
- pyegeria-5.5.3.3.dist-info/entry_points.txt +103 -0
- pyegeria-5.5.3.3.dist-info/top_level.txt +4 -0
- commands/cat/.DS_Store +0 -0
- commands/cat/.env +0 -8
- commands/cat/README.md +0 -16
- commands/cat/debug_log +0 -1126
- commands/cat/debug_log.2025-08-18_11-34-38_088636.zip +0 -0
- commands/cat/list_categories.py +0 -192
- commands/cat/logs/pyegeria.log +0 -4
- commands/cli/debug_log +0 -0
- commands/cli/debug_log.log +0 -0
- commands/cli/txt_custom_v2.tcss +0 -19
- commands/my/README.md +0 -17
- commands/ops/README.md +0 -24
- commands/ops/logs/pyegeria.log +0 -0
- commands/ops/monitor_asset_events.py +0 -108
- commands/tech/README.md +0 -24
- md_processing/.DS_Store +0 -0
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-30-37.md +0 -163
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-35-58.md +0 -474
- md_processing/dr_egeria_inbox/Derive-Dr-Gov-Defs.md +0 -8
- md_processing/dr_egeria_inbox/Dr.Egeria Templates.md +0 -873
- md_processing/dr_egeria_inbox/arch_test.md +0 -57
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
- md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
- md_processing/dr_egeria_inbox/cat_test.md +0 -100
- md_processing/dr_egeria_inbox/collections.md +0 -39
- md_processing/dr_egeria_inbox/data_designer_debug.log +0 -6
- md_processing/dr_egeria_inbox/data_designer_out.md +0 -60
- md_processing/dr_egeria_inbox/data_designer_search_test.md +0 -11
- md_processing/dr_egeria_inbox/data_field.md +0 -54
- md_processing/dr_egeria_inbox/data_spec.md +0 -77
- md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
- md_processing/dr_egeria_inbox/data_test.md +0 -179
- md_processing/dr_egeria_inbox/data_test2.md +0 -429
- md_processing/dr_egeria_inbox/data_test3.md +0 -462
- md_processing/dr_egeria_inbox/dr_egeria_data_designer_1.md +0 -124
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -318
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
- md_processing/dr_egeria_inbox/generated_help_report.md +0 -9
- md_processing/dr_egeria_inbox/glossary_creation_experiment.ipynb +0 -341
- md_processing/dr_egeria_inbox/glossary_list.md +0 -5
- md_processing/dr_egeria_inbox/glossary_search_test.md +0 -40
- md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
- md_processing/dr_egeria_inbox/gov_def.md +0 -482
- md_processing/dr_egeria_inbox/gov_def2.md +0 -447
- md_processing/dr_egeria_inbox/img.png +0 -0
- md_processing/dr_egeria_inbox/product.md +0 -211
- md_processing/dr_egeria_inbox/rel.md +0 -8
- md_processing/dr_egeria_inbox/sb.md +0 -119
- md_processing/dr_egeria_inbox/solution-components.md +0 -136
- md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
- md_processing/dr_egeria_inbox/synonym_test.md +0 -42
- md_processing/dr_egeria_inbox/t2.md +0 -268
- md_processing/dr_egeria_outbox/.obsidian/app.json +0 -1
- md_processing/dr_egeria_outbox/.obsidian/appearance.json +0 -1
- md_processing/dr_egeria_outbox/.obsidian/community-plugins.json +0 -6
- md_processing/dr_egeria_outbox/.obsidian/core-plugins.json +0 -31
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/data.json +0 -10
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/main.js +0 -4459
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/manifest.json +0 -10
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/data.json +0 -3
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/main.js +0 -153
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/manifest.json +0 -11
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/styles.css +0 -1
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/main.js +0 -500
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +0 -12
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/styles.css +0 -1
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/main.js +0 -37
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/manifest.json +0 -11
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/styles.css +0 -220
- md_processing/dr_egeria_outbox/.obsidian/types.json +0 -28
- md_processing/dr_egeria_outbox/.obsidian/workspace.json +0 -220
- md_processing/dr_egeria_outbox/Untitled.canvas +0 -1
- md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:22-dr_egeria_intro_part1.md +0 -312
- md_processing/dr_egeria_outbox/friday/processed-2025-08-22 21:23-dr_egeria_intro_part1.md +0 -265
- md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:06-dr_egeria_intro_part1.md +0 -230
- md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:30-dr_egeria_intro_part1.md +0 -296
- md_processing/dr_egeria_outbox/friday/processed-2025-08-23 15:31-dr_egeria_intro_part1.md +0 -253
- md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:08-dr_egeria_intro_part2.md +0 -343
- md_processing/dr_egeria_outbox/friday/processed-2025-08-23 16:12-dr_egeria_intro_part2.md +0 -343
- md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +0 -426
- md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +0 -212
- md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +0 -201
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 14:55-product.md +0 -77
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:05-product.md +0 -75
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:11-product.md +0 -74
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 20:40-collections.md +0 -49
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +0 -719
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +0 -41
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +0 -33
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +0 -192
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:08-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:10-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:53-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:54-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:03-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:06-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:10-gov_def2.md +0 -486
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-16 19:15-gov_def2.md +0 -527
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 12:08-gov_def2.md +0 -527
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 14:27-gov_def2.md +0 -485
- md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +0 -209
- md_processing/family_docs/Data Designer/Create_Data_Class.md +0 -164
- md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +0 -30
- md_processing/family_docs/Data Designer/Create_Data_Field.md +0 -162
- md_processing/family_docs/Data Designer/Create_Data_Specification.md +0 -36
- md_processing/family_docs/Data Designer/Create_Data_Structure.md +0 -38
- md_processing/family_docs/Data Designer/View_Data_Classes.md +0 -78
- md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +0 -78
- md_processing/family_docs/Data Designer/View_Data_Fields.md +0 -78
- md_processing/family_docs/Data Designer/View_Data_Specifications.md +0 -78
- md_processing/family_docs/Data Designer/View_Data_Structures.md +0 -78
- md_processing/family_docs/Data Designer.md +0 -842
- md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +0 -42
- md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +0 -36
- md_processing/family_docs/Digital Product Manager/Create_Agreement.md +0 -96
- md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +0 -72
- md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +0 -102
- md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +0 -134
- md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +0 -60
- md_processing/family_docs/Digital Product Manager/Link_Contracts.md +0 -26
- md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +0 -30
- md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +0 -48
- md_processing/family_docs/Digital Product Manager.md +0 -668
- md_processing/family_docs/Glossary/Attach_Category_Parent.md +0 -18
- md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +0 -26
- md_processing/family_docs/Glossary/Create_Category.md +0 -38
- md_processing/family_docs/Glossary/Create_Glossary.md +0 -42
- md_processing/family_docs/Glossary/Create_Term.md +0 -70
- md_processing/family_docs/Glossary.md +0 -206
- md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +0 -106
- md_processing/family_docs/Governance Officer/Create_Certification_Type.md +0 -112
- md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +0 -114
- md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +0 -114
- md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +0 -114
- md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +0 -128
- md_processing/family_docs/Governance Officer/Create_Governance_Process.md +0 -122
- md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +0 -106
- md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +0 -122
- md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +0 -122
- md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +0 -106
- md_processing/family_docs/Governance Officer/Create_License_Type.md +0 -112
- md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +0 -122
- md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +0 -106
- md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +0 -118
- md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +0 -114
- md_processing/family_docs/Governance Officer/Create_Security_Group.md +0 -120
- md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +0 -122
- md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +0 -106
- md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +0 -32
- md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +0 -32
- md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +0 -32
- md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +0 -82
- md_processing/family_docs/Governance Officer.md +0 -2412
- md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +0 -70
- md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +0 -44
- md_processing/family_docs/Solution Architect/Create_Solution_Component.md +0 -96
- md_processing/family_docs/Solution Architect/Create_Solution_Role.md +0 -66
- md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +0 -32
- md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +0 -32
- md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +0 -32
- md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +0 -32
- md_processing/family_docs/Solution Architect/View_Solution_Components.md +0 -32
- md_processing/family_docs/Solution Architect/View_Solution_Roles.md +0 -32
- md_processing/family_docs/Solution Architect.md +0 -490
- md_processing/md_processing_utils/debug_log +0 -574
- md_processing/md_processing_utils/debug_log.log +0 -0
- md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +0 -2065
- md_processing/md_processing_utils/generated_help_terms.md +0 -842
- pyegeria/.DS_Store +0 -0
- pyegeria/README.md +0 -35
- pyegeria/_client_new.py +0 -1102
- pyegeria/_output_formats.py +0 -730
- pyegeria/asset_catalog_omvs.py +0 -864
- pyegeria/automated_curation_omvs.py +0 -3765
- pyegeria/config.py +0 -523
- pyegeria/egeria_my_client.py +0 -91
- pyegeria/feedback_manager_omvs.py +0 -4573
- pyegeria/load_config_orig.py +0 -218
- pyegeria/md_processing_helpers.py +0 -58
- pyegeria/md_processing_utils_orig.py +0 -1103
- pyegeria/metadata_explorer_omvs.py +0 -2326
- pyegeria/my_profile_omvs.py +0 -1022
- pyegeria/project_manager.py +0 -1591
- pyegeria/registered_info.py +0 -167
- pyegeria/template_manager_omvs.py +0 -1414
- pyegeria/utils.py +0 -256
- pyegeria-5.4.0.28.dist-info/METADATA +0 -77
- pyegeria-5.4.0.28.dist-info/RECORD +0 -343
- pyegeria-5.4.0.28.dist-info/entry_points.txt +0 -105
- /commands/cat/debug_log.log → /pyegeria/deprecated/__init__.py +0 -0
- /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
- /pyegeria/{collection_models.py → models/collection_models.py} +0 -0
- {pyegeria-5.4.0.28.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
""" python
|
|
2
|
+
|
|
3
|
+
PDX-License-Identifier: Apache-2.0
|
|
4
|
+
Copyright Contributors to the ODPi Egeria project.
|
|
5
|
+
|
|
6
|
+
This file provides a utility function for my_egeria.
|
|
7
|
+
|
|
8
|
+
This file is being used to test some display layout options
|
|
9
|
+
This is a test file to explore different ways to display Egeria data
|
|
10
|
+
Author: Peter Coldicott, November 2025
|
|
11
|
+
|
|
12
|
+
This version is to test having the user input required parameters to run
|
|
13
|
+
customized reports
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import re
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from commands.cat.run_report import list_generic
|
|
22
|
+
from pydantic import ValidationError
|
|
23
|
+
from pyegeria.view.base_report_formats import report_spec_list, select_report_spec
|
|
24
|
+
from pyegeria.view.format_set_executor import exec_report_spec
|
|
25
|
+
from textual import on
|
|
26
|
+
from textual.app import App
|
|
27
|
+
from textual.containers import Container, Horizontal, HorizontalScroll, ScrollableContainer
|
|
28
|
+
from textual.widgets import Static, Button, DataTable, Header, Footer, Input, Tree, Label
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class RunSpec(App):
|
|
32
|
+
CSS_PATH = "my_reports.tcss"
|
|
33
|
+
|
|
34
|
+
BINDINGS = [
|
|
35
|
+
("q", "quit", "Quit"),
|
|
36
|
+
("s", "show_report", "Show"),
|
|
37
|
+
("r", "prepare_report", "Run"),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# TITLE = "My_Egeria"
|
|
41
|
+
# SUB_TITLE = "Report Specification Details"
|
|
42
|
+
|
|
43
|
+
def __init__(self, **kwargs):
|
|
44
|
+
super().__init__(**kwargs)
|
|
45
|
+
self.Egeria_config = ["https://127.0.0.1:9443", "qs-view-server", "erinoverview", "secret"]
|
|
46
|
+
self.platform_url = self.Egeria_config[0]
|
|
47
|
+
self.view_server = self.Egeria_config[1]
|
|
48
|
+
self.user = self.Egeria_config[2]
|
|
49
|
+
self.password = self.Egeria_config[3]
|
|
50
|
+
self.selected_report_spec: str = ""
|
|
51
|
+
self.items: list = []
|
|
52
|
+
self.created_inputs: list[Input] = []
|
|
53
|
+
self.inputs_tracker: dict[str, list] = {}
|
|
54
|
+
self.snode_label: str = ""
|
|
55
|
+
# Holds rotated data as column -> list of row values
|
|
56
|
+
self.rotated_table: dict[str, list[str]] = {}
|
|
57
|
+
|
|
58
|
+
def compose(self):
|
|
59
|
+
self.title = "My_Egeria"
|
|
60
|
+
self.sub_title = "Report Specification Details"
|
|
61
|
+
yield Header()
|
|
62
|
+
yield Container(
|
|
63
|
+
Static("Start of report specification list:", id="one_start"),
|
|
64
|
+
Tree(label="Report Specs",id="spec_tree", classes="trees"),
|
|
65
|
+
Static("End of report specification list:", id="one_end"),
|
|
66
|
+
id="container1", classes="box")
|
|
67
|
+
yield Container(
|
|
68
|
+
Static("Report Specification Details", classes="box", id="two_start"),
|
|
69
|
+
DataTable(id="spec_extracted_datatable"),
|
|
70
|
+
Static("End of Report Specification Details", classes="box", id="two_end"),
|
|
71
|
+
id="container2", classes="box")
|
|
72
|
+
yield ScrollableContainer(
|
|
73
|
+
Static("Report Specs Input Fields", classes="box", id="four_start"),
|
|
74
|
+
Container(id="input_fields"),
|
|
75
|
+
Static("End of Report Specs Input Fields", classes="box", id="four_end"),
|
|
76
|
+
id="container4", classes="box")
|
|
77
|
+
yield Container(
|
|
78
|
+
Static("Report Specification Output)", classes="box", id="three_start"),
|
|
79
|
+
DataTable(id="spec_output_datatable"),
|
|
80
|
+
Static("End of Report Specification Output)", classes="box", id="three_end"),
|
|
81
|
+
id="container3", classes="box")
|
|
82
|
+
yield Footer()
|
|
83
|
+
|
|
84
|
+
def on_mount(self):
|
|
85
|
+
self.spec_tree = self.query_one("#spec_tree", Tree)
|
|
86
|
+
self.spec_tree.clear()
|
|
87
|
+
root_data = "A categorized list of PyEgeria report specifications"
|
|
88
|
+
self.spec_tree.root.expand()
|
|
89
|
+
self.spec_tree.root.label = "Report Specs"
|
|
90
|
+
self.spec_tree.root.data = root_data
|
|
91
|
+
tree_root = self.spec_tree.root
|
|
92
|
+
self.family: str = ""
|
|
93
|
+
self.heading = "Report Specs"
|
|
94
|
+
self.subheading = "Select a report spec to execute:"
|
|
95
|
+
self.description = "A list of report specifications, click on one to see its attributes\ns key to run"
|
|
96
|
+
self.report_spec_list: list = report_spec_list(show_family=True, sort_by_family=True, return_kind="dicts")
|
|
97
|
+
self.log(f"report_spec_list: {self.report_spec_list}, type: {type(self.report_spec_list)}")
|
|
98
|
+
for spec in self.report_spec_list:
|
|
99
|
+
if spec.get("family") != self.family:
|
|
100
|
+
self.family = spec.get("family")
|
|
101
|
+
family_node = tree_root.add(self.family, data="family_name")
|
|
102
|
+
family_node.expand()
|
|
103
|
+
family_node.add(spec.get("name"), data=spec.get("description"))
|
|
104
|
+
continue
|
|
105
|
+
else:
|
|
106
|
+
family_node.add(spec.get("name"), data=spec.get("description"))
|
|
107
|
+
continue
|
|
108
|
+
self.spec_tree.refresh()
|
|
109
|
+
|
|
110
|
+
@on(Tree.NodeSelected, "#spec_tree")
|
|
111
|
+
async def handle_spec_tree_node_selected(self, message: Tree.NodeSelected):
|
|
112
|
+
self.log(f"Node Selected, Processing selection")
|
|
113
|
+
self.selected_report_spec = message.node
|
|
114
|
+
self.log(f"selected_report_spec: {self.selected_report_spec}")
|
|
115
|
+
snode = message.node
|
|
116
|
+
self.log(f"snode: {snode}", type(snode))
|
|
117
|
+
if snode.data:
|
|
118
|
+
snode_label = str(snode.label)
|
|
119
|
+
self.log(f"snode_label: {snode_label}", type(snode_label))
|
|
120
|
+
else:
|
|
121
|
+
snode_label = str(snode.label)
|
|
122
|
+
self.log(f"snode_label: {snode_label}", type(snode_label))
|
|
123
|
+
# address input fields container so we can clear it from prior selections
|
|
124
|
+
inputs_container = self.query_one("#input_fields", Container)
|
|
125
|
+
# Clear previous rows
|
|
126
|
+
try:
|
|
127
|
+
self.created_inputs: list[Input] = []
|
|
128
|
+
# Remove all existing children synchronously
|
|
129
|
+
for child in list(inputs_container.children):
|
|
130
|
+
await child.remove()
|
|
131
|
+
except Exception as e:
|
|
132
|
+
self.log(f"Exception clearing inputs container: {e} possibly first time through")
|
|
133
|
+
self.snode_label = snode_label
|
|
134
|
+
await self.get_named_report_spec_details(snode_label)
|
|
135
|
+
|
|
136
|
+
async def get_named_report_spec_details(self, name):
|
|
137
|
+
"""Get the details of a named report spec and render as a flat table.
|
|
138
|
+
|
|
139
|
+
Simplified approach:
|
|
140
|
+
- Normalize the incoming spec to a dict.
|
|
141
|
+
- Recursively walk dicts/lists with a small helper that yields rows.
|
|
142
|
+
- Use a path convention where the first segment is shown in "Attribute",
|
|
143
|
+
the remaining path (if any) is shown in "Value", and the leaf value in
|
|
144
|
+
"Extended Values". This keeps the UI compact while preserving structure.
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
self.spec_name = name
|
|
149
|
+
self.log(f"get_named_report_spec_details: {self.spec_name}")
|
|
150
|
+
selected_report_spec = select_report_spec(self.spec_name, output_type="DICT")
|
|
151
|
+
self.log(f"selected_report_spec: {selected_report_spec}, type: {type(selected_report_spec)}")
|
|
152
|
+
if selected_report_spec == None:
|
|
153
|
+
selected_report_spec = {"NoDetails": "No details found for selected report spec"}
|
|
154
|
+
# Normalize the shape of the returned spec → always a dict
|
|
155
|
+
if isinstance(selected_report_spec, dict) and "data" in selected_report_spec:
|
|
156
|
+
self.extracted_report_spec: dict = selected_report_spec.get("data") or {}
|
|
157
|
+
elif isinstance(selected_report_spec, dict):
|
|
158
|
+
self.extracted_report_spec: dict = selected_report_spec or {}
|
|
159
|
+
else:
|
|
160
|
+
error_text = f"Unknown shape: {selected_report_spec}"
|
|
161
|
+
self.extracted_report_spec = {"Error": error_text}
|
|
162
|
+
|
|
163
|
+
self.log(f"extracted_report_spec: {self.extracted_report_spec}, type: {type(self.extracted_report_spec)}")
|
|
164
|
+
response_data = self.extracted_report_spec
|
|
165
|
+
# Access the datatable used to display report specification attributes
|
|
166
|
+
self.spec_attribute_datatable = self.query_one("#spec_extracted_datatable", DataTable)
|
|
167
|
+
# Ensure columns exist only once
|
|
168
|
+
self.spec_attribute_datatable.clear(columns=True)
|
|
169
|
+
self.spec_attribute_datatable.add_columns("Attribute", "Value", "Extended Values")
|
|
170
|
+
self.spec_attribute_datatable.border = True
|
|
171
|
+
self.spec_attribute_datatable.zebra_stripes = True
|
|
172
|
+
self.spec_attribute_datatable.cursor_type = "row"
|
|
173
|
+
self.spec_attribute_datatable.refresh()
|
|
174
|
+
|
|
175
|
+
# if not response_data or response_data == None or response_data == "":
|
|
176
|
+
if not response_data:
|
|
177
|
+
response_data = {"NoData": "No data found for selected item"}
|
|
178
|
+
if isinstance(response_data, list):
|
|
179
|
+
for list_item in response_data:
|
|
180
|
+
response_data: dict = list_item
|
|
181
|
+
self.log(f"list_item: {list_item}")
|
|
182
|
+
if isinstance(response_data, dict):
|
|
183
|
+
for key, value in response_data.items():
|
|
184
|
+
self.log(f"key: {key}, value: {value}")
|
|
185
|
+
# check for input capable report spec parms
|
|
186
|
+
if key == "required_params" or key == "optional_params" or key == "spec_params" or key == "types":
|
|
187
|
+
self.log(f"Executing populate_input_fields for key: {key}")
|
|
188
|
+
await self.populate_input_fields(key, value)
|
|
189
|
+
self.log(f"populate_input_fields completed for key: {key}")
|
|
190
|
+
self.log(f"key: {key}, value: {value}")
|
|
191
|
+
if isinstance(value, dict):
|
|
192
|
+
for vkey, vvalue in value.items():
|
|
193
|
+
if vkey == "required_params" or vkey == "optional_params" or vkey == "spec_params" or vkey == "types":
|
|
194
|
+
self.log(f"Executing populate_input_fields for key: {vkey}")
|
|
195
|
+
await self.populate_input_fields(vkey, vvalue)
|
|
196
|
+
self.log(f"populate_input_fields completed for key: {vkey}")
|
|
197
|
+
self.log(f"vkey: {vkey}, vvalue: {vvalue}")
|
|
198
|
+
self.spec_attribute_datatable.add_row(vkey, vvalue)
|
|
199
|
+
continue
|
|
200
|
+
elif isinstance(value, list):
|
|
201
|
+
for v in value:
|
|
202
|
+
self.log(f"v: {v}")
|
|
203
|
+
self.spec_attribute_datatable.add_row(key, v)
|
|
204
|
+
continue
|
|
205
|
+
elif key == "kind" and value == "empty":
|
|
206
|
+
key_str = "No Data"
|
|
207
|
+
value_str = "For That Asset Type in this repository"
|
|
208
|
+
self.log(f"key_str: {key_str}, value_str: {value_str}")
|
|
209
|
+
self.spec_attribute_datatable.add_row(key_str, value_str)
|
|
210
|
+
continue
|
|
211
|
+
elif isinstance(value, dict):
|
|
212
|
+
for vkey, vvalue in value.items():
|
|
213
|
+
self.log(f"vkey: {vkey}, vvalue: {vvalue}")
|
|
214
|
+
self.spec_attribute_datatable.add_row(vkey, vvalue)
|
|
215
|
+
continue
|
|
216
|
+
else:
|
|
217
|
+
self.log(f"else: key {key} value: {value}")
|
|
218
|
+
self.spec_attribute_datatable.add_row(key, value)
|
|
219
|
+
continue
|
|
220
|
+
elif isinstance(response_data, dict):
|
|
221
|
+
for key, value in response_data.items():
|
|
222
|
+
self.log(f"key: {key}, value: {value}")
|
|
223
|
+
if key == "required_params" or key == "optional_params" or key == "spec_params" or key == "types":
|
|
224
|
+
self.log(f"Executing populate_input_fields for key: {key}")
|
|
225
|
+
await self.populate_input_fields(key, value)
|
|
226
|
+
self.log(f"populate_input_fields completed for key: {key}")
|
|
227
|
+
if isinstance(value, dict):
|
|
228
|
+
for vkey, vvalue in value.items():
|
|
229
|
+
if vkey == "required_params" or vkey == "optional_params" or vkey == "spec_params" or vkey == "types":
|
|
230
|
+
self.log(f"Executing populate_input_fields for key: {vkey}")
|
|
231
|
+
await self.populate_input_fields(vkey, vvalue)
|
|
232
|
+
self.log(f"populate_input_fields completed for key: {vkey}")
|
|
233
|
+
self.spec_attribute_datatable.add_row(vkey, vvalue)
|
|
234
|
+
continue
|
|
235
|
+
elif isinstance(value, list):
|
|
236
|
+
for v in value:
|
|
237
|
+
self.spec_attribute_datatable.add_row(key, v)
|
|
238
|
+
continue
|
|
239
|
+
elif key == "kind" and value == "empty":
|
|
240
|
+
key_str = "No Data"
|
|
241
|
+
value_str = "For That Asset Type in this repository"
|
|
242
|
+
self.spec_attribute_datatable.add_row(key_str, value_str)
|
|
243
|
+
continue
|
|
244
|
+
else:
|
|
245
|
+
self.spec_attribute_datatable.add_row(key, value)
|
|
246
|
+
continue
|
|
247
|
+
|
|
248
|
+
self.spec_attribute_datatable.refresh()
|
|
249
|
+
mount_point = self.query_one("#container2", Container)
|
|
250
|
+
await mount_point.mount(self.spec_attribute_datatable, before="#two_end")
|
|
251
|
+
return
|
|
252
|
+
|
|
253
|
+
async def execute_selected_report_spec(self, selected_name: str = "", additional_parameters: dict = None):
|
|
254
|
+
""" execute the selected report spec """
|
|
255
|
+
self.selected_name = selected_name
|
|
256
|
+
self.additional_parameters = additional_parameters
|
|
257
|
+
output_form = "DICT"
|
|
258
|
+
if len(self.additional_parameters) > 0:
|
|
259
|
+
self.log(f"additional_parameters: {self.additional_parameters}")
|
|
260
|
+
else:
|
|
261
|
+
self.log(f"No additional parameters provided")
|
|
262
|
+
self.additional_parameters = {}
|
|
263
|
+
if self.additional_parameters != None:
|
|
264
|
+
if "inp_types" in self.additional_parameters:
|
|
265
|
+
output_form = self.additional_parameters["inp_types"]
|
|
266
|
+
|
|
267
|
+
self.log(f"Executing report spec: {self.selected_name}")
|
|
268
|
+
try:
|
|
269
|
+
reponse = exec_report_spec(format_set_name=selected_name,
|
|
270
|
+
output_format=output_form,
|
|
271
|
+
view_server=self.view_server,
|
|
272
|
+
view_url=self.platform_url,
|
|
273
|
+
user=self.user,
|
|
274
|
+
user_pass=self.password,
|
|
275
|
+
params=self.additional_parameters,
|
|
276
|
+
)
|
|
277
|
+
self.log(f"Return from exec_report_spec:")
|
|
278
|
+
self.log(f"reponse: {reponse}")
|
|
279
|
+
except (ValidationError) as e:
|
|
280
|
+
self.log(f"ValidationError: {e}")
|
|
281
|
+
reponse = {"error": f"ValidationError: {e}"}
|
|
282
|
+
except Exception as e:
|
|
283
|
+
self.log(f"Exception: {e}")
|
|
284
|
+
reponse = {"error": f"Exception: {e}"}
|
|
285
|
+
await self.display_response(reponse)
|
|
286
|
+
|
|
287
|
+
async def display_response(self, response):
|
|
288
|
+
""" Display the response from executing the selected report spec"""
|
|
289
|
+
self.response = response
|
|
290
|
+
# create and/or clear datatable for displaying data
|
|
291
|
+
self.spec_output_datatable = self.query_one("#spec_output_datatable", DataTable)
|
|
292
|
+
self.spec_output_datatable.clear(columns=True)
|
|
293
|
+
self.log(f"self.spec_output_datatable : {self.spec_output_datatable} has been created")
|
|
294
|
+
# self.spec_output_datatable.id = "spec_output_datatable"
|
|
295
|
+
self.log(f"self.spec_output_datatable has been assigned an id : {self.spec_output_datatable.id} ")
|
|
296
|
+
# extract data payload from response["data"]. Then populate variables for display
|
|
297
|
+
if isinstance(self.response, dict) and "data" in self.response:
|
|
298
|
+
self.response_data = self.response.get("data")
|
|
299
|
+
elif isinstance(self.response, dict):
|
|
300
|
+
self.response_data = self.response
|
|
301
|
+
elif isinstance(self.response, list):
|
|
302
|
+
self.response_data = self.response
|
|
303
|
+
else:
|
|
304
|
+
self.response_data = [{"NoData": "No data found for selected item", "Data Content": self.response}]
|
|
305
|
+
|
|
306
|
+
self.rotated_table.clear()
|
|
307
|
+
if isinstance(self.response_data, list):
|
|
308
|
+
for list_item in self.response_data:
|
|
309
|
+
response_dict = list_item if isinstance(list_item, dict) else {"Value": list_item}
|
|
310
|
+
self.log(f"list_item: {list_item}")
|
|
311
|
+
for key, value in response_dict.items():
|
|
312
|
+
self.log(f"key: {key}, value: {value}")
|
|
313
|
+
if isinstance(value, dict):
|
|
314
|
+
for vkey, vvalue in value.items():
|
|
315
|
+
self.log(f"vkey: {vkey}, vvalue: {vvalue}")
|
|
316
|
+
self.rotated_table.setdefault(str(vkey), []).append(vvalue)
|
|
317
|
+
elif isinstance(value, list):
|
|
318
|
+
for v in value:
|
|
319
|
+
self.log(f"v: {v}")
|
|
320
|
+
self.rotated_table.setdefault(str(v), []).append(" ")
|
|
321
|
+
elif key == "kind" and value == "empty":
|
|
322
|
+
key_str: str = "NoData"
|
|
323
|
+
message: str = "For That Asset Type in this repository"
|
|
324
|
+
self.log(f"key_str: {key_str}, value_str: {message}")
|
|
325
|
+
# Present a single consolidated message row under NoData
|
|
326
|
+
self.rotated_table[key_str] = [message]
|
|
327
|
+
else:
|
|
328
|
+
self.log(f"else: key {key} value: {value}")
|
|
329
|
+
self.rotated_table.setdefault(str(key), []).append(value)
|
|
330
|
+
elif isinstance(self.response_data, dict):
|
|
331
|
+
for key, value in self.response_data.items():
|
|
332
|
+
self.log(f"key: {key}, value: {value}")
|
|
333
|
+
if key == "kind":
|
|
334
|
+
continue
|
|
335
|
+
elif isinstance(value, dict):
|
|
336
|
+
for vkey, vvalue in value.items():
|
|
337
|
+
self.rotated_table.setdefault(str(vkey), []).append(vvalue)
|
|
338
|
+
elif isinstance(value, list):
|
|
339
|
+
for v in value:
|
|
340
|
+
self.rotated_table.setdefault(str(v), []).append(" ")
|
|
341
|
+
elif key == "kind" and value == "empty":
|
|
342
|
+
key_str = "NoData"
|
|
343
|
+
message = "For That Asset Type in this repository"
|
|
344
|
+
self.log(f"key_str: {key_str}, value_str: {message}")
|
|
345
|
+
# Present a single consolidated message row under NoData
|
|
346
|
+
self.rotated_table[key_str] = [message]
|
|
347
|
+
else:
|
|
348
|
+
self.rotated_table.setdefault(str(key), []).append(value)
|
|
349
|
+
# now the rotated table is loaded with data, create the datatable
|
|
350
|
+
keys = list(self.rotated_table.keys())
|
|
351
|
+
for col_key in keys:
|
|
352
|
+
self.spec_output_datatable.add_column(str(col_key))
|
|
353
|
+
max_rows = max((len(self.rotated_table[k]) for k in keys), default=0)
|
|
354
|
+
for row_idx in range(max_rows):
|
|
355
|
+
row = [str(self.rotated_table[k][row_idx]) if row_idx < len(self.rotated_table[k]) else "" for k in keys]
|
|
356
|
+
self.spec_output_datatable.add_row(*row)
|
|
357
|
+
|
|
358
|
+
# Always refresh after populating
|
|
359
|
+
self.spec_output_datatable.refresh()
|
|
360
|
+
mount_point = self.query_one("#container3", Container)
|
|
361
|
+
await mount_point.mount(self.spec_output_datatable, before="#three_end")
|
|
362
|
+
return
|
|
363
|
+
|
|
364
|
+
async def populate_input_fields(self, key, value):
|
|
365
|
+
"""Create interactive input rows for required/optional params."""
|
|
366
|
+
self.key = key
|
|
367
|
+
self.input = value
|
|
368
|
+
inp_value: Any = None
|
|
369
|
+
inputs_container = self.query_one("#input_fields", Container)
|
|
370
|
+
|
|
371
|
+
def safe_id(s: str) -> str:
|
|
372
|
+
return re.sub(r"[^0-9a-zA-Z_-]", "_", s)
|
|
373
|
+
|
|
374
|
+
self.created_inputs: list[Input] = []
|
|
375
|
+
# reset tracker for this render; we'll repopulate with the current inputs
|
|
376
|
+
self.inputs_tracker.clear()
|
|
377
|
+
|
|
378
|
+
# Build rows according to incoming shape
|
|
379
|
+
if isinstance(self.input, dict):
|
|
380
|
+
items = list(self.input.items())
|
|
381
|
+
for ikey, ivalue in items:
|
|
382
|
+
row = HorizontalScroll(id=f"input_row_{safe_id(str(ikey))}")
|
|
383
|
+
await inputs_container.mount(row)
|
|
384
|
+
await row.mount(Label(f"{ikey}:"))
|
|
385
|
+
self.log(f"Processing input field: {ikey}")
|
|
386
|
+
if ikey == "search_string":
|
|
387
|
+
inp_value = "*"
|
|
388
|
+
elif ikey == "page_size":
|
|
389
|
+
inp_value = '0'
|
|
390
|
+
elif ikey == "start_from":
|
|
391
|
+
inp_value = '0'
|
|
392
|
+
elif ikey == "starts_with":
|
|
393
|
+
inp_value = "True"
|
|
394
|
+
elif ikey == "ends_with":
|
|
395
|
+
inp_value = "False"
|
|
396
|
+
elif ikey == "ignore_case":
|
|
397
|
+
inp_value = "False"
|
|
398
|
+
elif ikey == "output_format":
|
|
399
|
+
inp_value = "DICT"
|
|
400
|
+
else:
|
|
401
|
+
inp_value = ""
|
|
402
|
+
inp = Input(value=inp_value, placeholder=str(ivalue), id=f"inp_{safe_id(str(ikey))}", classes="spaced")
|
|
403
|
+
await row.mount(inp)
|
|
404
|
+
self.created_inputs.append(inp)
|
|
405
|
+
# Track by input id so events can update values reliably
|
|
406
|
+
self.inputs_tracker[inp.id] = [str(ikey), ""]
|
|
407
|
+
elif isinstance(self.input, list):
|
|
408
|
+
# Special-case for types: just display info text
|
|
409
|
+
if key == "types":
|
|
410
|
+
row = Horizontal(id=f"input_row_{safe_id(str(key))}")
|
|
411
|
+
await inputs_container.mount(row)
|
|
412
|
+
await row.mount(Label("Output Format:"))
|
|
413
|
+
await row.mount(Input(value="DICT", placeholder="DICT", id=f"inp_{safe_id(str(key))}", classes="spaced"))
|
|
414
|
+
# informational only; no input to track
|
|
415
|
+
else:
|
|
416
|
+
for list_item in self.input:
|
|
417
|
+
label = str(list_item)
|
|
418
|
+
row = Horizontal(id=f"input_row_{safe_id(label)}")
|
|
419
|
+
await inputs_container.mount(row)
|
|
420
|
+
await row.mount(Label(f"{label}:"))
|
|
421
|
+
self.log(f"Processing input field: {label}")
|
|
422
|
+
if label == "search_string":
|
|
423
|
+
inp_value = "*"
|
|
424
|
+
elif label == "page_size":
|
|
425
|
+
inp_value = '0'
|
|
426
|
+
elif label == "start_from":
|
|
427
|
+
inp_value = '0'
|
|
428
|
+
elif label == "starts_with":
|
|
429
|
+
inp_value = "True"
|
|
430
|
+
elif label == "ends_with":
|
|
431
|
+
inp_value = "False"
|
|
432
|
+
elif label == "ignore_case":
|
|
433
|
+
inp_value = "False"
|
|
434
|
+
elif label == "output_format":
|
|
435
|
+
inp_value = "DICT"
|
|
436
|
+
else:
|
|
437
|
+
inp_value = ""
|
|
438
|
+
inp = Input(value=inp_value, placeholder="", id=f"inp_{safe_id(label)}")
|
|
439
|
+
await row.mount(inp)
|
|
440
|
+
self.created_inputs.append(inp)
|
|
441
|
+
# Track with a reasonable parameter name for list entries
|
|
442
|
+
self.inputs_tracker[inp.id] = [label, ""]
|
|
443
|
+
else:
|
|
444
|
+
# Unknown shape: show a message
|
|
445
|
+
row = Horizontal(id=f"input_row_{safe_id(str(key))}")
|
|
446
|
+
await inputs_container.mount(row)
|
|
447
|
+
await row.mount(Label(f"Error, Unknown Shape for {key}: {value}"))
|
|
448
|
+
|
|
449
|
+
# Give focus to the first input if any
|
|
450
|
+
if self.created_inputs:
|
|
451
|
+
self.created_inputs[0].focus()
|
|
452
|
+
|
|
453
|
+
# Refresh the container
|
|
454
|
+
inputs_container.refresh()
|
|
455
|
+
return
|
|
456
|
+
|
|
457
|
+
@on(Input.Changed, "#input_fields Input")
|
|
458
|
+
async def handle_input_changed(self, event: Input.Changed) -> None:
|
|
459
|
+
"""Update the tracker whenever an input changes.
|
|
460
|
+
|
|
461
|
+
We key the tracker by the actual Input id and store [param_name, value].
|
|
462
|
+
"""
|
|
463
|
+
input_id = event.input.id
|
|
464
|
+
value = event.value or ""
|
|
465
|
+
# Initialize if missing (defensive)
|
|
466
|
+
if input_id not in self.inputs_tracker:
|
|
467
|
+
# Default param name falls back to the visible label-less id
|
|
468
|
+
self.inputs_tracker[input_id] = [input_id, value]
|
|
469
|
+
else:
|
|
470
|
+
self.inputs_tracker[input_id][1] = value
|
|
471
|
+
self.log(f"Changed: {input_id} -> {value}")
|
|
472
|
+
return
|
|
473
|
+
|
|
474
|
+
@on(Button.Pressed, "#quit")
|
|
475
|
+
def handle_quit(self, event: Button.Pressed) -> None:
|
|
476
|
+
self.exit(200)
|
|
477
|
+
|
|
478
|
+
def action_quit(self):
|
|
479
|
+
self.exit(200)
|
|
480
|
+
|
|
481
|
+
async def action_prepare_report(self):
|
|
482
|
+
# Build additional parameters from current inputs
|
|
483
|
+
self.new_additional_parameters = {}
|
|
484
|
+
self.additional_parameters = {}
|
|
485
|
+
if self.inputs_tracker:
|
|
486
|
+
self.log(f"self.inputs_tracker: {self.inputs_tracker}")
|
|
487
|
+
for _, (parm_name, parm_value) in self.inputs_tracker.items():
|
|
488
|
+
self.additional_parameters[parm_name] = parm_value
|
|
489
|
+
self.log(f"additional_parameters: {self.additional_parameters}")
|
|
490
|
+
# run report when input fields completed
|
|
491
|
+
# iterate and strip the inp_ from the front of the key values if present
|
|
492
|
+
for key, value in self.additional_parameters.items():
|
|
493
|
+
new_key:str = key.removeprefix("inp_")
|
|
494
|
+
self.new_additional_parameters.update({new_key: value})
|
|
495
|
+
self.additional_parameters.clear()
|
|
496
|
+
# change the types key to output_format if present fior inclusion in parameters dict
|
|
497
|
+
value = self.new_additional_parameters.get("types")
|
|
498
|
+
if value:
|
|
499
|
+
self.new_additional_parameters.update({"output_format": value})
|
|
500
|
+
else:
|
|
501
|
+
self.new_additional_parameters.update({"output_format": "DICT"})
|
|
502
|
+
self.log (f"new_additional_parameters: {self.new_additional_parameters}")
|
|
503
|
+
self.additional_parameters = self.new_additional_parameters
|
|
504
|
+
self.log(f"additional_parameters trimmed: {self.additional_parameters}")
|
|
505
|
+
# Retrieve the output_format value
|
|
506
|
+
output_form = self.additional_parameters.get("output_format", "FORM")
|
|
507
|
+
self.log(f"output_format: {output_form}")
|
|
508
|
+
# if output_format is FORM, we write the report output to a file
|
|
509
|
+
# if not then we execute the report spec and display the output on the screen
|
|
510
|
+
if output_form == "FORM":
|
|
511
|
+
await self.report_to_file(self.snode_label, self.additional_parameters)
|
|
512
|
+
else:
|
|
513
|
+
await self.execute_selected_report_spec(self.snode_label, self.additional_parameters)
|
|
514
|
+
return
|
|
515
|
+
|
|
516
|
+
async def report_to_file(self, selected_name: str = "", additional_parameters: dict = None):
|
|
517
|
+
""" execute the selected report spec """
|
|
518
|
+
# self.selected_name = selected_name
|
|
519
|
+
# self.additional_parameters = additional_parameters
|
|
520
|
+
my_additional_parameters: dict = additional_parameters
|
|
521
|
+
output_form = "FORM"
|
|
522
|
+
if len(my_additional_parameters) > 0:
|
|
523
|
+
self.log(f"additional_parameters: {my_additional_parameters}")
|
|
524
|
+
if "output_format" in my_additional_parameters:
|
|
525
|
+
output_form = my_additional_parameters.get("output_format")
|
|
526
|
+
del my_additional_parameters["output_format"]
|
|
527
|
+
else:
|
|
528
|
+
output_form = "FORM"
|
|
529
|
+
else:
|
|
530
|
+
self.log(f"No additional parameters provided")
|
|
531
|
+
my_additional_parameters = {}
|
|
532
|
+
|
|
533
|
+
self.log(f"Executing report spec: {selected_name}")
|
|
534
|
+
try:
|
|
535
|
+
reponse = list_generic(report_spec=selected_name,
|
|
536
|
+
output_format=output_form,
|
|
537
|
+
view_server=self.view_server,
|
|
538
|
+
view_url=self.platform_url,
|
|
539
|
+
user=self.user,
|
|
540
|
+
user_pass=self.password,
|
|
541
|
+
params=my_additional_parameters,
|
|
542
|
+
write_file=True
|
|
543
|
+
)
|
|
544
|
+
self.log(f"Return from exec_report_spec:")
|
|
545
|
+
self.log(f"reponse: {reponse}")
|
|
546
|
+
except (ValidationError) as e:
|
|
547
|
+
self.log(f"ValidationError: {e}")
|
|
548
|
+
reponse = {"error": f"ValidationError: {e}"}
|
|
549
|
+
except Exception as e:
|
|
550
|
+
self.log(f"Exception: {e}")
|
|
551
|
+
reponse = {"error": f"Exception: {e}"}
|
|
552
|
+
await self.display_response(reponse)
|
|
553
|
+
|
|
554
|
+
def start_exp2():
|
|
555
|
+
app = RunSpec()
|
|
556
|
+
app.run()
|
|
557
|
+
|
|
558
|
+
if __name__ == "__main__":
|
|
559
|
+
start_exp2()
|