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,643 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generate report FormatSet specifications for pyegeria from a commands.json file.
|
|
3
|
+
|
|
4
|
+
Overview
|
|
5
|
+
- This utility reads a Dr Egeria style commands.json (aka Command Specifications)
|
|
6
|
+
and converts relevant entries (by default, only those with a display name
|
|
7
|
+
beginning with "Create") into pyegeria FormatSet definitions. These can be:
|
|
8
|
+
- returned in-memory as a FormatSetDict
|
|
9
|
+
- saved to a JSON file that can be loaded by pyegeria.base_report_formats.load_report_specs
|
|
10
|
+
- saved as a Python module that defines a dictionary of FormatSet objects
|
|
11
|
+
- merged directly into the built-in report_specs registry at runtime
|
|
12
|
+
|
|
13
|
+
Typical uses
|
|
14
|
+
- Quickly scaffold report formats for new content types defined in your command
|
|
15
|
+
specifications, without hand-writing every Column/Format block.
|
|
16
|
+
- Keep generated formats alongside your hand-curated ones and iterate as the
|
|
17
|
+
command specifications evolve.
|
|
18
|
+
|
|
19
|
+
What this script extracts
|
|
20
|
+
- Target type: from each command's display_name
|
|
21
|
+
- Columns: only attributes marked with level == "Basic" are included. The
|
|
22
|
+
column name comes from the attribute label; the column key from the
|
|
23
|
+
attribute's variable_name.
|
|
24
|
+
- Action parameter: if a find_method is present on the command, an ActionParameter
|
|
25
|
+
is created with:
|
|
26
|
+
- function = find_method
|
|
27
|
+
- required_params = ["search_string"]
|
|
28
|
+
- optional_params = pyegeria.base_report_formats.OPTIONAL_PARAMS
|
|
29
|
+
- spec_params = parsed find_constraints (see parsing notes below)
|
|
30
|
+
|
|
31
|
+
Constraints parsing
|
|
32
|
+
- find_constraints may be a dict or a JSON string (sometimes double-escaped).
|
|
33
|
+
We try, in order: direct JSON, unquoted JSON, and a simple single-to-double
|
|
34
|
+
quote substitution for dict-like strings. Failures yield an empty dict, and
|
|
35
|
+
a debug message is logged.
|
|
36
|
+
|
|
37
|
+
Naming
|
|
38
|
+
- Each FormatSet key and heading are derived from the command's display_name.
|
|
39
|
+
The key is display_name with spaces replaced by '-' and suffixed with '-DrE'.
|
|
40
|
+
Example: "Create Governance Strategy Definition" -> "Create-Governance-Strategy-Definition-DrE".
|
|
41
|
+
|
|
42
|
+
CLI usage examples
|
|
43
|
+
- Save to JSON (default mode):
|
|
44
|
+
poetry run python -m md_processing.md_processing_utils.gen_report_specs \
|
|
45
|
+
md_processing/data/commands.json md_processing/data/generated_format_sets.json --emit json
|
|
46
|
+
|
|
47
|
+
- Emit Python code to a .py file:
|
|
48
|
+
poetry run python -m md_processing.md_processing_utils.gen_report_specs \
|
|
49
|
+
md_processing/data/commands.json md_processing/data/generated_report_specs.py --emit code
|
|
50
|
+
|
|
51
|
+
- Build in-memory only and list set names:
|
|
52
|
+
poetry run python -m md_processing.md_processing_utils.gen_report_specs \
|
|
53
|
+
md_processing/data/commands.json --emit dict --list
|
|
54
|
+
|
|
55
|
+
- Merge generated sets into the built-in registry (report_specs):
|
|
56
|
+
poetry run python -m md_processing.md_processing_utils.gen_report_specs \
|
|
57
|
+
md_processing/data/commands.json --emit dict --merge --list
|
|
58
|
+
|
|
59
|
+
Programmatic usage
|
|
60
|
+
- Build in memory:
|
|
61
|
+
from md_processing.md_processing_utils.gen_report_specs import generate_format_sets
|
|
62
|
+
sets = generate_format_sets("md_processing/data/commands.json")
|
|
63
|
+
|
|
64
|
+
- Save JSON that can be loaded by pyegeria:
|
|
65
|
+
from md_processing.md_processing_utils.gen_report_specs import save_generated_format_sets
|
|
66
|
+
save_generated_format_sets("md_processing/data/commands.json", "md_processing/data/generated_format_sets.json")
|
|
67
|
+
|
|
68
|
+
- Save as importable Python module:
|
|
69
|
+
from md_processing.md_processing_utils.gen_report_specs import save_generated_format_sets_code
|
|
70
|
+
save_generated_format_sets_code("md_processing/data/commands.json", "md_processing/data/generated_report_specs.py")
|
|
71
|
+
|
|
72
|
+
- Merge directly into built-ins at runtime:
|
|
73
|
+
from md_processing.md_processing_utils.gen_report_specs import merge_generated_report_specs
|
|
74
|
+
merge_generated_format_sets("md_processing/data/commands.json")
|
|
75
|
+
|
|
76
|
+
Notes
|
|
77
|
+
- Only commands whose key or display_name begins with "Create" are included by
|
|
78
|
+
default. Pass include_only_create=False to include all commands.
|
|
79
|
+
- default_types controls the Format.types field, and defaults to ["ALL"].
|
|
80
|
+
- This script logs progress with loguru.
|
|
81
|
+
"""
|
|
82
|
+
import json
|
|
83
|
+
import re
|
|
84
|
+
import argparse
|
|
85
|
+
from pathlib import Path
|
|
86
|
+
from typing import Iterable, List, Optional
|
|
87
|
+
|
|
88
|
+
from loguru import logger
|
|
89
|
+
from rich.prompt import Prompt
|
|
90
|
+
|
|
91
|
+
from pyegeria.view._output_format_models import Column, Format, ActionParameter, FormatSet, FormatSetDict
|
|
92
|
+
from pyegeria.view.base_report_formats import OPTIONAL_PARAMS # ["page_size","start_from","starts_with","ends_with","ignore_case"]
|
|
93
|
+
|
|
94
|
+
def _is_create_command(cmd_key: str, cmd_obj: dict) -> bool:
|
|
95
|
+
"""Return True if a command should be treated as a "Create" command.
|
|
96
|
+
|
|
97
|
+
A command qualifies if either its dictionary key or its "display_name"
|
|
98
|
+
begins with the word "Create" (case-insensitive). This mirrors how the
|
|
99
|
+
CLI specs tend to name creation operations and is used to filter which
|
|
100
|
+
commands are transformed into report FormatSets by default.
|
|
101
|
+
"""
|
|
102
|
+
name = str(cmd_obj.get("display_name", "")).strip()
|
|
103
|
+
return (isinstance(cmd_key, str) and cmd_key.strip().lower().startswith("create")) or \
|
|
104
|
+
(name.lower().startswith("create"))
|
|
105
|
+
|
|
106
|
+
def _derive_set_name_from_display_name(display_name: str) -> str:
|
|
107
|
+
"""Derive a compact set name from a command display name.
|
|
108
|
+
|
|
109
|
+
Example: 'Create Governance Strategy Definition' -> 'GovernanceStrategyDefinition-DrE'
|
|
110
|
+
Currently not used in favor of a dash-separated variant, but kept for
|
|
111
|
+
reference and potential future toggles.
|
|
112
|
+
"""
|
|
113
|
+
if not display_name:
|
|
114
|
+
return ""
|
|
115
|
+
parts = display_name.strip().split()
|
|
116
|
+
if len(parts) <= 1:
|
|
117
|
+
return re.sub(r"\s+", "", display_name.strip())+"-DrE"
|
|
118
|
+
rest = " ".join(parts[1:]).strip()
|
|
119
|
+
rest = rest+"-DrE"
|
|
120
|
+
return re.sub(r"\s+", "", rest)
|
|
121
|
+
|
|
122
|
+
def _safe_parse_constraints(s) -> dict:
|
|
123
|
+
"""Parse a command's `find_constraints` field into a Python dict.
|
|
124
|
+
|
|
125
|
+
Accepts:
|
|
126
|
+
- A dict (returned as-is)
|
|
127
|
+
- A JSON string (possibly surrounded by quotes or single-quoted)
|
|
128
|
+
- A loosely dict-like string using single quotes
|
|
129
|
+
|
|
130
|
+
Returns an empty dict on failure and logs at debug level.
|
|
131
|
+
"""
|
|
132
|
+
if not s:
|
|
133
|
+
return {}
|
|
134
|
+
if isinstance(s, dict):
|
|
135
|
+
return s
|
|
136
|
+
txt = str(s).strip()
|
|
137
|
+
# Attempt 1: direct JSON
|
|
138
|
+
try:
|
|
139
|
+
return json.loads(txt)
|
|
140
|
+
except Exception:
|
|
141
|
+
logger.error(f"Error parsing constraints: {s!r}")
|
|
142
|
+
pass
|
|
143
|
+
# Attempt 2: unwrap quotes
|
|
144
|
+
try:
|
|
145
|
+
txt2 = txt.strip('"').strip("'")
|
|
146
|
+
return json.loads(txt2)
|
|
147
|
+
except Exception:
|
|
148
|
+
pass
|
|
149
|
+
# Attempt 3: heuristic single->double quotes for dict-like strings
|
|
150
|
+
if ("{" in txt and "}" in txt) and ("'" in txt and '"' not in txt):
|
|
151
|
+
try:
|
|
152
|
+
return json.loads(txt.replace("'", '"'))
|
|
153
|
+
except Exception:
|
|
154
|
+
pass
|
|
155
|
+
logger.debug(f"Could not parse find_constraints: {s!r} -> {{}}")
|
|
156
|
+
return {}
|
|
157
|
+
|
|
158
|
+
def _extract_basic_columns_from_attributes(attributes: Iterable[dict]) -> List[Column]:
|
|
159
|
+
"""Extract Basic-level Columns from a command's Attributes list.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
- attributes: iterable of dict entries. Each entry is typically a single-key
|
|
163
|
+
mapping of attribute label -> metadata dict with fields like
|
|
164
|
+
{"variable_name": ..., "level": "Basic"|"Advanced"|...}.
|
|
165
|
+
|
|
166
|
+
Behavior
|
|
167
|
+
- Only items with level == "Basic" are included
|
|
168
|
+
- Duplicate variable_name values are de-duplicated
|
|
169
|
+
- Column.name is the label; Column.key is the variable_name
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
- List[Column]
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
cols: List[Column] = []
|
|
176
|
+
seen: set[str] = set()
|
|
177
|
+
for entry in attributes or []:
|
|
178
|
+
if not isinstance(entry, dict) or not entry:
|
|
179
|
+
continue
|
|
180
|
+
# Some entries may contain more than one key; scan all items
|
|
181
|
+
for label, details in entry.items():
|
|
182
|
+
if not isinstance(details, dict):
|
|
183
|
+
continue
|
|
184
|
+
if details.get("level") != "Basic":
|
|
185
|
+
continue
|
|
186
|
+
key = details.get("variable_name")
|
|
187
|
+
if not key or key in seen:
|
|
188
|
+
continue
|
|
189
|
+
seen.add(key)
|
|
190
|
+
cols.append(Column(name=str(label), key=str(key)))
|
|
191
|
+
return cols
|
|
192
|
+
|
|
193
|
+
def build_format_sets_from_commands(
|
|
194
|
+
commands_json_path: str | Path,
|
|
195
|
+
*,
|
|
196
|
+
include_only_create: bool = True,
|
|
197
|
+
default_types: Optional[List[str]] = None
|
|
198
|
+
) -> FormatSetDict:
|
|
199
|
+
"""Build a FormatSetDict from a commands.json file.
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
- commands_json_path: path to the Dr Egeria style commands.json file. The
|
|
203
|
+
file may be an object with a "Command Specifications" map, or a list of
|
|
204
|
+
command objects.
|
|
205
|
+
- include_only_create: when True (default), include only commands whose key
|
|
206
|
+
or display_name starts with "Create".
|
|
207
|
+
- default_types: the list used for Format.types for each produced Format
|
|
208
|
+
(defaults to ["ALL"]).
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
- FormatSetDict keyed by set names derived from display_name + "-DrE".
|
|
212
|
+
|
|
213
|
+
Notes
|
|
214
|
+
- Columns are derived from Attributes entries whose level == "Basic".
|
|
215
|
+
- If find_method is present, an ActionParameter is created.
|
|
216
|
+
"""
|
|
217
|
+
path = Path(commands_json_path)
|
|
218
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
219
|
+
|
|
220
|
+
if isinstance(data, dict):
|
|
221
|
+
items_iter = data.items()
|
|
222
|
+
elif isinstance(data, list):
|
|
223
|
+
# If it’s a list of command objects, synthesize keys from display_name or index
|
|
224
|
+
def _key_for(idx, obj):
|
|
225
|
+
dn = str(obj.get("display_name", "")).strip()
|
|
226
|
+
return dn or f"cmd_{idx}"
|
|
227
|
+
|
|
228
|
+
items_iter = ((_key_for(i, obj), obj) for i, obj in enumerate(data))
|
|
229
|
+
else:
|
|
230
|
+
raise ValueError("commands.json root must be an object/dict or an array of command objects")
|
|
231
|
+
data = dict(items_iter).get("Command Specifications", {})
|
|
232
|
+
logger.info(
|
|
233
|
+
f"Loaded commands.json from {path} with {len(data)} commands"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
results = FormatSetDict()
|
|
238
|
+
types = default_types or ["ALL"]
|
|
239
|
+
|
|
240
|
+
for cmd_key, cmd_obj in data.items():
|
|
241
|
+
if not isinstance(cmd_obj, dict):
|
|
242
|
+
continue
|
|
243
|
+
if include_only_create and not _is_create_command(cmd_key, cmd_obj):
|
|
244
|
+
continue
|
|
245
|
+
|
|
246
|
+
display_name = str(cmd_obj.get("display_name", "")).strip()
|
|
247
|
+
if not display_name:
|
|
248
|
+
logger.debug(f"Skip {cmd_key!r}: missing display_name")
|
|
249
|
+
continue
|
|
250
|
+
set_name = re.sub(r"\s+", "-", display_name)
|
|
251
|
+
set_name = set_name.strip() + "-DrE"
|
|
252
|
+
# set_name = _derive_set_name_from_display_name(display_name)
|
|
253
|
+
if not set_name:
|
|
254
|
+
logger.debug(f"Skip {cmd_key!r}: could not derive set name from display_name={display_name!r}")
|
|
255
|
+
continue
|
|
256
|
+
|
|
257
|
+
columns = _extract_basic_columns_from_attributes(cmd_obj.get("Attributes", []))
|
|
258
|
+
if not columns:
|
|
259
|
+
logger.debug(f"Skip {set_name}: no Basic attributes")
|
|
260
|
+
continue
|
|
261
|
+
|
|
262
|
+
find_method = cmd_obj.get("find_method") or ""
|
|
263
|
+
constraints = _safe_parse_constraints(cmd_obj.get("find_constraints"))
|
|
264
|
+
action = None
|
|
265
|
+
if find_method:
|
|
266
|
+
action = ActionParameter(
|
|
267
|
+
function=find_method,
|
|
268
|
+
required_params=["search_string"],
|
|
269
|
+
optional_params=OPTIONAL_PARAMS,
|
|
270
|
+
spec_params=constraints or {},
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
fs = FormatSet(
|
|
274
|
+
target_type=display_name,
|
|
275
|
+
heading=f"{set_name} Attributes",
|
|
276
|
+
description=f"Auto-generated format for {display_name} (Create).",
|
|
277
|
+
family=cmd_obj.get("family"),
|
|
278
|
+
formats=[Format(types=types, columns=columns)],
|
|
279
|
+
action=action
|
|
280
|
+
)
|
|
281
|
+
results[set_name] = fs
|
|
282
|
+
|
|
283
|
+
return results
|
|
284
|
+
|
|
285
|
+
def save_generated_format_sets(
|
|
286
|
+
commands_json_path: str | Path,
|
|
287
|
+
out_file: str | Path,
|
|
288
|
+
*,
|
|
289
|
+
include_only_create: bool = True,
|
|
290
|
+
default_types: Optional[List[str]] = None
|
|
291
|
+
) -> Path:
|
|
292
|
+
"""Build FormatSets from commands.json and save them as JSON.
|
|
293
|
+
|
|
294
|
+
The resulting JSON can be loaded via `pyegeria.base_report_formats.load_report_specs`.
|
|
295
|
+
|
|
296
|
+
Parameters
|
|
297
|
+
- commands_json_path: input commands.json path
|
|
298
|
+
- out_file: where to write the generated JSON
|
|
299
|
+
- include_only_create: filter to only "Create" commands (default True)
|
|
300
|
+
- default_types: list for Format.types (default ["ALL"]).
|
|
301
|
+
|
|
302
|
+
Returns
|
|
303
|
+
- Path to the written JSON file
|
|
304
|
+
"""
|
|
305
|
+
sets = build_format_sets_from_commands(
|
|
306
|
+
commands_json_path,
|
|
307
|
+
include_only_create=include_only_create,
|
|
308
|
+
default_types=default_types,
|
|
309
|
+
)
|
|
310
|
+
out = Path(out_file)
|
|
311
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
|
312
|
+
sets.save_to_json(str(out))
|
|
313
|
+
logger.info(f"Saved {len(sets)} generated format sets to {out}")
|
|
314
|
+
return out
|
|
315
|
+
|
|
316
|
+
# New: expose a simple alias that returns a FormatSetDict directly
|
|
317
|
+
# for callers that want the in-memory object rather than JSON.
|
|
318
|
+
def generate_format_sets(
|
|
319
|
+
commands_json_path: str | Path,
|
|
320
|
+
*,
|
|
321
|
+
include_only_create: bool = True,
|
|
322
|
+
default_types: Optional[List[str]] = None,
|
|
323
|
+
):
|
|
324
|
+
"""Return a FormatSetDict built from commands.json (no file I/O).
|
|
325
|
+
|
|
326
|
+
This is a convenience wrapper around `build_format_sets_from_commands` for
|
|
327
|
+
programmatic use when you don't want to touch the filesystem.
|
|
328
|
+
"""
|
|
329
|
+
return build_format_sets_from_commands(
|
|
330
|
+
commands_json_path,
|
|
331
|
+
include_only_create=include_only_create,
|
|
332
|
+
default_types=default_types,
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
# New: merge generated sets into the builtin registry
|
|
336
|
+
|
|
337
|
+
def merge_generated_format_sets(
|
|
338
|
+
commands_json_path: str | Path,
|
|
339
|
+
*,
|
|
340
|
+
include_only_create: bool = True,
|
|
341
|
+
default_types: Optional[List[str]] = None,
|
|
342
|
+
) -> int:
|
|
343
|
+
"""Build and merge generated FormatSets into the built-in registry.
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
- commands_json_path: input commands.json path
|
|
347
|
+
- include_only_create: filter to only "Create" commands (default True)
|
|
348
|
+
- default_types: list for Format.types (default ["ALL"]).
|
|
349
|
+
|
|
350
|
+
Returns
|
|
351
|
+
- int: number of sets merged/added into `pyegeria.base_report_formats.report_specs`.
|
|
352
|
+
"""
|
|
353
|
+
from pyegeria.view.base_report_formats import report_specs # local import to avoid cycles on tooling
|
|
354
|
+
|
|
355
|
+
gen = build_format_sets_from_commands(
|
|
356
|
+
commands_json_path,
|
|
357
|
+
include_only_create=include_only_create,
|
|
358
|
+
default_types=default_types,
|
|
359
|
+
)
|
|
360
|
+
count = 0
|
|
361
|
+
for name, fs in gen.items():
|
|
362
|
+
report_specs[name] = fs
|
|
363
|
+
count += 1
|
|
364
|
+
logger.info(f"Merged {count} generated format sets into built-ins")
|
|
365
|
+
return count
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def _py_literal(value):
|
|
369
|
+
"""Render a value as a valid Python literal string.
|
|
370
|
+
|
|
371
|
+
Supports strings, numbers, bools, None, lists, tuples, dicts. Used when
|
|
372
|
+
emitting Python code for generated FormatSets.
|
|
373
|
+
"""
|
|
374
|
+
if isinstance(value, str):
|
|
375
|
+
return repr(value)
|
|
376
|
+
if isinstance(value, (int, float)):
|
|
377
|
+
return str(value)
|
|
378
|
+
if value is True:
|
|
379
|
+
return "True"
|
|
380
|
+
if value is False:
|
|
381
|
+
return "False"
|
|
382
|
+
if value is None:
|
|
383
|
+
return "None"
|
|
384
|
+
if isinstance(value, list):
|
|
385
|
+
return "[" + ", ".join(_py_literal(v) for v in value) + "]"
|
|
386
|
+
if isinstance(value, dict):
|
|
387
|
+
# Render dict with stable key ordering
|
|
388
|
+
items = ", ".join(f"{_py_literal(k)}: {_py_literal(v)}" for k, v in sorted(value.items(), key=lambda kv: str(kv[0]).lower()))
|
|
389
|
+
return "{" + items + "}"
|
|
390
|
+
# Fallback
|
|
391
|
+
return repr(value)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def _format_column(col: Column) -> str:
|
|
395
|
+
"""Render a Column instance as Python code.
|
|
396
|
+
|
|
397
|
+
Returns a string like: Column(name='Display Name', key='display_name', ...)
|
|
398
|
+
Only includes optional attributes when present.
|
|
399
|
+
"""
|
|
400
|
+
parts = [f"name={_py_literal(getattr(col, 'name', ''))}", f"key={_py_literal(getattr(col, 'key', ''))}"]
|
|
401
|
+
fmt = getattr(col, 'format', None)
|
|
402
|
+
if fmt not in (None, False):
|
|
403
|
+
parts.append(f"format={_py_literal(bool(fmt))}")
|
|
404
|
+
return "Column(" + ", ".join(parts) + ")"
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def _format_action(ap: ActionParameter | None) -> str:
|
|
408
|
+
"""Render an ActionParameter as Python code for emission.
|
|
409
|
+
|
|
410
|
+
Includes function, required_params, optional_params, and spec_params when present.
|
|
411
|
+
"""
|
|
412
|
+
if not ap:
|
|
413
|
+
return "None"
|
|
414
|
+
parts = [
|
|
415
|
+
f"function={_py_literal(getattr(ap, 'function', ''))}",
|
|
416
|
+
]
|
|
417
|
+
req = getattr(ap, 'required_params', None)
|
|
418
|
+
if req:
|
|
419
|
+
parts.append(f"required_params={_py_literal(list(req))}")
|
|
420
|
+
opt = getattr(ap, 'optional_params', None)
|
|
421
|
+
if opt:
|
|
422
|
+
parts.append(f"optional_params={_py_literal(list(opt))}")
|
|
423
|
+
spec = getattr(ap, 'spec_params', None)
|
|
424
|
+
if spec:
|
|
425
|
+
parts.append(f"spec_params={_py_literal(dict(spec))}")
|
|
426
|
+
return "ActionParameter(" + ", ".join(parts) + ")"
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def _format_format(fmt: Format) -> str:
|
|
430
|
+
"""Render a Format instance as Python code, including types and columns."""
|
|
431
|
+
cols = getattr(fmt, 'columns', []) or []
|
|
432
|
+
types = getattr(fmt, 'types', []) or []
|
|
433
|
+
col_code = ", ".join(_format_column(c) for c in cols)
|
|
434
|
+
parts = [f"types={_py_literal(list(types))}", f"columns=[{col_code}]"]
|
|
435
|
+
return "Format(" + ", ".join(parts) + ")"
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _format_formatset(fs: FormatSet) -> str:
|
|
439
|
+
"""Render a FormatSet as Python code including nested formats and actions."""
|
|
440
|
+
parts = []
|
|
441
|
+
if getattr(fs, 'target_type', None):
|
|
442
|
+
parts.append(f"target_type={_py_literal(fs.target_type)}")
|
|
443
|
+
if getattr(fs, 'heading', None):
|
|
444
|
+
parts.append(f"heading={_py_literal(fs.heading)}")
|
|
445
|
+
if getattr(fs, 'description', None):
|
|
446
|
+
parts.append(f"description={_py_literal(fs.description)}")
|
|
447
|
+
if getattr(fs, 'family', None):
|
|
448
|
+
parts.append(f"family={_py_literal(fs.family)}")
|
|
449
|
+
aliases = getattr(fs, 'aliases', None)
|
|
450
|
+
if aliases:
|
|
451
|
+
parts.append(f"aliases={_py_literal(list(aliases))}")
|
|
452
|
+
ann = getattr(fs, 'annotations', None)
|
|
453
|
+
if ann:
|
|
454
|
+
parts.append(f"annotations={_py_literal(dict(ann))}")
|
|
455
|
+
# formats
|
|
456
|
+
fmts = getattr(fs, 'formats', []) or []
|
|
457
|
+
fmt_code = ", ".join(_format_format(f) for f in fmts)
|
|
458
|
+
parts.append(f"formats=[{fmt_code}]")
|
|
459
|
+
# actions
|
|
460
|
+
action = getattr(fs, 'action', None)
|
|
461
|
+
if action:
|
|
462
|
+
parts.append(f"action={_format_action(action)}")
|
|
463
|
+
get_add = getattr(fs, 'get_additional_props', None)
|
|
464
|
+
if get_add:
|
|
465
|
+
parts.append(f"get_additional_props={_format_action(get_add)}")
|
|
466
|
+
return "FormatSet(" + ", ".join(parts) + ")"
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def format_sets_to_python_code(sets: FormatSetDict, var_name: str = "generated_format_sets") -> str:
|
|
470
|
+
"""Render a FormatSetDict into the text of a small Python module.
|
|
471
|
+
|
|
472
|
+
Parameters
|
|
473
|
+
- sets: the FormatSetDict to render
|
|
474
|
+
- var_name: the variable name to assign the dict to (default 'generated_format_sets')
|
|
475
|
+
|
|
476
|
+
Returns
|
|
477
|
+
- str: Python source code that, when imported, defines `var_name` as a FormatSetDict
|
|
478
|
+
"""
|
|
479
|
+
header = (
|
|
480
|
+
"# Auto-generated by gen_report_specs.py\n"
|
|
481
|
+
"from pyegeria._output_format_models import Column, Format, ActionParameter, FormatSet, FormatSetDict\n\n"
|
|
482
|
+
)
|
|
483
|
+
# Stable ordering by key
|
|
484
|
+
entries = []
|
|
485
|
+
for name in sorted(sets.keys(), key=lambda s: s.lower()):
|
|
486
|
+
fs = sets[name]
|
|
487
|
+
entries.append(f" {_py_literal(name)}: {_format_formatset(fs)}")
|
|
488
|
+
body = f"{var_name} = FormatSetDict({{\n" + ",\n".join(entries) + "\n})\n"
|
|
489
|
+
return header + body
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def save_generated_format_sets_code(
|
|
493
|
+
commands_json_path: str | Path,
|
|
494
|
+
out_file: str | Path,
|
|
495
|
+
*,
|
|
496
|
+
include_only_create: bool = True,
|
|
497
|
+
default_types: Optional[List[str]] = None,
|
|
498
|
+
var_name: str = "generated_format_sets",
|
|
499
|
+
) -> Path:
|
|
500
|
+
"""Build FormatSets and save them as an importable Python module.
|
|
501
|
+
|
|
502
|
+
Parameters
|
|
503
|
+
- commands_json_path: input commands.json path
|
|
504
|
+
- out_file: path to write the .py file (module will define `var_name`)
|
|
505
|
+
- include_only_create: filter to only "Create" commands (default True)
|
|
506
|
+
- default_types: list for Format.types (default ["ALL"]).
|
|
507
|
+
- var_name: variable name to bind the resulting FormatSetDict to
|
|
508
|
+
|
|
509
|
+
Returns
|
|
510
|
+
- Path to the written Python file
|
|
511
|
+
|
|
512
|
+
Notes
|
|
513
|
+
- You can import the resulting file dynamically and access the variable
|
|
514
|
+
to merge into `pyegeria.base_report_formats.report_specs`.
|
|
515
|
+
"""
|
|
516
|
+
sets = build_format_sets_from_commands(
|
|
517
|
+
commands_json_path,
|
|
518
|
+
include_only_create=include_only_create,
|
|
519
|
+
default_types=default_types,
|
|
520
|
+
)
|
|
521
|
+
code = format_sets_to_python_code(sets, var_name=var_name)
|
|
522
|
+
out = Path(out_file)
|
|
523
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
|
524
|
+
out.write_text(code, encoding="utf-8")
|
|
525
|
+
logger.info(f"Saved Python code for {len(sets)} generated format sets to {out}")
|
|
526
|
+
return out
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def main():
|
|
530
|
+
"""CLI entry point for generating report FormatSets from commands.json.
|
|
531
|
+
|
|
532
|
+
Notes
|
|
533
|
+
- If a command object includes a string field `family`, it will be propagated into the generated
|
|
534
|
+
`FormatSet.family`. This applies to both JSON emission and generated Python code.
|
|
535
|
+
|
|
536
|
+
Synopsis
|
|
537
|
+
- Default (emit JSON):
|
|
538
|
+
python -m md_processing.md_processing_utils.gen_report_specs \
|
|
539
|
+
md_processing/data/commands.json md_processing/data/generated_format_sets.json --emit json
|
|
540
|
+
- Emit Python code:
|
|
541
|
+
python -m md_processing.md_processing_utils.gen_report_specs \
|
|
542
|
+
md_processing/data/commands.json md_processing/data/generated_format_sets.py --emit code
|
|
543
|
+
- In-memory only and list:
|
|
544
|
+
python -m md_processing.md_processing_utils.gen_report_specs \
|
|
545
|
+
md_processing/data/commands.json --emit dict --list
|
|
546
|
+
|
|
547
|
+
Flags
|
|
548
|
+
- --emit json|dict|code: controls output mode (default json)
|
|
549
|
+
- --merge: also merge generated sets into built-in report_specs at runtime
|
|
550
|
+
- --list: when emitting dict (or after merge), list set names to stdout
|
|
551
|
+
"""
|
|
552
|
+
parser = argparse.ArgumentParser(description="Generate FormatSets from commands.json")
|
|
553
|
+
parser.add_argument("commands_json", nargs="?", help="Path to commands.json")
|
|
554
|
+
parser.add_argument("output_json", nargs="?", help="Path to output JSON file (when --emit json)")
|
|
555
|
+
parser.add_argument("--emit", choices=["json", "dict", "code"], default="json",
|
|
556
|
+
help="Choose output mode: save JSON file, write Python code, or work with in-memory FormatSetDict")
|
|
557
|
+
parser.add_argument("--merge", action="store_true",
|
|
558
|
+
help="Merge generated sets into built-in registry (report_specs)")
|
|
559
|
+
parser.add_argument("--list", action="store_true",
|
|
560
|
+
help="When emitting dict (and/or after merge), list set names to stdout")
|
|
561
|
+
args = parser.parse_args()
|
|
562
|
+
|
|
563
|
+
try:
|
|
564
|
+
input_file = args.commands_json or Prompt.ask(
|
|
565
|
+
"Enter commands.json:", default="md_processing/data/commands.json"
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
if args.emit == "json":
|
|
569
|
+
# JSON output path
|
|
570
|
+
output_file = args.output_json or Prompt.ask(
|
|
571
|
+
"Output File:", default="md_processing/data/generated_format_sets.json"
|
|
572
|
+
)
|
|
573
|
+
save_generated_format_sets(input_file, output_file)
|
|
574
|
+
if args.merge:
|
|
575
|
+
# Also load and merge saved JSON into registry for convenience
|
|
576
|
+
from pyegeria.view.base_report_formats import load_report_specs
|
|
577
|
+
load_report_specs(output_file, merge=True)
|
|
578
|
+
logger.info("Merged saved JSON into built-in registry")
|
|
579
|
+
elif args.emit == "code":
|
|
580
|
+
# Python code output path
|
|
581
|
+
output_file = args.output_json or Prompt.ask(
|
|
582
|
+
"Output Python File:", default="pyegeria/dr_egeria_reports.py" # Changed from config/
|
|
583
|
+
)
|
|
584
|
+
saved_path = save_generated_format_sets_code(input_file, output_file)
|
|
585
|
+
logger.info(f"Generated Python code written to {saved_path}")
|
|
586
|
+
|
|
587
|
+
if args.merge:
|
|
588
|
+
# Dynamically import and merge the generated variable
|
|
589
|
+
try:
|
|
590
|
+
import importlib.util
|
|
591
|
+
import sys as _sys
|
|
592
|
+
|
|
593
|
+
# Convert to absolute path to ensure spec_from_file_location can find it
|
|
594
|
+
abs_output_file = saved_path.resolve()
|
|
595
|
+
|
|
596
|
+
spec = importlib.util.spec_from_file_location("_gen_fs_module", abs_output_file)
|
|
597
|
+
if spec is None or spec.loader is None:
|
|
598
|
+
raise ImportError(f"Could not create module spec from {abs_output_file}")
|
|
599
|
+
|
|
600
|
+
mod = importlib.util.module_from_spec(spec)
|
|
601
|
+
spec.loader.exec_module(mod) # type: ignore
|
|
602
|
+
|
|
603
|
+
generated = getattr(mod, "generated_format_sets", None)
|
|
604
|
+
if generated:
|
|
605
|
+
from pyegeria.view.base_report_formats import report_specs
|
|
606
|
+
merged = 0
|
|
607
|
+
for name, fs in generated.items():
|
|
608
|
+
report_specs[name] = fs
|
|
609
|
+
merged += 1
|
|
610
|
+
logger.info(f"Merged {merged} generated format sets from code into built-ins")
|
|
611
|
+
else:
|
|
612
|
+
logger.warning("No 'generated_format_sets' found in generated code module")
|
|
613
|
+
except Exception as e:
|
|
614
|
+
logger.error(f"Failed to import and merge generated code: {e}")
|
|
615
|
+
else:
|
|
616
|
+
# Emit dict path: build in memory
|
|
617
|
+
sets = generate_format_sets(input_file)
|
|
618
|
+
logger.info(f"Generated {len(sets)} format sets (in-memory FormatSetDict)")
|
|
619
|
+
if args.merge:
|
|
620
|
+
from pyegeria.view.base_report_formats import report_specs
|
|
621
|
+
merged = 0
|
|
622
|
+
for name, fs in sets.items():
|
|
623
|
+
report_specs[name] = fs
|
|
624
|
+
merged += 1
|
|
625
|
+
logger.info(f"Merged {merged} generated format sets into built-ins")
|
|
626
|
+
if args.list:
|
|
627
|
+
# If merged, show names from the global registry that match the generated ones
|
|
628
|
+
names = sorted(list(sets.keys()))
|
|
629
|
+
print("Merged set names:")
|
|
630
|
+
for n in names:
|
|
631
|
+
print(f"- {n}")
|
|
632
|
+
else:
|
|
633
|
+
if args.list:
|
|
634
|
+
names = sorted(list(sets.keys()))
|
|
635
|
+
print(f"Generated set names ({len(names)}):")
|
|
636
|
+
for n in names:
|
|
637
|
+
print(f"- {n}")
|
|
638
|
+
except (KeyboardInterrupt, EOFError):
|
|
639
|
+
# Graceful exit when user cancels or stdin is not interactive
|
|
640
|
+
pass
|
|
641
|
+
|
|
642
|
+
if __name__ == "__main__":
|
|
643
|
+
main()
|