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
pyegeria/core/config.py
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
Copyright Contributors to the ODPi Egeria project.
|
|
4
|
+
|
|
5
|
+
This module manages configuration information for pyegeria and pyegeria clients.
|
|
6
|
+
|
|
7
|
+
The load_app_config() function loads configuration information:
|
|
8
|
+
1) Default configuration variables are specified in the Pydantic models below.
|
|
9
|
+
2) Environment variables are loaded from the .env file using pydantic-settings.
|
|
10
|
+
- PYEGERIA_ROOT_PATH and PYEGERIA_CONFIG_FILE are loaded first to locate the config file
|
|
11
|
+
- Additional environment variables are loaded from the operating system
|
|
12
|
+
3) We construct a path to an external configuration JSON file from the Environment Variables
|
|
13
|
+
- PYEGERIA_ROOT_PATH
|
|
14
|
+
- PYEGERIA_CONFIG_FILE
|
|
15
|
+
4) If a valid configuration file is found, the configuration will be loaded on top of the default configuration.
|
|
16
|
+
5) We then update the in-memory configuration from Environment Variables, if set.
|
|
17
|
+
|
|
18
|
+
The result is that Environment Variable values take priority over configuration file values which override the defaults.
|
|
19
|
+
|
|
20
|
+
The get_app_config() function is used by other modules to get configuration information from the configuration structure
|
|
21
|
+
and makes it available as a Pydantic model.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
import inspect
|
|
25
|
+
import os
|
|
26
|
+
import json
|
|
27
|
+
from typing import List, Optional, Dict, Any
|
|
28
|
+
|
|
29
|
+
from loguru import logger
|
|
30
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
31
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
32
|
+
|
|
33
|
+
from pyegeria.core._exceptions import PyegeriaInvalidParameterException
|
|
34
|
+
|
|
35
|
+
logger.disable("pyegeria")
|
|
36
|
+
# --- Pydantic Settings for Environment Variables ---
|
|
37
|
+
|
|
38
|
+
class PyegeriaSettings(BaseSettings):
|
|
39
|
+
"""Top-level environment settings for pyegeria.
|
|
40
|
+
|
|
41
|
+
This class centralizes discovery of important filesystem paths and default
|
|
42
|
+
configuration values. It can be constructed directly or via `with_env_file`
|
|
43
|
+
to load overrides from a specific .env-like file.
|
|
44
|
+
"""
|
|
45
|
+
"""
|
|
46
|
+
Settings loaded from environment variables using pydantic-settings.
|
|
47
|
+
This class is used to load environment variables from the .env file.
|
|
48
|
+
|
|
49
|
+
The .env file path can be specified when creating an instance of this class
|
|
50
|
+
by passing the `_env_file` parameter. If not specified, it defaults to ".env"
|
|
51
|
+
in the current directory.
|
|
52
|
+
"""
|
|
53
|
+
# Core settings needed to locate the config file
|
|
54
|
+
pyegeria_root_path: str = ""
|
|
55
|
+
pyegeria_config_directory: str = ""
|
|
56
|
+
pyegeria_config_file: str = "config.json"
|
|
57
|
+
|
|
58
|
+
# Additional settings that can be loaded from .env
|
|
59
|
+
pyegeria_console_width: int = 200
|
|
60
|
+
# Renamed: format_sets -> report_specs
|
|
61
|
+
pyegeria_user_report_specs_dir: str = "~/.pyegeria/report_specs"
|
|
62
|
+
egeria_user_name: str = ""
|
|
63
|
+
egeria_user_password: str = ""
|
|
64
|
+
|
|
65
|
+
model_config = SettingsConfigDict(
|
|
66
|
+
env_file=".env",
|
|
67
|
+
env_file_encoding="utf-8",
|
|
68
|
+
extra="ignore",
|
|
69
|
+
case_sensitive=False
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def with_env_file(cls, env_file: str):
|
|
74
|
+
"""
|
|
75
|
+
Create a PyegeriaSettings instance with a specific .env file.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
env_file: Path to the .env file to load
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
PyegeriaSettings: A new PyegeriaSettings instance
|
|
82
|
+
"""
|
|
83
|
+
# Create a new class with a custom model_config that specifies the env_file
|
|
84
|
+
class CustomSettings(cls):
|
|
85
|
+
model_config = SettingsConfigDict(
|
|
86
|
+
env_file=env_file,
|
|
87
|
+
env_file_encoding="utf-8",
|
|
88
|
+
extra="ignore",
|
|
89
|
+
case_sensitive=False
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Create and return an instance of the custom class
|
|
93
|
+
return CustomSettings()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# --- Pydantic Models for Configuration ---
|
|
97
|
+
|
|
98
|
+
class EnvironmentConfig(BaseModel):
|
|
99
|
+
"""Runtime environment parameters that influence formatting and behavior."""
|
|
100
|
+
"""Environment configuration settings"""
|
|
101
|
+
console_width: int = Field(default=200, alias="Console Width")
|
|
102
|
+
egeria_outbox: str = Field(default="egeria-outbox", alias="Egeria Outbox")
|
|
103
|
+
egeria_inbox: str = Field(default="egeria-inbox", alias="Egeria Inbox")
|
|
104
|
+
dr_egeria_inbox: str = Field(default="sample-data/egeria-inbox/dr-egeria-inbox", alias="Dr.Egeria Inbox")
|
|
105
|
+
dr_egeria_outbox: str = Field(default="sample-data/egeria-outbox/dr-egeria-outbox", alias="Dr.Egeria Outbox")
|
|
106
|
+
egeria_engine_host_url: str = Field(default="", alias="Egeria Engine Host URL")
|
|
107
|
+
egeria_engine_host: str = Field(default="qs-engine-host", alias="Egeria Engine Host")
|
|
108
|
+
egeria_glossary_path: str = Field(default="glossary", alias="Egeria Glossary Path")
|
|
109
|
+
egeria_integration_daemon_url: str = Field(default="https://localhost:9443", alias="Egeria Integration Daemon URL")
|
|
110
|
+
egeria_integration_daemon: str = Field(default="qs-integration-daemon", alias="Egeria Integration Daemon")
|
|
111
|
+
egeria_jupyter: bool = Field(default=True, alias="Egeria Jupyter")
|
|
112
|
+
egeria_kafka_endpoint: str = Field(default="localhost:9192", alias="Egeria Kafka Endpoint")
|
|
113
|
+
egeria_mermaid_folder: str = Field(default="egeria-outbox/mermaid-graphs", alias="Egeria Mermaid Folder")
|
|
114
|
+
egeria_metadata_store: str = Field(default="qs-metadata-store", alias="Egeria Metadata Store")
|
|
115
|
+
egeria_platform_url: str = Field(default="https://localhost:9443", alias="Egeria Platform URL")
|
|
116
|
+
egeria_view_server_url: str = Field(default="https://localhost:9443", alias="Egeria View Server URL")
|
|
117
|
+
egeria_view_server: str = Field(default="qs-view-server", alias="Egeria View Server")
|
|
118
|
+
pyegeria_root: str = Field(default="sample-data", alias="Pyegeria Root")
|
|
119
|
+
pyegeria_config_directory: str = Field(default="", alias="Pyegeria Config Directory")
|
|
120
|
+
pyegeria_config_file: str = Field(default="config.json", alias="Egeria Config File")
|
|
121
|
+
pyegeria_publishing_root: str = Field(default="/dr-egeria-outbox", alias="Pyegeria Publishing Root")
|
|
122
|
+
# Renamed: Format Sets -> Report Specs
|
|
123
|
+
pyegeria_user_report_specs_dir: str = Field(default="~/.pyegeria/report_specs", alias="Pyegeria User Report Specs Dir")
|
|
124
|
+
|
|
125
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class DebugConfig(BaseModel):
|
|
129
|
+
"""Debug configuration settings"""
|
|
130
|
+
debug_mode: bool = False
|
|
131
|
+
enable_logger_catch: bool = False
|
|
132
|
+
timeout_seconds: int = 30
|
|
133
|
+
|
|
134
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class LoggingConfig(BaseModel):
|
|
138
|
+
"""Logging configuration settings"""
|
|
139
|
+
console_filter_levels: List[str] = ["SUCCESS"]
|
|
140
|
+
console_logging_enabled: List[str] = [ "_exceptions_new", "dr_egeria_md", "tests"]
|
|
141
|
+
console_logging_level: str = "ERROR"
|
|
142
|
+
enable_logging: bool = False
|
|
143
|
+
file_logging_level: str = "INFO"
|
|
144
|
+
log_directory: str = "logs"
|
|
145
|
+
logging_console_format: str = " <green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>:<cyan>{line}</cyan> - <level>{message}</level> -{extra}"
|
|
146
|
+
logging_file_format: str = " {time:YYYY-MM-DD HH:mm:ss} | {level} | {function}:{line} - {message }-{extra}"
|
|
147
|
+
|
|
148
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class UserProfileConfig(BaseModel):
|
|
152
|
+
"""User profile configuration settings"""
|
|
153
|
+
egeria_home_collection: str = Field(default="MyHome", alias="Egeria Home Collection")
|
|
154
|
+
egeria_home_glossary_name: str = Field(default="Egeria-Markdown", alias="Egeria Home Glossary Name")
|
|
155
|
+
egeria_local_qualifier: str = Field(default="PDR", alias="Egeria Local Qualifier")
|
|
156
|
+
egeria_usage_level: str = Field(default="Advanced", alias="Egeria Usage Level")
|
|
157
|
+
user_name: Optional[str] = "erinoverview"
|
|
158
|
+
user_pwd: Optional[str] = "secret"
|
|
159
|
+
|
|
160
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class AppConfig(BaseModel):
|
|
164
|
+
"""Aggregated application configuration used by pyegeria components."""
|
|
165
|
+
"""Main application configuration"""
|
|
166
|
+
Environment: EnvironmentConfig
|
|
167
|
+
Debug: DebugConfig
|
|
168
|
+
Logging: LoggingConfig
|
|
169
|
+
User_Profile: UserProfileConfig = Field(alias="User Profile")
|
|
170
|
+
feature_x_enabled: bool = False
|
|
171
|
+
|
|
172
|
+
def get(self, key, default=None):
|
|
173
|
+
"""
|
|
174
|
+
Dictionary-like get method for backward compatibility.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
key: The key to look up
|
|
178
|
+
default: The default value to return if the key is not found
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
The value for the key if found, otherwise the default value
|
|
182
|
+
"""
|
|
183
|
+
# First check if the key is a direct attribute of this model
|
|
184
|
+
if hasattr(self, key):
|
|
185
|
+
return getattr(self, key)
|
|
186
|
+
|
|
187
|
+
# Then check if it's in any of the nested models
|
|
188
|
+
for section in [self.Environment, self.Debug, self.Logging, self.User_Profile]:
|
|
189
|
+
if hasattr(section, key):
|
|
190
|
+
return getattr(section, key)
|
|
191
|
+
# Also check using the original field names (with aliases)
|
|
192
|
+
for field_name, field in section.model_fields.items():
|
|
193
|
+
# In Pydantic v2, the alias is stored in json_schema_extra
|
|
194
|
+
alias = None
|
|
195
|
+
if hasattr(field, 'alias'):
|
|
196
|
+
alias = field.alias
|
|
197
|
+
elif hasattr(field, 'json_schema_extra') and field.json_schema_extra:
|
|
198
|
+
alias = field.json_schema_extra.get('alias')
|
|
199
|
+
|
|
200
|
+
if alias == key:
|
|
201
|
+
return getattr(section, field_name)
|
|
202
|
+
|
|
203
|
+
# If not found, return the default
|
|
204
|
+
return default
|
|
205
|
+
|
|
206
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# --- Configuration Loading Logic ---
|
|
210
|
+
|
|
211
|
+
# Private variable to hold the loaded configuration
|
|
212
|
+
_app_config = None
|
|
213
|
+
|
|
214
|
+
def _resolve_env_settings(env_file: str | None) -> PyegeriaSettings:
|
|
215
|
+
if env_file:
|
|
216
|
+
return PyegeriaSettings.with_env_file(env_file)
|
|
217
|
+
return PyegeriaSettings()
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _find_config_file_path(settings: PyegeriaSettings) -> str | None:
|
|
221
|
+
config_dir = (settings.pyegeria_config_directory or "").strip()
|
|
222
|
+
root_path = (settings.pyegeria_root_path or "").strip()
|
|
223
|
+
config_file = (settings.pyegeria_config_file or "config.json").strip()
|
|
224
|
+
|
|
225
|
+
candidates = []
|
|
226
|
+
if config_dir:
|
|
227
|
+
candidates.append(os.path.join(config_dir, config_file))
|
|
228
|
+
if root_path:
|
|
229
|
+
candidates.append(os.path.join(root_path, config_file))
|
|
230
|
+
candidates.append(os.path.abspath(os.path.join(os.getcwd(), "config.json")))
|
|
231
|
+
|
|
232
|
+
for path in candidates:
|
|
233
|
+
if path and os.path.exists(path):
|
|
234
|
+
return path
|
|
235
|
+
return None
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def load_app_config(env_file: str | None = None):
|
|
239
|
+
"""
|
|
240
|
+
Loads application configuration from files and environment variables.
|
|
241
|
+
This function should ideally be called only once at application startup.
|
|
242
|
+
|
|
243
|
+
The function follows this precedence order for configuration settings:
|
|
244
|
+
1. If env_file is passed in, it uses that file to load environment variables
|
|
245
|
+
2. Otherwise, it first checks if OS environment variables are set for PYEGERIA_ROOT_PATH and PYEGERIA_CONFIG_FILE
|
|
246
|
+
3. If they are not set, it checks for a .env file in the current directory
|
|
247
|
+
4. It then loads the configuration from the config file if available
|
|
248
|
+
5. Finally, it updates the configuration with environment variables from the operating system,
|
|
249
|
+
which take precedence over the config file values
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
env_file: Optional path to a specific .env file to load. If not specified,
|
|
253
|
+
the function follows the precedence order described above.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
AppConfig: The loaded configuration as a Pydantic model
|
|
257
|
+
"""
|
|
258
|
+
global _app_config # Declare intent to modify the global _app_config
|
|
259
|
+
|
|
260
|
+
if _app_config is not None:
|
|
261
|
+
# Configuration already loaded, return existing instance
|
|
262
|
+
return _app_config
|
|
263
|
+
|
|
264
|
+
# 1) Defaults from models
|
|
265
|
+
config_dict: dict[str, Any] = {
|
|
266
|
+
"Environment": {},
|
|
267
|
+
"Debug": {},
|
|
268
|
+
"Logging": {},
|
|
269
|
+
"User Profile": {},
|
|
270
|
+
"feature_x_enabled": False,
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
# 2) Load env settings from OS/.env according to env_file
|
|
274
|
+
env_settings = _resolve_env_settings(env_file)
|
|
275
|
+
|
|
276
|
+
# 3) Load config file if found
|
|
277
|
+
file_path = _find_config_file_path(env_settings)
|
|
278
|
+
if file_path:
|
|
279
|
+
logger.info(f"Using config file: {file_path}")
|
|
280
|
+
try:
|
|
281
|
+
with open(file_path, "r") as f:
|
|
282
|
+
file_cfg = json.load(f)
|
|
283
|
+
if isinstance(file_cfg, dict):
|
|
284
|
+
config_dict.update(file_cfg)
|
|
285
|
+
else:
|
|
286
|
+
logger.warning("Config file root is not an object; ignoring.")
|
|
287
|
+
except Exception as e:
|
|
288
|
+
logger.warning(f"Could not read/parse config file '{file_path}': {e}. Continuing with defaults+env.")
|
|
289
|
+
else:
|
|
290
|
+
logger.debug("No config.json found; continuing with defaults + env.")
|
|
291
|
+
|
|
292
|
+
# 4) Overlay environment variables
|
|
293
|
+
# Debug
|
|
294
|
+
dbg = config_dict.setdefault("Debug", {})
|
|
295
|
+
dbg["debug_mode"] = _parse_bool_env("PYEGERIA_DEBUG_MODE", bool(dbg.get("debug_mode", False)))
|
|
296
|
+
dbg["enable_logger_catch"] = _parse_bool_env("PYEGERIA_ENABLE_LOGGER_CATCH", bool(dbg.get("enable_logger_catch", False)))
|
|
297
|
+
dbg["timeout_seconds"] = int(os.getenv("PYEGERIA_TIMEOUT_SECONDS", dbg.get("timeout_seconds", 30)))
|
|
298
|
+
|
|
299
|
+
# Environment
|
|
300
|
+
env = config_dict.setdefault("Environment", {})
|
|
301
|
+
default_root = env.get("Pyegeria Root") or os.getcwd()
|
|
302
|
+
env_config_dir = os.getenv("PYEGERIA_CONFIG_DIRECTORY", env_settings.pyegeria_config_directory or "")
|
|
303
|
+
env_root = os.getenv("PYEGERIA_ROOT_PATH", env_settings.pyegeria_root_path or default_root)
|
|
304
|
+
env_config_file = os.getenv("PYEGERIA_CONFIG_FILE", env_settings.pyegeria_config_file or "config.json")
|
|
305
|
+
env["Pyegeria Config Directory"] = env_config_dir
|
|
306
|
+
env["pyegeria_config_directory"] = env_config_dir
|
|
307
|
+
env["Pyegeria Root"] = env_root
|
|
308
|
+
env["pyegeria_root"] = env_root
|
|
309
|
+
env["Egeria Config File"] = env_config_file
|
|
310
|
+
env["pyegeria_config_file"] = env_config_file
|
|
311
|
+
|
|
312
|
+
env["Console Width"] = int(os.getenv("CONSOLE_WIDTH", env.get("Console Width", env_settings.pyegeria_console_width)))
|
|
313
|
+
env["console_width"] = env["Console Width"]
|
|
314
|
+
# Egeria Outbox (new)
|
|
315
|
+
env["Egeria Outbox"] = os.getenv("EGERIA_OUTBOX", env.get("Egeria Outbox", "egeria-outbox"))
|
|
316
|
+
env["Egeria Inbox"] = os.getenv("EGERIA_INBOX", env.get("Egeria Inbox", "egeria-inbox"))
|
|
317
|
+
env["Dr.Egeria Inbox"] = os.getenv("DR_EGERIA_INBOX_PATH", env.get("Dr.Egeria Inbox", "md_processing/dr-egeria-inbox"))
|
|
318
|
+
env["Dr.Egeria Outbox"] = os.getenv("DR_EGERIA_OUTBOX_PATH", env.get("Dr.Egeria Outbox", "md_processing/dr-egeria-outbox"))
|
|
319
|
+
env["Egeria Engine Host"] = os.getenv("EGERIA_ENGINE_HOST", env.get("Egeria Engine Host", "qs-engine-host"))
|
|
320
|
+
env["Egeria Engine Host URL"] = os.getenv("EGERIA_ENGINE_HOST_URL", env.get("Egeria Engine Host URL", "https://localhost:9443"))
|
|
321
|
+
env["Egeria Glossary Path"] = os.getenv("EGERIA_GLOSSARY_PATH", env.get("Egeria Glossary Path", "glossary"))
|
|
322
|
+
env["Egeria Integration Daemon"] = os.getenv("EGERIA_INTEGRATION_DAEMON", env.get("Egeria Integration Daemon", "qs-integration-daemon"))
|
|
323
|
+
env["Egeria Integration Daemon URL"] = os.getenv("EGERIA_INTEGRATION_DAEMON_URL", env.get("Egeria Integration Daemon URL", "https://localhost:9443"))
|
|
324
|
+
env["Egeria Jupyter"] = _parse_bool_env("EGERIA_JUPYTER", bool(env.get("Egeria Jupyter", True)))
|
|
325
|
+
env["Egeria Kafka Endpoint"] = os.getenv("EGERIA_KAFKA", env.get("Egeria Kafka Endpoint", "localhost:9192"))
|
|
326
|
+
# Normalize to hyphenated folder name; retain any explicit env override
|
|
327
|
+
env["Egeria Mermaid Folder"] = os.getenv(
|
|
328
|
+
"EGERIA_MERMAID_FOLDER",
|
|
329
|
+
env.get("Egeria Mermaid Folder", "egeria-outbox/mermaid-graphs"),
|
|
330
|
+
)
|
|
331
|
+
env["Egeria Metadata Store"] = os.getenv("EGERIA_METADATA_STORE", env.get("Egeria Metadata Store", "qs-metadata-store"))
|
|
332
|
+
env["Egeria Platform URL"] = os.getenv("EGERIA_PLATFORM_URL", env.get("Egeria Platform URL", "https://localhost:9443"))
|
|
333
|
+
env["Egeria View Server"] = os.getenv("EGERIA_VIEW_SERVER", env.get("Egeria View Server", "qs-view-server"))
|
|
334
|
+
env["Egeria View Server URL"] = os.getenv("EGERIA_VIEW_SERVER_URL", env.get("Egeria View Server URL", "https://localhost:9443"))
|
|
335
|
+
env["Pyegeria Publishing Root"] = os.getenv("PYEGERIA_PUBLISHING_ROOT", env.get("Pyegeria Publishing Root", "/dr-egeria-outbox"))
|
|
336
|
+
# New primary env var with fallback to old name for backward compatibility
|
|
337
|
+
env["Pyegeria User Report Specs Dir"] = (
|
|
338
|
+
os.getenv("PYEGERIA_USER_REPORT_SPECS_DIR")
|
|
339
|
+
or os.getenv("PYEGERIA_USER_FORMAT_SETS_DIR")
|
|
340
|
+
or env.get("Pyegeria User Report Specs Dir")
|
|
341
|
+
or env.get("Pyegeria User Format Sets Dir")
|
|
342
|
+
or "~/.pyegeria/report_specs"
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# Logging
|
|
346
|
+
log = config_dict.setdefault("Logging", {})
|
|
347
|
+
log["console_filter_levels"] = _parse_list_env("PYEGERIA_CONSOLE_FILTER_LEVELS", log.get("console_filter_levels", ["ERROR", "WARNING", "INFO", "SUCCESS"]))
|
|
348
|
+
log["console_logging_enabled"] = _parse_list_env("PYEGERIA_CONSOLE_LOGGING_ENABLED", log.get("console_logging_enabled", ["pyegeria"]))
|
|
349
|
+
log["console_logging_level"] = os.getenv("PYEGERIA_CONSOLE_LOG_LVL", log.get("console_logging_level", "INFO"))
|
|
350
|
+
log["enable_logging"] = _parse_bool_env("PYEGERIA_ENABLE_LOGGING", bool(log.get("enable_logging", False)))
|
|
351
|
+
log["file_logging_level"] = os.getenv("PYEGERIA_FILE_LOG_LVL", log.get("file_logging_level", "INFO"))
|
|
352
|
+
log["log_directory"] = os.getenv("PYEGERIA_LOG_DIRECTORY", log.get("log_directory", "logs"))
|
|
353
|
+
log["logging_console_format"] = os.getenv(
|
|
354
|
+
"PYEGERIA_LOGGING_CONSOLE_FORMAT",
|
|
355
|
+
log.get(
|
|
356
|
+
"logging_console_format",
|
|
357
|
+
" <green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>:<cyan>{line}</cyan> - <level>{message}</level> -{extra}",
|
|
358
|
+
),
|
|
359
|
+
)
|
|
360
|
+
log["logging_file_format"] = os.getenv(
|
|
361
|
+
"PYEGERIA_LOGGING_FILE_FORMAT",
|
|
362
|
+
log.get("logging_file_format", " {time:YYYY-MM-DD HH:mm:ss} | {level} | {function}:{line} - {message}-{extra}"),
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
# User Profile
|
|
366
|
+
user = config_dict.setdefault("User Profile", {})
|
|
367
|
+
user["Egeria Home Collection"] = os.getenv("EGERIA_HOME_COLLECTION", user.get("Egeria Home Collection", "MyHome"))
|
|
368
|
+
user["Egeria Home Glossary Name"] = os.getenv("EGERIA_HOME_GLOSSARY_NAME", user.get("Egeria Home Glossary Name", "Egeria-Markdown"))
|
|
369
|
+
user["Egeria Local Qualifier"] = os.getenv("EGERIA_LOCAL_QUALIFIER", user.get("Egeria Local Qualifier", "PDR"))
|
|
370
|
+
|
|
371
|
+
user_name = os.getenv("EGERIA_USER", user.get("user_name") or env_settings.egeria_user_name or None)
|
|
372
|
+
user_pwd = os.getenv("EGERIA_USER_PASSWORD", user.get("user_pwd") or env_settings.egeria_user_password or None)
|
|
373
|
+
user["user_name"] = user_name
|
|
374
|
+
user["user_pwd"] = user_pwd
|
|
375
|
+
|
|
376
|
+
# Feature flags
|
|
377
|
+
feature_x = _parse_bool_value(os.getenv("FEATURE_X_ENABLED", config_dict.get("feature_x_enabled", False)))
|
|
378
|
+
config_dict["feature_x_enabled"] = feature_x
|
|
379
|
+
|
|
380
|
+
# Debug print of env before model creation
|
|
381
|
+
try:
|
|
382
|
+
logger.info(f"DEBUG ENV SECTION: {config_dict.get('Environment')}")
|
|
383
|
+
_app_config = AppConfig(**config_dict)
|
|
384
|
+
except Exception as e:
|
|
385
|
+
context = {"caller method": inspect.currentframe().f_back.f_code.co_name}
|
|
386
|
+
additional_info = {"reason": str(e)}
|
|
387
|
+
raise PyegeriaInvalidParameterException(None, context, additional_info)
|
|
388
|
+
|
|
389
|
+
return _app_config
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def get_app_config(env_file: str = None)-> AppConfig:
|
|
393
|
+
"""
|
|
394
|
+
Provides access to the loaded application configuration.
|
|
395
|
+
Ensures config is loaded if not already (useful for testing or simple scripts).
|
|
396
|
+
For structured apps, load_app_config() should be called explicitly once at startup.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
env_file: Optional path to a specific .env file to load. If not specified,
|
|
400
|
+
the default .env file in the current directory is used.
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
AppConfig: The loaded configuration as a Pydantic model
|
|
404
|
+
"""
|
|
405
|
+
if _app_config is None:
|
|
406
|
+
# If get_app_config is called before load_app_config, load it now.
|
|
407
|
+
# This can be convenient but explicit loading is generally better.
|
|
408
|
+
logger.info(f"The env_file {env_file} is being passed in")
|
|
409
|
+
return load_app_config(env_file)
|
|
410
|
+
return _app_config
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def _parse_bool_env(env_var: str, default: bool) -> bool:
|
|
416
|
+
"""
|
|
417
|
+
Parse a boolean environment variable.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
env_var: The name of the environment variable
|
|
421
|
+
default: The default value if the environment variable is not set
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
bool: The parsed boolean value
|
|
425
|
+
"""
|
|
426
|
+
if env_var in os.environ:
|
|
427
|
+
value = os.getenv(env_var).lower()
|
|
428
|
+
return value in ('true', '1', 't', 'y', 'yes', 'on')
|
|
429
|
+
return default
|
|
430
|
+
|
|
431
|
+
def _parse_bool_value(value: Any) -> bool:
|
|
432
|
+
"""
|
|
433
|
+
Parse a boolean value from any type.
|
|
434
|
+
|
|
435
|
+
Args:
|
|
436
|
+
value: The value to parse
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
bool: The parsed boolean value
|
|
440
|
+
"""
|
|
441
|
+
if isinstance(value, bool):
|
|
442
|
+
return value
|
|
443
|
+
if isinstance(value, str):
|
|
444
|
+
return value.lower() in ('true', '1', 't', 'y', 'yes', 'on')
|
|
445
|
+
if isinstance(value, (int, float)):
|
|
446
|
+
return bool(value)
|
|
447
|
+
return False
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def _parse_list_env(env_var: str, default: List[str]) -> List[str]:
|
|
451
|
+
"""
|
|
452
|
+
Parse a list environment variable (comma-separated).
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
env_var: The name of the environment variable
|
|
456
|
+
default: The default value if the environment variable is not set
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
List[str]: The parsed list value
|
|
460
|
+
"""
|
|
461
|
+
if env_var in os.environ:
|
|
462
|
+
value = os.getenv(env_var)
|
|
463
|
+
if value:
|
|
464
|
+
return [item.strip() for item in value.split(',')]
|
|
465
|
+
return default
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
# Export a lazily-evaluated settings accessor to avoid import-time side effects
|
|
469
|
+
class _LazySettings:
|
|
470
|
+
def __getattr__(self, name):
|
|
471
|
+
cfg = get_app_config()
|
|
472
|
+
return getattr(cfg, name)
|
|
473
|
+
|
|
474
|
+
settings = _LazySettings()
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def pretty_print_config(env_file: str | None = None, safe: bool = True, to_console: bool = True) -> Dict[str, Dict[str, Any]]:
|
|
478
|
+
"""
|
|
479
|
+
Pretty print the current configuration and indicate the source of each value
|
|
480
|
+
(Environment, .env file, config file, or default). Uses Rich if available.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
env_file: Optional .env path to force loading before printing (if config not yet loaded).
|
|
484
|
+
safe: Mask sensitive values such as passwords/tokens.
|
|
485
|
+
to_console: If True, prints to console; function always returns a structured dict.
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
dict mapping section -> { key -> {"value": ..., "source": ...} }
|
|
489
|
+
"""
|
|
490
|
+
# Ensure config is loaded
|
|
491
|
+
cfg = get_app_config(env_file)
|
|
492
|
+
|
|
493
|
+
# Try import rich lazily
|
|
494
|
+
try:
|
|
495
|
+
from rich.console import Console
|
|
496
|
+
from rich.table import Table
|
|
497
|
+
from rich import box
|
|
498
|
+
console = Console(width=getattr(cfg.Environment, 'console_width', 200))
|
|
499
|
+
use_rich = True
|
|
500
|
+
except Exception:
|
|
501
|
+
console = None
|
|
502
|
+
use_rich = False
|
|
503
|
+
|
|
504
|
+
# Helper to mask sensitive keys
|
|
505
|
+
def _mask(key: str, val: Any) -> Any:
|
|
506
|
+
if not safe:
|
|
507
|
+
return val
|
|
508
|
+
key_l = (key or "").lower()
|
|
509
|
+
if any(s in key_l for s in ["password", "pwd", "secret", "token", "apikey", "api_key"]):
|
|
510
|
+
if val is None:
|
|
511
|
+
return None
|
|
512
|
+
s = str(val)
|
|
513
|
+
if len(s) <= 4:
|
|
514
|
+
return "****"
|
|
515
|
+
return s[:2] + "****" + s[-2:]
|
|
516
|
+
return val
|
|
517
|
+
|
|
518
|
+
# Determine sources. Because we merge defaults, config.json, and env, we infer source:
|
|
519
|
+
# - If an OS env var exists for a specific setting name we used, it's "env".
|
|
520
|
+
# - Else if a config file was found (by our path resolver) and provided an override, mark "config".
|
|
521
|
+
# - Else if value equals model default and neither env nor config provided, "default".
|
|
522
|
+
|
|
523
|
+
# We need to reconstruct which keys are influenced by ENV VAR names.
|
|
524
|
+
env_var_map = {
|
|
525
|
+
# Debug
|
|
526
|
+
("Debug", "debug_mode"): "PYEGERIA_DEBUG_MODE",
|
|
527
|
+
("Debug", "enable_logger_catch"): "PYEGERIA_ENABLE_LOGGER_CATCH",
|
|
528
|
+
("Debug", "timeout_seconds"): "PYEGERIA_TIMEOUT_SECONDS",
|
|
529
|
+
# Environment
|
|
530
|
+
("Environment", "Console Width"): "CONSOLE_WIDTH",
|
|
531
|
+
("Environment", "Egeria Outbox"): "EGERIA_OUTBOX",
|
|
532
|
+
("Environment", "Dr.Egeria Inbox"): "DR_EGERIA_INBOX_PATH",
|
|
533
|
+
("Environment", "Dr.Egeria Outbox"): "DR_EGERIA_OUTBOX_PATH",
|
|
534
|
+
("Environment", "Egeria Engine Host"): "EGERIA_ENGINE_HOST",
|
|
535
|
+
("Environment", "Egeria Engine Host URL"): "EGERIA_ENGINE_HOST_URL",
|
|
536
|
+
("Environment", "Egeria Glossary Path"): "EGERIA_GLOSSARY_PATH",
|
|
537
|
+
("Environment", "Egeria Integration Daemon"): "EGERIA_INTEGRATION_DAEMON",
|
|
538
|
+
("Environment", "Egeria Integration Daemon URL"): "EGERIA_INTEGRATION_DAEMON_URL",
|
|
539
|
+
("Environment", "Egeria Jupyter"): "EGERIA_JUPYTER",
|
|
540
|
+
("Environment", "Egeria Kafka Endpoint"): "EGERIA_KAFKA",
|
|
541
|
+
("Environment", "Egeria Mermaid Folder"): "EGERIA_MERMAID_FOLDER",
|
|
542
|
+
("Environment", "Egeria Metadata Store"): "EGERIA_METADATA_STORE",
|
|
543
|
+
("Environment", "Egeria Platform URL"): "EGERIA_PLATFORM_URL",
|
|
544
|
+
("Environment", "Egeria View Server"): "EGERIA_VIEW_SERVER",
|
|
545
|
+
("Environment", "Egeria View Server URL"): "EGERIA_VIEW_SERVER_URL",
|
|
546
|
+
("Environment", "Pyegeria Publishing Root"): "PYEGERIA_PUBLISHING_ROOT",
|
|
547
|
+
# Updated variable name
|
|
548
|
+
("Environment", "Pyegeria User Report Specs Dir"): "PYEGERIA_USER_REPORT_SPECS_DIR",
|
|
549
|
+
("Environment", "Pyegeria Root"): "PYEGERIA_ROOT_PATH",
|
|
550
|
+
("Environment", "Pyegeria Config Directory"): "PYEGERIA_CONFIG_DIRECTORY",
|
|
551
|
+
("Environment", "Egeria Config File"): "PYEGERIA_CONFIG_FILE",
|
|
552
|
+
# Logging
|
|
553
|
+
("Logging", "console_filter_levels"): "PYEGERIA_CONSOLE_FILTER_LEVELS",
|
|
554
|
+
("Logging", "console_logging_enabled"): "PYEGERIA_CONSOLE_LOGGING_ENABLED",
|
|
555
|
+
("Logging", "console_logging_level"): "PYEGERIA_CONSOLE_LOG_LVL",
|
|
556
|
+
("Logging", "enable_logging"): "PYEGERIA_ENABLE_LOGGING",
|
|
557
|
+
("Logging", "file_logging_level"): "PYEGERIA_FILE_LOG_LVL",
|
|
558
|
+
("Logging", "log_directory"): "PYEGERIA_LOG_DIRECTORY",
|
|
559
|
+
("Logging", "logging_console_format"): "PYEGERIA_LOGGING_CONSOLE_FORMAT",
|
|
560
|
+
("Logging", "logging_file_format"): "PYEGERIA_LOGGING_FILE_FORMAT",
|
|
561
|
+
# User profile
|
|
562
|
+
("User Profile", "Egeria Home Collection"): "EGERIA_HOME_COLLECTION",
|
|
563
|
+
("User Profile", "Egeria Home Glossary Name"): "EGERIA_HOME_GLOSSARY_NAME",
|
|
564
|
+
("User Profile", "Egeria Local Qualifier"): "EGERIA_LOCAL_QUALIFIER",
|
|
565
|
+
("User Profile", "user_name"): "EGERIA_USER",
|
|
566
|
+
("User Profile", "user_pwd"): "EGERIA_USER_PASSWORD",
|
|
567
|
+
# Feature flag example
|
|
568
|
+
(None, "feature_x_enabled"): "FEATURE_X_ENABLED",
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
# Attempt to detect if a config.json was used
|
|
572
|
+
env_settings = _resolve_env_settings(env_file)
|
|
573
|
+
config_file_path = _find_config_file_path(env_settings)
|
|
574
|
+
|
|
575
|
+
# Build a snapshot of defaults by instantiating empty models
|
|
576
|
+
defaults = {
|
|
577
|
+
"Environment": EnvironmentConfig().model_dump(by_alias=True),
|
|
578
|
+
"Debug": DebugConfig().model_dump(by_alias=True),
|
|
579
|
+
"Logging": LoggingConfig().model_dump(by_alias=False),
|
|
580
|
+
"User Profile": UserProfileConfig().model_dump(by_alias=True),
|
|
581
|
+
"feature_x_enabled": False,
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
# Current values from cfg
|
|
585
|
+
sections = [
|
|
586
|
+
("Environment", cfg.Environment.model_dump(by_alias=True)),
|
|
587
|
+
("Debug", cfg.Debug.model_dump(by_alias=False)),
|
|
588
|
+
("Logging", cfg.Logging.model_dump(by_alias=False)),
|
|
589
|
+
("User Profile", cfg.User_Profile.model_dump(by_alias=True)),
|
|
590
|
+
]
|
|
591
|
+
|
|
592
|
+
result: Dict[str, Dict[str, Any]] = {}
|
|
593
|
+
|
|
594
|
+
for section_name, values in sections:
|
|
595
|
+
section_out: Dict[str, Any] = {}
|
|
596
|
+
for key, val in values.items():
|
|
597
|
+
# Prefer alias keys in display; ensure key exists in defaults appropriately
|
|
598
|
+
default_section = defaults.get(section_name, {})
|
|
599
|
+
default_val = default_section.get(key, None)
|
|
600
|
+
|
|
601
|
+
# Identify env var used for this key if any
|
|
602
|
+
env_var = env_var_map.get((section_name, key))
|
|
603
|
+
source = "default"
|
|
604
|
+
if env_var and env_var in os.environ:
|
|
605
|
+
source = "env"
|
|
606
|
+
elif config_file_path and (key in (defaults.get(section_name, {}) or {}) or True):
|
|
607
|
+
# If a config file exists and value differs from default and no env var set
|
|
608
|
+
if val != default_val:
|
|
609
|
+
source = "config"
|
|
610
|
+
else:
|
|
611
|
+
source = "default"
|
|
612
|
+
else:
|
|
613
|
+
source = "default"
|
|
614
|
+
|
|
615
|
+
section_out[key] = {
|
|
616
|
+
"value": _mask(key, val),
|
|
617
|
+
"source": source,
|
|
618
|
+
}
|
|
619
|
+
result[section_name] = section_out
|
|
620
|
+
|
|
621
|
+
# Add top-level feature flags
|
|
622
|
+
feat_val = getattr(cfg, "feature_x_enabled", False)
|
|
623
|
+
source = "env" if ("FEATURE_X_ENABLED" in os.environ) else ("config" if config_file_path and feat_val != defaults["feature_x_enabled"] else "default")
|
|
624
|
+
result["feature_x_enabled"] = {"value": _mask("feature_x_enabled", feat_val), "source": source}
|
|
625
|
+
|
|
626
|
+
if to_console:
|
|
627
|
+
if use_rich and console:
|
|
628
|
+
for section_name in ["Environment", "Debug", "Logging", "User Profile"]:
|
|
629
|
+
table = Table(title=f"{section_name} Settings", box=box.SIMPLE_HEAVY)
|
|
630
|
+
table.add_column("Key")
|
|
631
|
+
table.add_column("Value")
|
|
632
|
+
table.add_column("Source")
|
|
633
|
+
for k, info in result[section_name].items():
|
|
634
|
+
table.add_row(str(k), str(info["value"]), info["source"])
|
|
635
|
+
console.print(table)
|
|
636
|
+
# Feature flags
|
|
637
|
+
table = Table(title="Feature Flags", box=box.SIMPLE_HEAVY)
|
|
638
|
+
table.add_column("Key")
|
|
639
|
+
table.add_column("Value")
|
|
640
|
+
table.add_column("Source")
|
|
641
|
+
ff = result["feature_x_enabled"]
|
|
642
|
+
table.add_row("feature_x_enabled", str(ff["value"]), ff["source"])
|
|
643
|
+
console.print(table)
|
|
644
|
+
else:
|
|
645
|
+
# Plain text fallback
|
|
646
|
+
print("Configuration:")
|
|
647
|
+
for section_name in ["Environment", "Debug", "Logging", "User Profile"]:
|
|
648
|
+
print(f"[{section_name}]")
|
|
649
|
+
for k, info in result[section_name].items():
|
|
650
|
+
print(f"- {k}: {info['value']} (source: {info['source']})")
|
|
651
|
+
ff = result["feature_x_enabled"]
|
|
652
|
+
print(f"feature_x_enabled: {ff['value']} (source: {ff['source']})")
|
|
653
|
+
|
|
654
|
+
return result
|
|
@@ -10,7 +10,6 @@ These GUIDS should be copied into the pyegeria/__init__.py.
|
|
|
10
10
|
from datetime import datetime
|
|
11
11
|
from rich.console import Console
|
|
12
12
|
from pyegeria.egeria_tech_client import EgeriaTech
|
|
13
|
-
from pyegeria._globals import NO_ELEMENTS_FOUND
|
|
14
13
|
|
|
15
14
|
console = Console(width=200)
|
|
16
15
|
integration_server = "qs-integration-daemon"
|