pyegeria 5.3.9.9.3__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/__init__.py +1 -17
- commands/cat/collection_actions.py +197 -0
- commands/cat/dr_egeria_command_help.py +372 -0
- commands/cat/dr_egeria_jupyter.py +7 -7
- commands/cat/dr_egeria_md.py +27 -182
- 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 +46 -138
- 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/run_report_orig.py +528 -0
- commands/cli/egeria.py +222 -247
- commands/cli/egeria_cat.py +68 -81
- commands/cli/egeria_my.py +13 -0
- commands/cli/egeria_ops.py +69 -74
- commands/cli/egeria_tech.py +17 -93
- commands/cli/ops_config.py +3 -6
- commands/{cat/list_categories.py → deprecated/list_data_designer.py} +53 -64
- commands/{cat/list_data_structures.py → 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 +35 -26
- 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 +90 -0
- 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 +17568 -0
- md_processing/data/commands_working.json +30641 -0
- 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/__init__.py +3 -0
- md_processing/md_commands/data_designer_commands.py +1276 -0
- 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 +684 -0
- md_processing/md_commands/governance_officer_commands.py +600 -0
- md_processing/md_commands/product_manager_commands.py +1266 -0
- md_processing/md_commands/project_commands.py +383 -0
- md_processing/md_commands/solution_architect_commands.py +1184 -0
- md_processing/md_commands/view_commands.py +295 -0
- md_processing/md_processing_utils/__init__.py +4 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +1249 -0
- md_processing/md_processing_utils/common_md_utils.py +578 -0
- md_processing/md_processing_utils/determine_width.py +103 -0
- md_processing/md_processing_utils/extraction_utils.py +547 -0
- md_processing/md_processing_utils/gen_report_specs.py +643 -0
- md_processing/md_processing_utils/generate_dr_help.py +193 -0
- md_processing/md_processing_utils/generate_md_cmd_templates.py +144 -0
- md_processing/md_processing_utils/generate_md_templates.py +83 -0
- md_processing/md_processing_utils/md_processing_constants.py +1228 -0
- md_processing/md_processing_utils/message_constants.py +19 -0
- pyegeria/__init__.py +201 -443
- pyegeria/core/__init__.py +40 -0
- pyegeria/core/_base_platform_client.py +574 -0
- pyegeria/core/_base_server_client.py +573 -0
- pyegeria/core/_exceptions.py +457 -0
- pyegeria/core/_globals.py +60 -0
- pyegeria/core/_server_client.py +6073 -0
- pyegeria/core/_validators.py +257 -0
- 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/core/logging_configuration.py +207 -0
- pyegeria/core/mcp_adapter.py +144 -0
- pyegeria/core/mcp_server.py +212 -0
- pyegeria/core/utils.py +405 -0
- pyegeria/deprecated/__init__.py +0 -0
- pyegeria/{_client.py → deprecated/_client.py} +62 -24
- pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
- pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1988 -1878
- pyegeria/deprecated/output_formatter_with_machine_keys.py +1127 -0
- pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +216 -229
- 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 +25 -51
- pyegeria/egeria_client.py +140 -98
- pyegeria/egeria_config_client.py +48 -24
- pyegeria/egeria_tech_client.py +170 -83
- pyegeria/models/__init__.py +150 -0
- pyegeria/models/collection_models.py +168 -0
- pyegeria/models/models.py +654 -0
- 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/omvs/collection_manager.py +5780 -0
- 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_omvs.py → omvs/data_designer.py} +1991 -1691
- 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/omvs/glossary_manager.py +3231 -0
- pyegeria/omvs/governance_officer.py +3009 -0
- 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/omvs/solution_architect.py +6490 -0
- 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/view/_output_format_models.py +514 -0
- 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.3.9.9.3.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/README.md +0 -16
- commands/cli/txt_custom_v2.tcss +0 -19
- commands/my/README.md +0 -17
- commands/ops/README.md +0 -24
- commands/ops/monitor_asset_events.py +0 -108
- commands/tech/README.md +0 -24
- pyegeria/.DS_Store +0 -0
- pyegeria/README.md +0 -35
- pyegeria/_globals.py +0 -47
- pyegeria/_validators.py +0 -385
- pyegeria/asset_catalog_omvs.py +0 -864
- pyegeria/automated_curation_omvs.py +0 -3765
- pyegeria/collection_manager_omvs.py +0 -2744
- pyegeria/dr.egeria spec.md +0 -9
- pyegeria/egeria_my_client.py +0 -56
- pyegeria/feedback_manager_omvs.py +0 -4573
- pyegeria/glossary_browser_omvs.py +0 -3728
- pyegeria/glossary_manager_omvs.py +0 -2440
- pyegeria/m_test.py +0 -118
- 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/output_formatter.py +0 -389
- pyegeria/project_manager_omvs.py +0 -1933
- pyegeria/registered_info.py +0 -167
- pyegeria/solution_architect_omvs.py +0 -2156
- pyegeria/template_manager_omvs.py +0 -1414
- pyegeria/utils.py +0 -197
- pyegeria-5.3.9.9.3.dist-info/METADATA +0 -72
- pyegeria-5.3.9.9.3.dist-info/RECORD +0 -143
- pyegeria-5.3.9.9.3.dist-info/entry_points.txt +0 -99
- /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
- {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This file contains general utility functions for processing Egeria Markdown
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Any
|
|
8
|
+
from loguru import logger
|
|
9
|
+
from rich import print
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.markdown import Markdown
|
|
12
|
+
|
|
13
|
+
from pyegeria import ServerClient, PyegeriaException
|
|
14
|
+
from pyegeria.core.utils import (camel_to_title_case)
|
|
15
|
+
from pyegeria.core._globals import DEBUG_LEVEL
|
|
16
|
+
from md_processing.md_processing_utils.message_constants import message_types
|
|
17
|
+
|
|
18
|
+
# Constants
|
|
19
|
+
EGERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
|
|
20
|
+
EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
|
|
21
|
+
EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
|
|
22
|
+
EGERIA_VIEW_SERVER = os.environ.get("EGERIA_VIEW_SERVER", "view-server")
|
|
23
|
+
EGERIA_VIEW_SERVER_URL = os.environ.get("EGERIA_VIEW_SERVER_URL", "https://localhost:9443")
|
|
24
|
+
EGERIA_INTEGRATION_DAEMON = os.environ.get("EGERIA_INTEGRATION_DAEMON", "integration-daemon")
|
|
25
|
+
EGERIA_INTEGRATION_DAEMON_URL = os.environ.get("EGERIA_INTEGRATION_DAEMON_URL", "https://localhost:9443")
|
|
26
|
+
EGERIA_ADMIN_USER = os.environ.get("ADMIN_USER", "garygeeke")
|
|
27
|
+
EGERIA_ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "secret")
|
|
28
|
+
EGERIA_USER = os.environ.get("EGERIA_USER", "erinoverview")
|
|
29
|
+
EGERIA_USER_PASSWORD = os.environ.get("EGERIA_USER_PASSWORD", "secret")
|
|
30
|
+
EGERIA_WIDTH = os.environ.get("EGERIA_WIDTH", 220)
|
|
31
|
+
EGERIA_JUPYTER = os.environ.get("EGERIA_JUPYTER", False)
|
|
32
|
+
EGERIA_HOME_GLOSSARY_GUID = os.environ.get("EGERIA_HOME_GLOSSARY_GUID", None)
|
|
33
|
+
EGERIA_GLOSSARY_PATH = os.environ.get("EGERIA_GLOSSARY_PATH", None)
|
|
34
|
+
EGERIA_ROOT_PATH = os.environ.get("EGERIA_ROOT_PATH", "../../")
|
|
35
|
+
EGERIA_INBOX_PATH = os.environ.get("EGERIA_INBOX_PATH", "md_processing/dr_egeria_inbox")
|
|
36
|
+
EGERIA_OUTBOX_PATH = os.environ.get("EGERIA_OUTBOX_PATH", "md_processing/dr_egeria_outbox")
|
|
37
|
+
|
|
38
|
+
GENERAL_GOVERNANCE_DEFINITIONS = ["Governance Definition", "Business Imperative", "Regulation Article", "Threat",
|
|
39
|
+
"Governance Policy", "Governance Principle", "Governance Obligation",
|
|
40
|
+
"Governance Approach",
|
|
41
|
+
"Governance Processing Purpose"]
|
|
42
|
+
GOVERNANCE_DRIVERS = ["Governance Driver", "Governance Strategy", "Governance Imperative", "Regulation",
|
|
43
|
+
"Regulation Article", "Threat"]
|
|
44
|
+
GOVERNANCE_POLICIES = ["Governance Policy", "Governance Principle", "Governance Obligation", "Governance Approach"]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
GOVERNANCE_CONTROLS = ["Governance Control", "Governance Rule", "Service Level Objective", "Governance Action",
|
|
48
|
+
"Security Access Control", "Governance Procedure","Governance Responsibility",
|
|
49
|
+
"Subject Area Definition", "Data Processing Purposes", "Methodology"]
|
|
50
|
+
|
|
51
|
+
ALL_GOVERNANCE_DEFINITIONS = GENERAL_GOVERNANCE_DEFINITIONS + GOVERNANCE_CONTROLS + ["Governance Strategy", "Regulation",
|
|
52
|
+
"Security Group", "GovernanceMetric",
|
|
53
|
+
"Naming Standard Rule", "TermsAndConditions", "Certification Type", "License Type"]
|
|
54
|
+
console = Console(width=EGERIA_WIDTH)
|
|
55
|
+
debug_level = DEBUG_LEVEL
|
|
56
|
+
global COMMAND_DEFINITIONS
|
|
57
|
+
|
|
58
|
+
def split_tb_string(input: str)-> [Any]:
|
|
59
|
+
"""Split the string and trim the items"""
|
|
60
|
+
l = [item.strip() for item in re.split(r'[;,\n]+',input)] if input is not None else None
|
|
61
|
+
return l
|
|
62
|
+
|
|
63
|
+
def str_to_bool(value: str) -> bool:
|
|
64
|
+
"""Converts a string to a boolean value."""
|
|
65
|
+
return value.lower() in ("yes", "true", "t", "1")
|
|
66
|
+
|
|
67
|
+
def render_markdown(markdown_text: str) -> None:
|
|
68
|
+
"""Renders the given markdown text in the console."""
|
|
69
|
+
console.print(Markdown(markdown_text))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def is_valid_iso_date(date_text) -> bool:
|
|
73
|
+
"""Checks if the given string is a valid ISO date."""
|
|
74
|
+
try:
|
|
75
|
+
datetime.strptime(date_text, '%Y-%m-%d')
|
|
76
|
+
return True
|
|
77
|
+
except ValueError:
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def set_debug_level(directive: str) -> None:
|
|
82
|
+
"""Sets the debug level for the script."""
|
|
83
|
+
global debug_level
|
|
84
|
+
if directive == "display":
|
|
85
|
+
debug_level = "display-only"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def get_current_datetime_string():
|
|
89
|
+
"""Returns the current date and time as a human-readable string."""
|
|
90
|
+
now = datetime.now().strftime('%Y-%m-%d %H:%M')
|
|
91
|
+
return now
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def print_msg(msg_level: str, msg: str, verbosity: str):
|
|
95
|
+
"""
|
|
96
|
+
Prints a message based on its type and verbosity level.
|
|
97
|
+
|
|
98
|
+
This function handles the output of messages depending on the specified
|
|
99
|
+
verbosity level and message type. It uses predefined message types and
|
|
100
|
+
formats the output accordingly.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
msg_level: The type of the message, such as 'WARNING', 'ERROR', 'INFO', or
|
|
104
|
+
'ALWAYS'.
|
|
105
|
+
msg: The content of the message to display.
|
|
106
|
+
verbosity: The verbosity level, which determines how the message is
|
|
107
|
+
displayed ('verbose', 'quiet', or 'debug').
|
|
108
|
+
"""
|
|
109
|
+
if msg_level == "ALWAYS":
|
|
110
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
|
111
|
+
# else:
|
|
112
|
+
# logger.info(f"{message_types.get(msg_level, '')}{msg}")
|
|
113
|
+
# elif verbosity == "verbose" and msg_level in ["INFO", "WARNING", "ERROR"]:
|
|
114
|
+
# print(f"{message_types.get(msg_level, '')}{msg}")
|
|
115
|
+
# elif verbosity == "quiet" and msg_level in ["WARNING", "ERROR"]:
|
|
116
|
+
# print(f"{message_types.get(msg_level, '')}{msg}")
|
|
117
|
+
# elif verbosity == "debug" and msg_level in ["INFO", "WARNING", "ERROR", "DEBUG-INFO", "DEBUG-WARNING",
|
|
118
|
+
# "DEBUG-ERROR"]:
|
|
119
|
+
# print(f"{message_types.get(msg_level, '')}{msg}")
|
|
120
|
+
# elif verbosity == "display-only" and msg_level in ["ALWAYS", "ERROR"]:
|
|
121
|
+
# print(f"{message_types.get(msg_level, '')}{msg}")
|
|
122
|
+
elif msg_level == "ERROR":
|
|
123
|
+
logger.error(f"{message_types.get(msg_level, '')}{msg}")
|
|
124
|
+
elif msg_level == "WARNING":
|
|
125
|
+
logger.warning(f"{message_types.get(msg_level, '')}{msg}")
|
|
126
|
+
elif msg_level == "DEBUG":
|
|
127
|
+
logger.debug(f"{message_types.get(msg_level, '')}{msg}")
|
|
128
|
+
else:
|
|
129
|
+
logger.info(f"{message_types.get(msg_level, '')}{msg}")
|
|
130
|
+
|
|
131
|
+
def process_provenance_command(file_path: str, txt: [str]) -> str:
|
|
132
|
+
"""
|
|
133
|
+
Processes a provenance object_action by extracting the file path and current datetime.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
file_path: The path to the file being processed.
|
|
137
|
+
txt: The text containing the provenance object_action.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
A string containing the provenance information.
|
|
141
|
+
"""
|
|
142
|
+
now = get_current_datetime_string()
|
|
143
|
+
file_name = os.path.basename(file_path)
|
|
144
|
+
provenance = f"\n\n\n# Provenance:\n \n* Derived from processing file {file_name} on {now}\n"
|
|
145
|
+
return provenance
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# Dictionary to store element information to avoid redundant API calls
|
|
149
|
+
element_dictionary = {}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def get_element_dictionary():
|
|
153
|
+
"""
|
|
154
|
+
Get the shared element dictionary.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
dict: The shared element dictionary
|
|
158
|
+
"""
|
|
159
|
+
global element_dictionary
|
|
160
|
+
return element_dictionary
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def update_element_dictionary(key, value):
|
|
164
|
+
"""
|
|
165
|
+
Update the shared element dictionary with a new key-value pair.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
key (str): The key to update
|
|
169
|
+
value (dict): The value to associate with the key
|
|
170
|
+
"""
|
|
171
|
+
global element_dictionary
|
|
172
|
+
if (key is None or value is None):
|
|
173
|
+
print(f"===>ERROR Key is {key} and value is {value}")
|
|
174
|
+
return
|
|
175
|
+
element_dictionary[key] = value
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def clear_element_dictionary():
|
|
179
|
+
"""
|
|
180
|
+
Clear the shared element dictionary.
|
|
181
|
+
"""
|
|
182
|
+
global element_dictionary
|
|
183
|
+
element_dictionary.clear()
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def is_present(value: str) -> bool:
|
|
187
|
+
global element_dictionary
|
|
188
|
+
present = value in element_dictionary.keys() or any(
|
|
189
|
+
value in inner_dict.values() for inner_dict in element_dictionary.values())
|
|
190
|
+
return present
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def find_key_with_value(value: str) -> str | None:
|
|
194
|
+
"""
|
|
195
|
+
Finds the top-level key whose nested dictionary contains the given value.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
data (dict): A dictionary where keys map to nested dictionaries.
|
|
199
|
+
value (str): The value to search for.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
str | None: The top-level key that contains the value, or None if not found.
|
|
203
|
+
"""
|
|
204
|
+
global element_dictionary
|
|
205
|
+
# Check if the value matches a top-level key
|
|
206
|
+
if value in element_dictionary.keys():
|
|
207
|
+
return value
|
|
208
|
+
|
|
209
|
+
# Check if the value exists in any of the nested dictionaries
|
|
210
|
+
for key, inner_dict in element_dictionary.items():
|
|
211
|
+
if value in inner_dict.values():
|
|
212
|
+
return key
|
|
213
|
+
|
|
214
|
+
return None # If value not found
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def set_find_body(object_type: str, attributes: dict)->dict:
|
|
218
|
+
prop_name = object_type.replace(" ", "")
|
|
219
|
+
s = attributes.get('Search String', {}).get('value', None)
|
|
220
|
+
search_string = None if s =='*' else s
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
body = {
|
|
224
|
+
"class": "SearchStringRequestBody",
|
|
225
|
+
"searchString": search_string,
|
|
226
|
+
"startsWith": attributes.get('Start With', {}).get('value', True),
|
|
227
|
+
"endWith": attributes.get('End With', {}).get('value', False),
|
|
228
|
+
"ignoreCase": attributes.get('Ignore Case', {}).get('value', False),
|
|
229
|
+
"limitResultsByStatus": attributes.get('Limit Results By Status', {}).get('value', []),
|
|
230
|
+
"startFrom": int(attributes.get('Start From', {}).get('value', 0)),
|
|
231
|
+
"pageSize": int(attributes.get('Page Size', {}).get('value', 0)),
|
|
232
|
+
# "metadataElementSubtypeNames": attributes.get('Metadata Element Subtype Name', {}).get('value', None),
|
|
233
|
+
"metadataElementTypeName": attributes.get('Metadata Element Type Name', {}).get('value', None),
|
|
234
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
235
|
+
"governanceZoneFilter" : attributes.get('Governance Zone Filter', {}).get('value', None),
|
|
236
|
+
"graphQueryDepth": int(attributes.get('Graph Query Depth', {}).get('value', 0)),
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return body
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def set_create_body(object_type: str, attributes: dict)->dict:
|
|
243
|
+
"""
|
|
244
|
+
Build the OUTER request body for a create action (NewElementRequestBody).
|
|
245
|
+
|
|
246
|
+
Notes on two-layer convention:
|
|
247
|
+
- Outer layer (this function): action wrapper with metadata like externalSource*, effectiveTime, anchor/parent hints, and an empty "properties" field.
|
|
248
|
+
- Inner layer: an element-type-specific Properties structure built by set_element_prop_body, set_product_body, set_data_field_body, etc.
|
|
249
|
+
Callers should build the inner body separately with the appropriate helper and then assign it to body["properties"].
|
|
250
|
+
"""
|
|
251
|
+
prop_name = object_type.replace(" ", "")
|
|
252
|
+
body = {
|
|
253
|
+
"class": "NewElementRequestBody",
|
|
254
|
+
"externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
|
|
255
|
+
"externalSourceName": attributes.get('External Source Name', {}).get('value', None),
|
|
256
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
257
|
+
"governanceZoneFilter" : attributes.get('Governance Zone Filter', {}).get('value', None),
|
|
258
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
259
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False),
|
|
260
|
+
"anchorGUID": attributes.get('Anchor ID', {}).get('guid', None),
|
|
261
|
+
"isOwnAnchor": attributes.get('Is Own Anchor', {}).get('value', True),
|
|
262
|
+
"parentGUID": attributes.get('Parent ID', {}).get('guid', None),
|
|
263
|
+
"parentRelationshipTypeName": attributes.get('Parent Relationship Type Name', {}).get('value', None),
|
|
264
|
+
"parentRelationshipProperties": attributes.get('Parent Relationship Properties', {}).get('value', None),
|
|
265
|
+
"parentAtEnd1": attributes.get('Parent at End1', {}).get('value', True),
|
|
266
|
+
"anchorScopeGUID": attributes.get('Anchor Scope GUID', {}).get('guid', None),
|
|
267
|
+
"properties": "",
|
|
268
|
+
"initialStatus": attributes.get('Status', {}).get('value', "ACTIVE"),
|
|
269
|
+
"initialClassifications": {}}
|
|
270
|
+
|
|
271
|
+
return body
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def set_update_body(object_type: str, attributes: dict)->dict:
|
|
277
|
+
"""
|
|
278
|
+
Build the OUTER request body for an update action (UpdateElementRequestBody).
|
|
279
|
+
|
|
280
|
+
Two-layer convention:
|
|
281
|
+
- Outer layer (this function) provides action metadata and an empty "properties" slot.
|
|
282
|
+
- Inner layer must be constructed via element-specific helpers (e.g., set_element_prop_body) and assigned to the returned dict's "properties" key by the caller before invoking the client.
|
|
283
|
+
"""
|
|
284
|
+
return {
|
|
285
|
+
"class" : "UpdateElementRequestBody",
|
|
286
|
+
"externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
|
|
287
|
+
"externalSourceName": attributes.get('External Source Name', {}).get('value', None),
|
|
288
|
+
"governanceZoneFilter": attributes.get('Governance Zone Filter', {}).get('value', None),
|
|
289
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
290
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
291
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False),
|
|
292
|
+
"mergeUpdate": attributes.get('Merge Update', {}).get('value', True),
|
|
293
|
+
"properties": "",
|
|
294
|
+
}
|
|
295
|
+
def set_rel_prop_body(object_type: str, attributes: dict)->dict:
|
|
296
|
+
prop_name = object_type.replace(" ", "")
|
|
297
|
+
display_name = attributes.get('Display Name', {}).get('value', None)
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
"class": prop_name + "Properties",
|
|
301
|
+
"description": attributes['Description'].get('value', None),
|
|
302
|
+
"label": attributes.get('Label', {}).get('value', None) or attributes.get('Link Label', {}).get('value', None),
|
|
303
|
+
"typeName" : attributes.get('Type Name', {}).get('value', None),
|
|
304
|
+
"effectiveFrom": attributes.get('Effective From', {}).get('value', None),
|
|
305
|
+
"effectiveTo": attributes.get('Effective To', {}).get('value', None),
|
|
306
|
+
"extendedProperties": attributes.get('Extended Properties', {}).get('value', None),
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
def set_element_prop_body(object_type: str, qualified_name: str, attributes: dict)->dict:
|
|
310
|
+
"""
|
|
311
|
+
Build the INNER element-specific Properties body to be placed under the outer body's "properties" key.
|
|
312
|
+
|
|
313
|
+
This returns the typed properties structure (e.g., "ReferenceableProperties" subtypes) appropriate for the object_type.
|
|
314
|
+
Usage example:
|
|
315
|
+
- outer = set_create_body(object_type, attributes)
|
|
316
|
+
- props = set_element_prop_body(object_type, qualified_name, attributes)
|
|
317
|
+
- outer["properties"] = props
|
|
318
|
+
- client.create_xxx(outer)
|
|
319
|
+
"""
|
|
320
|
+
prop_name = object_type.replace(" ", "")
|
|
321
|
+
display_name = attributes.get('Display Name', {}).get('value', None)
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
"class": prop_name + "Properties",
|
|
325
|
+
"displayName": attributes.get('Display Name', {}).get('value', None),
|
|
326
|
+
"qualifiedName" : qualified_name,
|
|
327
|
+
"description": attributes['Description'].get('value', None),
|
|
328
|
+
"category": attributes.get('Category', {}).get('value', None),
|
|
329
|
+
"identifier": attributes.get('Identifier', {}).get('value', None),
|
|
330
|
+
"userDefinedStatus": attributes.get('User Defined Status', {}).get('value', None),
|
|
331
|
+
"versionIdentifier": attributes.get('Version Identifier', {}).get('value', None),
|
|
332
|
+
"effectiveFrom": attributes.get('Effective From', {}).get('value', None),
|
|
333
|
+
"effectiveTo": attributes.get('Effective To', {}).get('value', None),
|
|
334
|
+
"additionalProperties": attributes.get('Additional Properties', {}).get('value', None),
|
|
335
|
+
"extendedProperties": attributes.get('Extended Properties', {}).get('value', None),
|
|
336
|
+
"supportLevel": attributes.get('Support Level', {}).get('value', None),
|
|
337
|
+
"serviceLevels": attributes.get('Service Levels', {}).get('value', None),
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
def set_product_body(object_type: str, qualified_name: str, attributes: dict)->dict:
|
|
341
|
+
prop_bod = set_element_prop_body(object_type, qualified_name, attributes)
|
|
342
|
+
prop_bod["identifier"] = attributes.get('Identifier', {}).get('value', None)
|
|
343
|
+
prop_bod["productName"] = attributes.get('Product Name', {}).get('value', None)
|
|
344
|
+
prop_bod["maturity"] = attributes.get('Maturity', {}).get('value', None)
|
|
345
|
+
prop_bod["serviceLife"] = attributes.get('Service Life', {}).get('value', None)
|
|
346
|
+
prop_bod["introductionDate"] = attributes.get('Introduction Date', {}).get('value', [])
|
|
347
|
+
prop_bod["withdrawalDate"] = attributes.get('Withdrawal Date', {}).get('value', [])
|
|
348
|
+
prop_bod["nextVersion"] = attributes.get('Next Version Date', {}).get('value', [])
|
|
349
|
+
return prop_bod
|
|
350
|
+
|
|
351
|
+
def set_data_field_body(object_type: str, qualified_name: str, attributes: dict)->dict:
|
|
352
|
+
prop_bod = set_element_prop_body(object_type, qualified_name, attributes)
|
|
353
|
+
prop_bod["namespace"] = attributes.get('Namespace', {}).get('value', None)
|
|
354
|
+
prop_bod["aliases"] = attributes.get('Aliases', {}).get('value', [])
|
|
355
|
+
prop_bod["namePatterns"] = attributes.get('Name Patterns', {}).get('value', [])
|
|
356
|
+
prop_bod["defaultValue"] = attributes.get('Default Value', {}).get('value', None)
|
|
357
|
+
prop_bod["isNullable"] = attributes.get('Is Nullable', {}).get('value', None)
|
|
358
|
+
prop_bod["dataType"] = attributes.get('Data Type', {}).get('value', None)
|
|
359
|
+
prop_bod["units"] = attributes.get('Units', {}).get('value', None)
|
|
360
|
+
prop_bod["minimumLength"] = attributes.get('Minimum Length', {}).get('value', None)
|
|
361
|
+
prop_bod["length"] = attributes.get('Length', {}).get('value', None)
|
|
362
|
+
prop_bod["precision"] = attributes.get('Precision', {}).get('value', None)
|
|
363
|
+
prop_bod["orderedValues"] = attributes.get('Ordered Values', {}).get('value', [])
|
|
364
|
+
prop_bod["sortOrder"] = attributes.get('Sort Order', {}).get('value', None)
|
|
365
|
+
return prop_bod
|
|
366
|
+
|
|
367
|
+
def set_update_status_body(object_type: str, attributes: dict)->dict:
|
|
368
|
+
return {
|
|
369
|
+
"class" : "UpdateStatusRequestBody",
|
|
370
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
371
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
372
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False),
|
|
373
|
+
"mergeUpdate": attributes.get('Merge Update', {}).get('value', True),
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
def set_gov_prop_body(object_type: str, qualified_name: str, attributes: dict)->dict:
|
|
377
|
+
prop_name = object_type.replace(" ", "")
|
|
378
|
+
prop_bod = set_element_prop_body(object_type, qualified_name, attributes)
|
|
379
|
+
prop_bod["domainIdentifier"] = attributes.get('Domain Identifier', {}).get('value', None)
|
|
380
|
+
prop_bod["displayName"]= attributes.get('Display Name', {}).get('value', None)
|
|
381
|
+
prop_bod['qualifiedName'] = qualified_name
|
|
382
|
+
prop_bod["versionIdentifier"] = attributes.get('Version Identifier', {}).get('value', None)
|
|
383
|
+
prop_bod["summary"] = attributes.get('Summary', {}).get('value', None)
|
|
384
|
+
prop_bod["description"] = attributes.get('Description', {}).get('value', None)
|
|
385
|
+
|
|
386
|
+
prop_bod["scope"] = attributes.get('Scope', {}).get('value', None)
|
|
387
|
+
prop_bod["importance"] = attributes.get('Importance', {}).get('value', None)
|
|
388
|
+
prop_bod["implications"] = attributes.get('Implication', {}).get('value', [])
|
|
389
|
+
prop_bod["outcomes"] = attributes.get('Outcomes', {}).get('value', [])
|
|
390
|
+
prop_bod["results"] = attributes.get('Results', {}).get('value', []) or []
|
|
391
|
+
prop_bod["effectiveFrom"] = attributes.get('Effective From', {}).get('value', None),
|
|
392
|
+
prop_bod["effectiveTo"] = attributes.get('Effective To', {}).get('value', None),
|
|
393
|
+
prop_bod["additionalProperties"] = attributes.get('Additional Properties', {}).get('value', None),
|
|
394
|
+
prop_bod["extendedProperties"] = attributes.get('Extended Properties', {}).get('value', None)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
body = update_gov_body_for_type(object_type, prop_bod, attributes)
|
|
398
|
+
return body
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def update_gov_body_for_type(object_type: str, body: dict, attributes: dict) -> dict:
|
|
402
|
+
gov_def_name = object_type.replace(" ", "")
|
|
403
|
+
if object_type in GENERAL_GOVERNANCE_DEFINITIONS:
|
|
404
|
+
return body
|
|
405
|
+
elif object_type == "Governance Strategy":
|
|
406
|
+
body['businessImperatives'] = attributes.get('Business Imperatives', {}).get('value', [])
|
|
407
|
+
return body
|
|
408
|
+
|
|
409
|
+
elif object_type == "Regulation":
|
|
410
|
+
body['regulationSource'] = attributes.get('Regulation Source', {}).get('value', None)
|
|
411
|
+
body['regulators'] = attributes.get('Regulators', {}).get('value', [])
|
|
412
|
+
return body
|
|
413
|
+
|
|
414
|
+
elif object_type in GOVERNANCE_CONTROLS:
|
|
415
|
+
body['implementationDescription'] = attributes.get('Implementation Description', {}).get('value', None)
|
|
416
|
+
return body
|
|
417
|
+
elif object_type == "Security Group":
|
|
418
|
+
body['distinguishedName'] = attributes.get('Distinguished Name', {}).get('value', None)
|
|
419
|
+
return body
|
|
420
|
+
elif object_type == "GovernanceMetric":
|
|
421
|
+
body['measurement'] = attributes.get('Measurement', {}).get('value', None)
|
|
422
|
+
body['target'] = attributes.get('Target', {}).get('value', None)
|
|
423
|
+
return body
|
|
424
|
+
elif object_type == "Naming Standard Rule":
|
|
425
|
+
body['namePatterns'] = attributes.get('Name Patterns', {}).get('value', [])
|
|
426
|
+
return body
|
|
427
|
+
elif object_type in ["TermsAndConditions", "Certification Type", "License Type"]:
|
|
428
|
+
entitlements = attributes.get('Entitlementss', {}).get('value', {}) if attributes.get('Entitlementss',None) else None
|
|
429
|
+
restrictions = attributes.get('Restrictions', {}).get('value', {}) if attributes.get('Restrictions',None) else None
|
|
430
|
+
obligations = attributes.get('Obligations', {}).get('value', {}) if attributes.get('Obligations',None) else None
|
|
431
|
+
body['entitlements'] = entitlements
|
|
432
|
+
body['restrictions'] = restrictions
|
|
433
|
+
body['obligations'] = obligations
|
|
434
|
+
|
|
435
|
+
return body
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def set_rel_request_body(object_type: str, attributes: dict)->dict:
|
|
439
|
+
"""
|
|
440
|
+
Build the OUTER request body for creating a relationship (NewRelationshipRequestBody).
|
|
441
|
+
The inner relationship properties must be assigned to the returned dict under the "properties" key,
|
|
442
|
+
commonly via set_rel_prop_body or set_rel_request_body_for_type.
|
|
443
|
+
"""
|
|
444
|
+
return {
|
|
445
|
+
"class" : "NewRelationshipRequestBody",
|
|
446
|
+
"externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
|
|
447
|
+
"externalSourceName": attributes.get('External Source Name', {}).get('value', None),
|
|
448
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
449
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
450
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False),
|
|
451
|
+
"properties": "",
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
def set_peer_gov_def_request_body(object_type: str, attributes: dict)->dict:
|
|
455
|
+
rel_body = set_rel_request_body(object_type, attributes)
|
|
456
|
+
rel_body["properties"] = {
|
|
457
|
+
"class" : "PeerDefinitionProperties",
|
|
458
|
+
"description": attributes.get('Description', {}).get('value', None),
|
|
459
|
+
"effectiveFrom": attributes.get('Effective From', {}).get('value', None),
|
|
460
|
+
"effectiveTo": attributes.get('Effective To', {}).get('value', None),
|
|
461
|
+
"label": attributes.get('Label', {}).get('value', None),
|
|
462
|
+
}
|
|
463
|
+
return rel_body
|
|
464
|
+
|
|
465
|
+
def set_rel_request_body_for_type(object_type: str, attributes: dict)->dict:
|
|
466
|
+
"""
|
|
467
|
+
Convenience helper that builds both layers (outer + inner) for a relationship of a known type.
|
|
468
|
+
It creates the outer NewRelationshipRequestBody via set_rel_request_body and fills rel_body["properties"]
|
|
469
|
+
with a typed properties structure under the "class" of f"{object_type}Properties".
|
|
470
|
+
"""
|
|
471
|
+
rel_body = set_rel_request_body(object_type, attributes)
|
|
472
|
+
# class_prop = camel_to_title_case(object_type) + "Properties"
|
|
473
|
+
class_prop = f"{object_type}Properties"
|
|
474
|
+
rel_body["properties"] = {
|
|
475
|
+
"class" : class_prop,
|
|
476
|
+
"description": attributes.get('Description', {}).get('value', None),
|
|
477
|
+
"effectiveFrom": attributes.get('Effective From', {}).get('value', None),
|
|
478
|
+
"effectiveTo": attributes.get('Effective To', {}).get('value', None),
|
|
479
|
+
"label": attributes.get('Label', {}).get('value', None),
|
|
480
|
+
}
|
|
481
|
+
return rel_body
|
|
482
|
+
|
|
483
|
+
def set_delete_request_body(object_type: str, attributes: dict)->dict:
|
|
484
|
+
return {
|
|
485
|
+
"class": "DeleteElementRequestBody",
|
|
486
|
+
"externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
|
|
487
|
+
"externalSourceName": attributes.get('External Source Name', {}).get('value', None),
|
|
488
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
489
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
490
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False)
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def set_filter_request_body(object_type: str, attributes: dict)->dict:
|
|
496
|
+
return {
|
|
497
|
+
"class": "FilterRequestBody",
|
|
498
|
+
"asOfTime": attributes.get('AsOfTime', {}).get('value', None),
|
|
499
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
500
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
501
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False),
|
|
502
|
+
"limitResultsByStatus": attributes.get('Limit Result by Status', {}).get('value', None),
|
|
503
|
+
"sequencingOrder": attributes.get('Sequencing Order', {}).get('value', None),
|
|
504
|
+
"sequencingProperty": attributes.get('Sequencing Property', {}).get('value', None),
|
|
505
|
+
"filter": attributes.get('Search String', {}).get('value', None),
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
def set_element_status_request_body(object_type: str, attributes: dict)->dict:
|
|
509
|
+
return {
|
|
510
|
+
"class": f"{camel_to_title_case(object_type)}StatusRequestBody",
|
|
511
|
+
"status": attributes.get('Status', {}).get('value', None),
|
|
512
|
+
"externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
|
|
513
|
+
"externalSourceName": attributes.get('External Source Name', {}).get('value', None),
|
|
514
|
+
"effectiveTime": attributes.get('Effective Time', {}).get('value', None),
|
|
515
|
+
"forLineage": attributes.get('For Lineage', {}).get('value', False),
|
|
516
|
+
"forDuplicateProcessing": attributes.get('For Duplicate Processing', {}).get('value', False)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def set_classifications(object_type: str, attributes: dict)->dict:
|
|
521
|
+
classifications = attributes.get('Classifications', {}).get('name_list', None)
|
|
522
|
+
body = None
|
|
523
|
+
if classifications:
|
|
524
|
+
body = {classification: {} for classification in classifications} if classifications else {}
|
|
525
|
+
return body
|
|
526
|
+
|
|
527
|
+
def set_object_classifications(object_type: str, attributes: dict, obj_types: list[str])->dict:
|
|
528
|
+
classifications = attributes.get('Classifications', {}).get('name_list', None)
|
|
529
|
+
obj = object_type.replace(" ", "")
|
|
530
|
+
if object_type in obj_types:
|
|
531
|
+
if classifications:
|
|
532
|
+
if object_type not in classifications:
|
|
533
|
+
classifications.append(obj)
|
|
534
|
+
else:
|
|
535
|
+
classifications = [obj]
|
|
536
|
+
|
|
537
|
+
body = {}
|
|
538
|
+
if classifications:
|
|
539
|
+
for classification in classifications:
|
|
540
|
+
body[classification] = {"class" : f"{classification}Properties"}
|
|
541
|
+
return body
|
|
542
|
+
|
|
543
|
+
def add_search_keywords(client: ServerClient, element_guid: str, keywords: list[str]):
|
|
544
|
+
"""Add a search keyword to an element. Throw an exception if a problem is encountered.
|
|
545
|
+
|
|
546
|
+
Args:
|
|
547
|
+
client (ServerClient): The Egeria client instance.
|
|
548
|
+
element_guid (str): The GUID of the element to add the keyword to.
|
|
549
|
+
keyword (str): The search keyword to add.
|
|
550
|
+
|
|
551
|
+
Returns:
|
|
552
|
+
None
|
|
553
|
+
"""
|
|
554
|
+
try:
|
|
555
|
+
for keyword in keywords:
|
|
556
|
+
client.add_search_keyword_to_element(element_guid, keyword)
|
|
557
|
+
print("Added keyword `{}` to element `{}`".format(keyword, element_guid))
|
|
558
|
+
|
|
559
|
+
except PyegeriaException as e:
|
|
560
|
+
context = {
|
|
561
|
+
"readon" : "Exception encountered executing add_search_keyword",
|
|
562
|
+
"element_guid": element_guid,
|
|
563
|
+
"keyword": keyword,
|
|
564
|
+
"exception": str(e)
|
|
565
|
+
}
|
|
566
|
+
raise PyegeriaException(context = context)
|
|
567
|
+
|
|
568
|
+
def add_note_in_dr_e(client: ServerClient, qualified_name: str, display_name: str, journal_entry: str)-> str:
|
|
569
|
+
if journal_entry:
|
|
570
|
+
note_log_qn = f"{qualified_name}-NoteLog"
|
|
571
|
+
note_log_display_name = f"{display_name}-NoteLog"
|
|
572
|
+
note_display_name = f"{qualified_name}-Journal-Entry-{datetime.now().strftime('%Y-%m-%d %H:%M')}"
|
|
573
|
+
journal_entry_guid = client.add_journal_entry(note_log_qn, qualified_name, note_log_display_name,
|
|
574
|
+
note_display_name, journal_entry)
|
|
575
|
+
logger.info(f"Added journal entry `{journal_entry_guid}` to `{qualified_name}`")
|
|
576
|
+
return journal_entry_guid
|
|
577
|
+
else:
|
|
578
|
+
return None
|