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,3231 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
Copyright Contributors to the ODPi Egeria project.
|
|
4
|
+
|
|
5
|
+
This module contains an initial version of the glossary_manager module.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import csv
|
|
11
|
+
import os
|
|
12
|
+
from typing import List, Annotated, Literal, Optional
|
|
13
|
+
|
|
14
|
+
from loguru import logger
|
|
15
|
+
from pydantic import Field
|
|
16
|
+
|
|
17
|
+
from pyegeria.core._exceptions import PyegeriaInvalidParameterException
|
|
18
|
+
from pyegeria.core._globals import NO_GUID_RETURNED
|
|
19
|
+
from pyegeria.core._validators import validate_guid
|
|
20
|
+
from pyegeria.omvs.collection_manager import CollectionManager
|
|
21
|
+
from pyegeria.core.config import settings as app_settings
|
|
22
|
+
from pyegeria.models import (NewElementRequestBody, DeleteElementRequestBody, DeleteRelationshipRequestBody,
|
|
23
|
+
ReferenceableProperties, UpdateElementRequestBody, TemplateRequestBody,
|
|
24
|
+
NewRelationshipRequestBody, UpdateRelationshipRequestBody, NewClassificationRequestBody,
|
|
25
|
+
FilterRequestBody, GetRequestBody, SearchStringRequestBody,
|
|
26
|
+
DeleteClassificationRequestBody)
|
|
27
|
+
from pyegeria.view.output_formatter import (generate_output,
|
|
28
|
+
_extract_referenceable_properties, populate_common_columns,
|
|
29
|
+
overlay_additional_values, resolve_output_formats)
|
|
30
|
+
from pyegeria.core.utils import body_slimmer, dynamic_catch
|
|
31
|
+
|
|
32
|
+
EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GlossaryProperties(ReferenceableProperties):
|
|
37
|
+
class_: Annotated[Literal["GlossaryProperties"], Field(alias="class")]
|
|
38
|
+
language: str = "English"
|
|
39
|
+
usage: str = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class GlossaryTermProperties(ReferenceableProperties):
|
|
43
|
+
class_: Annotated[Literal["GlossaryTermProperties"], Field(alias="class")]
|
|
44
|
+
summary: str = None
|
|
45
|
+
description: str = None
|
|
46
|
+
abbreviation: str = None
|
|
47
|
+
examples: str = None
|
|
48
|
+
usage: str = None
|
|
49
|
+
user_defined_status: str = None
|
|
50
|
+
publishVersionIdentifier: str = None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class GlossaryManager(CollectionManager):
|
|
54
|
+
"""
|
|
55
|
+
Client for the Glossary Manager View Service.
|
|
56
|
+
|
|
57
|
+
The Glossary Manager View Service provides methods to create and manage glossaries,
|
|
58
|
+
terms, and categories.
|
|
59
|
+
|
|
60
|
+
Attributes
|
|
61
|
+
----------
|
|
62
|
+
view_server : str
|
|
63
|
+
The name of the View Server to connect to.
|
|
64
|
+
platform_url : str
|
|
65
|
+
URL of the server platform to connect to.
|
|
66
|
+
user_id : str
|
|
67
|
+
The identity of the user calling the method.
|
|
68
|
+
user_pwd : str
|
|
69
|
+
The password associated with the user_id. Defaults to None.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
view_server: str,
|
|
75
|
+
platform_url: str,
|
|
76
|
+
user_id: str,
|
|
77
|
+
user_pwd: Optional[str] = None,
|
|
78
|
+
token: Optional[str] = None,
|
|
79
|
+
):
|
|
80
|
+
self.view_server = view_server
|
|
81
|
+
self.platform_url = platform_url
|
|
82
|
+
self.user_id = user_id
|
|
83
|
+
self.user_pwd = user_pwd
|
|
84
|
+
self.url_marker = "glossary-manager"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
CollectionManager.__init__(self, view_server, platform_url, user_id, user_pwd, token)
|
|
88
|
+
# result = self.get_platform_origin()
|
|
89
|
+
# logger.info(f"GlossaryManager initialized, platform origin is: {result}")
|
|
90
|
+
self.glossary_command_root = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager"
|
|
91
|
+
#
|
|
92
|
+
# Get Valid Values for Enumerations
|
|
93
|
+
#
|
|
94
|
+
|
|
95
|
+
def __validate_term_status__(self, status: str) -> bool:
|
|
96
|
+
"""Return True if the status is a legal glossary term status"""
|
|
97
|
+
recognized_term_status = self.get_glossary_term_statuses()
|
|
98
|
+
return status in recognized_term_status
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# Glossaries
|
|
102
|
+
#
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dynamic_catch
|
|
107
|
+
async def _async_create_glossary(self, display_name: str, description: Optional[str] = None, language: str = "English", usage: Optional[str] = None,
|
|
108
|
+
category: Optional[str] = None, body: Optional[dict | NewElementRequestBody] = None) -> str:
|
|
109
|
+
"""Create a new glossary. Async version.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
display_name : str
|
|
114
|
+
The name of the glossary.
|
|
115
|
+
description : str, optional
|
|
116
|
+
The description of the glossary.
|
|
117
|
+
language : str, optional
|
|
118
|
+
The language of the glossary (default is "English").
|
|
119
|
+
usage : str, optional
|
|
120
|
+
The usage information for the glossary.
|
|
121
|
+
category : str, optional
|
|
122
|
+
The category for the glossary.
|
|
123
|
+
body : dict | NewElementRequestBody, optional
|
|
124
|
+
If provided, the request body for creating the glossary.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
str
|
|
129
|
+
The GUID of the newly created glossary.
|
|
130
|
+
|
|
131
|
+
Raises
|
|
132
|
+
------
|
|
133
|
+
PyegeriaException
|
|
134
|
+
If there are issues in communications, message format, or Egeria errors.
|
|
135
|
+
"""
|
|
136
|
+
if body is None:
|
|
137
|
+
qualified_name = self.__create_qualified_name__("Glossary", display_name, EGERIA_LOCAL_QUALIFIER)
|
|
138
|
+
body = {
|
|
139
|
+
"class": "NewElementRequestBody",
|
|
140
|
+
"is_own_anchor": True,
|
|
141
|
+
"properties": {
|
|
142
|
+
"class": "GlossaryProperties",
|
|
143
|
+
"displayName": display_name,
|
|
144
|
+
"qualifiedName": qualified_name,
|
|
145
|
+
"description": description,
|
|
146
|
+
"language": language,
|
|
147
|
+
"usage": usage,
|
|
148
|
+
"category": category
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
response = await self._async_create_collection(body=body)
|
|
152
|
+
return response
|
|
153
|
+
|
|
154
|
+
def create_glossary(self, display_name: str, description: Optional[str] = None, language: str = "English",
|
|
155
|
+
usage: Optional[str] = None,
|
|
156
|
+
category: Optional[str] = None, body: Optional[dict | NewElementRequestBody] = None) -> str:
|
|
157
|
+
"""Create a new glossary.
|
|
158
|
+
|
|
159
|
+
Parameters
|
|
160
|
+
----------
|
|
161
|
+
display_name : str
|
|
162
|
+
The name of the glossary.
|
|
163
|
+
description : str, optional
|
|
164
|
+
The description of the glossary.
|
|
165
|
+
language : str, optional
|
|
166
|
+
The language of the glossary (default is "English").
|
|
167
|
+
usage : str, optional
|
|
168
|
+
The usage information for the glossary.
|
|
169
|
+
category : str, optional
|
|
170
|
+
The category for the glossary.
|
|
171
|
+
body : dict | NewElementRequestBody, optional
|
|
172
|
+
If provided, the request body for creating the glossary.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
str
|
|
177
|
+
The GUID of the newly created glossary.
|
|
178
|
+
|
|
179
|
+
Raises
|
|
180
|
+
------
|
|
181
|
+
PyegeriaException
|
|
182
|
+
If there are issues in communications, message format, or Egeria errors.
|
|
183
|
+
"""
|
|
184
|
+
loop = asyncio.get_event_loop()
|
|
185
|
+
response = loop.run_until_complete(
|
|
186
|
+
self._async_create_glossary(display_name, description, language, usage, category, body)
|
|
187
|
+
)
|
|
188
|
+
return response
|
|
189
|
+
|
|
190
|
+
async def _async_delete_glossary(self, glossary_guid: str, body: Optional[dict | DeleteElementRequestBody] = None,
|
|
191
|
+
cascade: bool = False) -> None:
|
|
192
|
+
"""Delete glossary. Async version.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
glossary_guid: str
|
|
197
|
+
The ID of the glossary to delete.
|
|
198
|
+
cascade: bool, optional, default = False
|
|
199
|
+
If true, then delete all terms and categories in the glossary as well.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
None
|
|
204
|
+
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
await self._async_delete_collection(glossary_guid, body, cascade)
|
|
208
|
+
|
|
209
|
+
logger.info(f"Deleted glossary {glossary_guid} with cascade {cascade}")
|
|
210
|
+
|
|
211
|
+
def delete_glossary(self, glossary_guid: str, body: Optional[dict | DeleteElementRequestBody] = None, cascade: bool = False) -> None:
|
|
212
|
+
"""Delete a new glossary.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
glossary_guid: str
|
|
217
|
+
The ID of the glossary to delete.
|
|
218
|
+
cascade: bool, optional, default = False
|
|
219
|
+
If true, then delete all terms and categories in the glossary as well.
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
Returns
|
|
223
|
+
-------
|
|
224
|
+
None
|
|
225
|
+
|
|
226
|
+
"""
|
|
227
|
+
loop = asyncio.get_event_loop()
|
|
228
|
+
loop.run_until_complete(self._async_delete_glossary(glossary_guid, body, cascade))
|
|
229
|
+
|
|
230
|
+
async def _async_update_glossary(
|
|
231
|
+
self,
|
|
232
|
+
glossary_guid: str,
|
|
233
|
+
body: dict | UpdateElementRequestBody,
|
|
234
|
+
merge_update: bool = True,
|
|
235
|
+
) -> None:
|
|
236
|
+
"""Update Glossary.
|
|
237
|
+
|
|
238
|
+
Async version.
|
|
239
|
+
|
|
240
|
+
Parameters
|
|
241
|
+
----------
|
|
242
|
+
glossary_guid: str
|
|
243
|
+
The ID of the glossary to update.
|
|
244
|
+
body: dict
|
|
245
|
+
A dict containing the properties to update.
|
|
246
|
+
|
|
247
|
+
Returns
|
|
248
|
+
-------
|
|
249
|
+
None
|
|
250
|
+
|
|
251
|
+
Notes
|
|
252
|
+
-----
|
|
253
|
+
|
|
254
|
+
Sample body:
|
|
255
|
+
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
await self._async_update_collection(glossary_guid, body)
|
|
261
|
+
logger.info(f"Updated glossary {glossary_guid}")
|
|
262
|
+
|
|
263
|
+
def update_glossary(
|
|
264
|
+
self,
|
|
265
|
+
glossary_guid: str,
|
|
266
|
+
body: dict | UpdateElementRequestBody,
|
|
267
|
+
merge_update: bool = True,
|
|
268
|
+
) -> None:
|
|
269
|
+
"""Update Glossary.
|
|
270
|
+
|
|
271
|
+
Parameters
|
|
272
|
+
----------
|
|
273
|
+
glossary_guid: str
|
|
274
|
+
The ID of the glossary to update.
|
|
275
|
+
body: dict
|
|
276
|
+
A dict containing the properties to update.
|
|
277
|
+
is_merge_update: bool, optional, default = True
|
|
278
|
+
If true, then only those properties specified in the body will be updated. If false, then all the
|
|
279
|
+
properties of the glossary will be replaced with those of the body.
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
Returns
|
|
283
|
+
-------
|
|
284
|
+
None
|
|
285
|
+
|
|
286
|
+
Notes
|
|
287
|
+
-----
|
|
288
|
+
|
|
289
|
+
Sample body:
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
"""
|
|
293
|
+
loop = asyncio.get_event_loop()
|
|
294
|
+
loop.run_until_complete(
|
|
295
|
+
self._async_update_glossary(
|
|
296
|
+
glossary_guid,
|
|
297
|
+
body, merge_update
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
#
|
|
302
|
+
# add glossary classifications? is-canonical, is editing, is staging, is taxonomy?
|
|
303
|
+
# Not all show up in UML
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
#
|
|
308
|
+
# Terms
|
|
309
|
+
#
|
|
310
|
+
async def _async_create_glossary_term(
|
|
311
|
+
self, body: dict | NewElementRequestBody
|
|
312
|
+
) -> str:
|
|
313
|
+
"""Create a term for a glossary. Async version.
|
|
314
|
+
|
|
315
|
+
Parameters
|
|
316
|
+
----------
|
|
317
|
+
body : dict | NewElementRequestBody
|
|
318
|
+
The request body for creating the glossary term.
|
|
319
|
+
|
|
320
|
+
Returns
|
|
321
|
+
-------
|
|
322
|
+
str
|
|
323
|
+
The unique GUID for the created term.
|
|
324
|
+
|
|
325
|
+
Raises
|
|
326
|
+
------
|
|
327
|
+
PyegeriaException
|
|
328
|
+
If there are issues in communications, message format, or Egeria errors.
|
|
329
|
+
"""
|
|
330
|
+
|
|
331
|
+
url = (
|
|
332
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms"
|
|
333
|
+
)
|
|
334
|
+
return await self._async_create_element_body_request(url, "GlossaryTermProperties", body)
|
|
335
|
+
|
|
336
|
+
def create_glossary_term(self, body: dict | NewElementRequestBody) -> str:
|
|
337
|
+
"""Create a term for a glossary.
|
|
338
|
+
|
|
339
|
+
Parameters
|
|
340
|
+
----------
|
|
341
|
+
body : dict | NewElementRequestBody
|
|
342
|
+
The request body for creating the glossary term.
|
|
343
|
+
|
|
344
|
+
Returns
|
|
345
|
+
-------
|
|
346
|
+
str
|
|
347
|
+
The unique GUID for the created term.
|
|
348
|
+
|
|
349
|
+
Raises
|
|
350
|
+
------
|
|
351
|
+
PyegeriaException
|
|
352
|
+
If there are issues in communications, message format, or Egeria errors.
|
|
353
|
+
"""
|
|
354
|
+
loop = asyncio.get_event_loop()
|
|
355
|
+
response = loop.run_until_complete(
|
|
356
|
+
self._async_create_glossary_term(body)
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
return response
|
|
360
|
+
|
|
361
|
+
def load_terms_from_csv_file(
|
|
362
|
+
self,
|
|
363
|
+
glossary_name: str,
|
|
364
|
+
filename: str,
|
|
365
|
+
file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
|
|
366
|
+
upsert: bool = True,
|
|
367
|
+
verbose: bool = True,
|
|
368
|
+
) -> List[dict] | None:
|
|
369
|
+
"""This method loads glossary terms into the specified glossary from the indicated file.
|
|
370
|
+
|
|
371
|
+
Parameters
|
|
372
|
+
----------
|
|
373
|
+
glossary_name : str
|
|
374
|
+
Name of the glossary to import terms into.
|
|
375
|
+
file_path: str, default is EGERIA_GLOSSARY_PATH if specified or None
|
|
376
|
+
If EGERIA_GLOSSARY_PATH environment variable is set, then it will be used in forming the
|
|
377
|
+
prepended to the filename parameter to form the full path to the file.
|
|
378
|
+
filename: str
|
|
379
|
+
Path to the file to import terms from. File is assumed to be in CSV format. The path
|
|
380
|
+
is relative to where the python method is being called from.
|
|
381
|
+
upsert: bool, default = True
|
|
382
|
+
If true, terms from the file are inserted into the glossary if no qualified name is specified;
|
|
383
|
+
if a qualified name is specified in the file, then the file values for this term will over-ride the
|
|
384
|
+
values in the glossary. If false, the row in the file will be appended to the glossary, possibly
|
|
385
|
+
resulting in duplicate term names - which is legal (since the qualified names will be unique).
|
|
386
|
+
|
|
387
|
+
verbose: bool, default = True
|
|
388
|
+
If true, a JSON structure will be returned indicating the import status of each row.
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
Returns
|
|
392
|
+
-------
|
|
393
|
+
[dict]:
|
|
394
|
+
If verbose is True, import status for each row
|
|
395
|
+
None:
|
|
396
|
+
If verbose is False
|
|
397
|
+
|
|
398
|
+
Raises
|
|
399
|
+
------
|
|
400
|
+
PyegeriaInvalidParameterException
|
|
401
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
402
|
+
PyegeriaAPIException
|
|
403
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
404
|
+
NotAuthorizedException
|
|
405
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
406
|
+
Notes
|
|
407
|
+
-----
|
|
408
|
+
Keep in mind that the file path is relative to where the python method is being called from -
|
|
409
|
+
not relative to the Egeria platform.
|
|
410
|
+
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
# Check that glossary exists and get guid
|
|
414
|
+
glossaries = self.get_glossaries_by_name(glossary_name)
|
|
415
|
+
if type(glossaries) is not list:
|
|
416
|
+
return "Unknown glossary"
|
|
417
|
+
if len(glossaries) > 1:
|
|
418
|
+
glossary_error = (
|
|
419
|
+
"Multiple glossaries found - please use a qualified name from below\n"
|
|
420
|
+
)
|
|
421
|
+
for g in glossaries:
|
|
422
|
+
glossary_error += (
|
|
423
|
+
f"Display Name: {g['glossaryProperties']['displayName']}\tQualified Name:"
|
|
424
|
+
f" {g['glossaryProperties']['qualifiedName']}\n"
|
|
425
|
+
)
|
|
426
|
+
raise Exception(glossary_error)
|
|
427
|
+
sys.exit(1)
|
|
428
|
+
|
|
429
|
+
# Now we know we have a single glossary so we can get the guid
|
|
430
|
+
glossary_guid = glossaries[0]["elementHeader"]["guid"]
|
|
431
|
+
|
|
432
|
+
term_properties = {
|
|
433
|
+
"Term Name",
|
|
434
|
+
"Qualified Name",
|
|
435
|
+
"Abbreviation",
|
|
436
|
+
"Summary",
|
|
437
|
+
"Description",
|
|
438
|
+
"Examples",
|
|
439
|
+
"Usage",
|
|
440
|
+
"Version Identifier",
|
|
441
|
+
"Status",
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if file_path:
|
|
445
|
+
full_file_path = os.path.join(file_path, filename)
|
|
446
|
+
else:
|
|
447
|
+
full_file_path = filename
|
|
448
|
+
|
|
449
|
+
if not os.path.isfile(full_file_path):
|
|
450
|
+
raise FileNotFoundError(
|
|
451
|
+
f"Did not find file with path {file_path} and name {filename}"
|
|
452
|
+
)
|
|
453
|
+
# process file
|
|
454
|
+
with open(full_file_path, mode="r") as file:
|
|
455
|
+
# Create a CSV reader object
|
|
456
|
+
csv_reader = csv.DictReader(file)
|
|
457
|
+
headers = csv_reader.fieldnames
|
|
458
|
+
term_info = []
|
|
459
|
+
# check that the column headers are known
|
|
460
|
+
if all(header in term_properties for header in headers) is False:
|
|
461
|
+
raise PyegeriaInvalidParameterException(
|
|
462
|
+
None,
|
|
463
|
+
context={"caller_method": "load_terms_from_csv"},
|
|
464
|
+
additional_info={"reason": "Invalid headers in CSV File"},
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
# process each row and validate values
|
|
468
|
+
for row in csv_reader:
|
|
469
|
+
# Parse the file. When the value '---' is encountered, make the value None.git+https:
|
|
470
|
+
term_name = row.get("Term Name", " ")
|
|
471
|
+
if len(term_name) < 2:
|
|
472
|
+
term_info.append(
|
|
473
|
+
{
|
|
474
|
+
"term_name": "---",
|
|
475
|
+
"qualified_name": "---",
|
|
476
|
+
"term_guid": "---",
|
|
477
|
+
"error": "missing or invalid term names - skipping",
|
|
478
|
+
}
|
|
479
|
+
)
|
|
480
|
+
continue
|
|
481
|
+
qualified_name = row.get("Qualified Name", None)
|
|
482
|
+
abbrev_in = row.get("Abbreviation", None)
|
|
483
|
+
abbrev = None if abbrev_in == "---" else abbrev_in
|
|
484
|
+
|
|
485
|
+
summary_in = row.get("Summary", None)
|
|
486
|
+
summary = None if summary_in == "---" else summary_in
|
|
487
|
+
|
|
488
|
+
description_in = row.get("Description", None)
|
|
489
|
+
description = None if description_in == "---" else description_in
|
|
490
|
+
|
|
491
|
+
examples_in = row.get("Examples", None)
|
|
492
|
+
examples = None if examples_in == "---" else examples_in
|
|
493
|
+
|
|
494
|
+
usage_in = row.get("Usage", None)
|
|
495
|
+
usage = None if usage_in == "---" else usage_in
|
|
496
|
+
|
|
497
|
+
version = row.get("Version Identifier", "1.0")
|
|
498
|
+
status = row.get("Status", "DRAFT").upper()
|
|
499
|
+
if self.__validate_term_status__(status) is False:
|
|
500
|
+
term_info.append(
|
|
501
|
+
{
|
|
502
|
+
"term_name": "---",
|
|
503
|
+
"qualified_name": "---",
|
|
504
|
+
"term_guid": "---",
|
|
505
|
+
"error": "invalid term status",
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
continue
|
|
509
|
+
|
|
510
|
+
if upsert:
|
|
511
|
+
# If upsert is set we need to see if it can be done (there must be a valid qualified name) and then
|
|
512
|
+
# do the update for the row - if there is no qualified name we will treat the row as an insert.
|
|
513
|
+
if qualified_name:
|
|
514
|
+
term_stuff = self.get_terms_by_name(
|
|
515
|
+
qualified_name, glossary_guid
|
|
516
|
+
)
|
|
517
|
+
if type(term_stuff) is str:
|
|
518
|
+
# An existing term was not found with that qualified name
|
|
519
|
+
term_info.append(
|
|
520
|
+
{
|
|
521
|
+
"term_name": term_name,
|
|
522
|
+
"qualified_name": qualified_name,
|
|
523
|
+
"error": "Matching term not found - skipping",
|
|
524
|
+
}
|
|
525
|
+
)
|
|
526
|
+
continue
|
|
527
|
+
elif len(term_stuff) > 1:
|
|
528
|
+
term_info.append(
|
|
529
|
+
{
|
|
530
|
+
"term_name": term_name,
|
|
531
|
+
"qualified_name": qualified_name,
|
|
532
|
+
"error": "Multiple matching terms - skipping",
|
|
533
|
+
}
|
|
534
|
+
)
|
|
535
|
+
continue
|
|
536
|
+
else:
|
|
537
|
+
# An existing term was found - so update it! Get the existing values and overlay
|
|
538
|
+
# values from file when present
|
|
539
|
+
|
|
540
|
+
body = {
|
|
541
|
+
"class": "ReferenceableRequestBody",
|
|
542
|
+
"elementProperties": {
|
|
543
|
+
"class": "GlossaryTermProperties",
|
|
544
|
+
"qualifiedName": qualified_name,
|
|
545
|
+
"displayName": term_name,
|
|
546
|
+
"summary": summary,
|
|
547
|
+
"description": description,
|
|
548
|
+
"abbreviation": abbrev,
|
|
549
|
+
"examples": examples,
|
|
550
|
+
"usage": usage,
|
|
551
|
+
"publishVersionIdentifier": version,
|
|
552
|
+
},
|
|
553
|
+
"updateDescription": "Update from file import via upsert",
|
|
554
|
+
}
|
|
555
|
+
term_guid = term_stuff[0]["elementHeader"]["guid"]
|
|
556
|
+
self.update_term(
|
|
557
|
+
term_guid, body_slimmer(body), is_merge_update=True
|
|
558
|
+
)
|
|
559
|
+
term_info.append(
|
|
560
|
+
{
|
|
561
|
+
"term_name": term_name,
|
|
562
|
+
"qualified_name": qualified_name,
|
|
563
|
+
"term_guid": term_guid,
|
|
564
|
+
"updated": "the term was updated",
|
|
565
|
+
}
|
|
566
|
+
)
|
|
567
|
+
continue
|
|
568
|
+
|
|
569
|
+
# Add the term
|
|
570
|
+
term_qualified_name = self.__create_qualified_name__("Term", term_name)
|
|
571
|
+
|
|
572
|
+
body = {
|
|
573
|
+
"class": "ReferenceableRequestBody",
|
|
574
|
+
"elementProperties": {
|
|
575
|
+
"class": "GlossaryTermProperties",
|
|
576
|
+
"qualifiedName": term_qualified_name,
|
|
577
|
+
"displayName": term_name,
|
|
578
|
+
"summary": summary,
|
|
579
|
+
"description": description,
|
|
580
|
+
"abbreviation": abbrev,
|
|
581
|
+
"examples": examples,
|
|
582
|
+
"usage": usage,
|
|
583
|
+
"publishVersionIdentifier": version,
|
|
584
|
+
},
|
|
585
|
+
"initialStatus": status,
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
# Add the term
|
|
589
|
+
term_guid = self.create_controlled_glossary_term(
|
|
590
|
+
glossary_guid, body_slimmer(body)
|
|
591
|
+
)
|
|
592
|
+
term_info.append(
|
|
593
|
+
{
|
|
594
|
+
"term_name": term_name,
|
|
595
|
+
"qualified_name": term_qualified_name,
|
|
596
|
+
"term_guid": term_guid,
|
|
597
|
+
}
|
|
598
|
+
)
|
|
599
|
+
if verbose:
|
|
600
|
+
return term_info
|
|
601
|
+
else:
|
|
602
|
+
return
|
|
603
|
+
|
|
604
|
+
async def _async_export_glossary_to_csv(
|
|
605
|
+
self,
|
|
606
|
+
glossary_guid: str,
|
|
607
|
+
target_file: str,
|
|
608
|
+
file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
|
|
609
|
+
) -> int:
|
|
610
|
+
"""Export all the terms in a glossary to a CSV file. Async version
|
|
611
|
+
|
|
612
|
+
Parameters:
|
|
613
|
+
-----------
|
|
614
|
+
glossary_guid: str
|
|
615
|
+
Identity of the glossary to export.
|
|
616
|
+
target_file: str
|
|
617
|
+
Complete file name with path and extension to export to.
|
|
618
|
+
input_file: str, default is EGERIA_GLOSSARY_PATH if specified or None
|
|
619
|
+
If EGERIA_GLOSSARY_PATH environment variable is set, then it will be used in forming the
|
|
620
|
+
prepended to the filename parameter to form the full path to the file.
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
int: Number of rows exported.
|
|
624
|
+
"""
|
|
625
|
+
|
|
626
|
+
term_list = await self._async_get_terms_for_glossary(glossary_guid)
|
|
627
|
+
|
|
628
|
+
header = [
|
|
629
|
+
"Term Name",
|
|
630
|
+
"Qualified Name",
|
|
631
|
+
"Abbreviation",
|
|
632
|
+
"Summary",
|
|
633
|
+
"Description",
|
|
634
|
+
"Examples",
|
|
635
|
+
"Usage",
|
|
636
|
+
"Version Identifier",
|
|
637
|
+
"Status",
|
|
638
|
+
]
|
|
639
|
+
if file_path:
|
|
640
|
+
full_file_path = os.path.join(file_path, target_file)
|
|
641
|
+
else:
|
|
642
|
+
full_file_path = target_file
|
|
643
|
+
|
|
644
|
+
with open(full_file_path, mode="w") as file:
|
|
645
|
+
csv_writer = csv.DictWriter(file, fieldnames=header)
|
|
646
|
+
csv_writer.writeheader()
|
|
647
|
+
count = 0
|
|
648
|
+
for term in term_list:
|
|
649
|
+
term_name = term["glossaryTermProperties"]["displayName"]
|
|
650
|
+
qualified_name = term["glossaryTermProperties"]["qualifiedName"]
|
|
651
|
+
abbrev = term["glossaryTermProperties"].get("abbreviation", "---")
|
|
652
|
+
summary = term["glossaryTermProperties"].get("summary", "---")
|
|
653
|
+
description = term["glossaryTermProperties"].get("description", "---")
|
|
654
|
+
examples = term["glossaryTermProperties"].get("examples", "---")
|
|
655
|
+
usage = term["glossaryTermProperties"].get("usage", "---")
|
|
656
|
+
version = term["glossaryTermProperties"].get(
|
|
657
|
+
"publishVersionIdentifier", "---"
|
|
658
|
+
)
|
|
659
|
+
status = term["elementHeader"]["status"]
|
|
660
|
+
|
|
661
|
+
csv_writer.writerow(
|
|
662
|
+
{
|
|
663
|
+
"Term Name": term_name,
|
|
664
|
+
"Qualified Name": qualified_name,
|
|
665
|
+
"Abbreviation": abbrev,
|
|
666
|
+
"Summary": summary,
|
|
667
|
+
"Description": description,
|
|
668
|
+
"Examples": examples,
|
|
669
|
+
"Usage": usage,
|
|
670
|
+
"Version Identifier": version,
|
|
671
|
+
"Status": status,
|
|
672
|
+
}
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
count += 1
|
|
676
|
+
return count
|
|
677
|
+
|
|
678
|
+
def export_glossary_to_csv(
|
|
679
|
+
self,
|
|
680
|
+
glossary_guid: str,
|
|
681
|
+
target_file: str,
|
|
682
|
+
file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
|
|
683
|
+
) -> int:
|
|
684
|
+
"""Export all the terms in a glossary to a CSV file.
|
|
685
|
+
|
|
686
|
+
Parameters:
|
|
687
|
+
-----------
|
|
688
|
+
glossary_guid: str
|
|
689
|
+
Identity of the glossary to export.
|
|
690
|
+
target_file: str
|
|
691
|
+
Complete file name with path and extension to export to.
|
|
692
|
+
input_file: str, default is EGERIA_GLOSSARY_PATH if specified or None
|
|
693
|
+
If EGERIA_GLOSSARY_PATH environment variable is set, then it will be used in forming the
|
|
694
|
+
prepended to the filename parameter to form the full path to the file.
|
|
695
|
+
|
|
696
|
+
Returns:
|
|
697
|
+
int: Number of rows exported.
|
|
698
|
+
"""
|
|
699
|
+
|
|
700
|
+
loop = asyncio.get_event_loop()
|
|
701
|
+
response = loop.run_until_complete(
|
|
702
|
+
self._async_export_glossary_to_csv(glossary_guid, target_file, file_path)
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
return response
|
|
706
|
+
|
|
707
|
+
async def _async_create_term_copy(
|
|
708
|
+
self,
|
|
709
|
+
glossary_guid: str,
|
|
710
|
+
glossary_term_guid: str,
|
|
711
|
+
new_display_name: str,
|
|
712
|
+
version_id: Optional[str] = None,
|
|
713
|
+
term_status: str = "PROPOSED",
|
|
714
|
+
body: Optional[dict | TemplateRequestBody] = None,
|
|
715
|
+
) -> str:
|
|
716
|
+
"""Create a new term from an existing term.
|
|
717
|
+
|
|
718
|
+
Async Version.
|
|
719
|
+
|
|
720
|
+
Parameters
|
|
721
|
+
----------
|
|
722
|
+
glossary_guid : str
|
|
723
|
+
Unique identifier for the glossary category to retrieve terms from.
|
|
724
|
+
glossary_term_guid: str
|
|
725
|
+
Unique identifier for the source glossary term.
|
|
726
|
+
new_display_name: str
|
|
727
|
+
The display name of the new term.
|
|
728
|
+
version_id: str
|
|
729
|
+
The version identifier of the new term.
|
|
730
|
+
term_status: str, optional, default = "PROPOSED"
|
|
731
|
+
The status of the term
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
Returns
|
|
735
|
+
-------
|
|
736
|
+
str:
|
|
737
|
+
The unique guid for the created term.
|
|
738
|
+
|
|
739
|
+
Raises
|
|
740
|
+
------
|
|
741
|
+
PyegeriaInvalidParameterException
|
|
742
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
743
|
+
PyegeriaAPIException
|
|
744
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
745
|
+
NotAuthorizedException
|
|
746
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
747
|
+
Notes
|
|
748
|
+
-----
|
|
749
|
+
|
|
750
|
+
"""
|
|
751
|
+
|
|
752
|
+
if isinstance(body, TemplateRequestBody):
|
|
753
|
+
validated_body = body
|
|
754
|
+
|
|
755
|
+
elif isinstance(body, dict):
|
|
756
|
+
validated_body = self._template_request_adapter.validate_python(body)
|
|
757
|
+
else:
|
|
758
|
+
qualified_name = self.__create_qualified_name__("Term", new_display_name, EGERIA_LOCAL_QUALIFIER)
|
|
759
|
+
body = {
|
|
760
|
+
"class" : "TemplateRequestBody",
|
|
761
|
+
"templateGUID": glossary_term_guid,
|
|
762
|
+
"parentGuid": glossary_guid,
|
|
763
|
+
"parentAtEnd1": True,
|
|
764
|
+
|
|
765
|
+
"replacementProperties": {
|
|
766
|
+
"class": "GlossaryTermProperties",
|
|
767
|
+
"qualifiedName": qualified_name,
|
|
768
|
+
"displayName": new_display_name,
|
|
769
|
+
"status": term_status,
|
|
770
|
+
"versionIdentifier": version_id
|
|
771
|
+
},
|
|
772
|
+
}
|
|
773
|
+
validated_body = self._template_request_adapter.validate_python(body)
|
|
774
|
+
validated_body._templateGUID = glossary_term_guid
|
|
775
|
+
v_body = body_slimmer(validated_body.model_dump(exclude_none=True))
|
|
776
|
+
logger.info(v_body)
|
|
777
|
+
|
|
778
|
+
url = (
|
|
779
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
780
|
+
f"terms/from-template/{glossary_term_guid}"
|
|
781
|
+
)
|
|
782
|
+
|
|
783
|
+
resp = await self._async_make_request("POST", url, v_body)
|
|
784
|
+
guid = resp.json().get("guid", NO_GUID_RETURNED)
|
|
785
|
+
logger.info(f"Create Term from template with GUID: {guid}")
|
|
786
|
+
return guid
|
|
787
|
+
|
|
788
|
+
def create_term_copy(
|
|
789
|
+
self,
|
|
790
|
+
glossary_guid: str,
|
|
791
|
+
glossary_term_guid: str,
|
|
792
|
+
new_display_name: str,
|
|
793
|
+
version_id: Optional[str] = None,
|
|
794
|
+
term_status: str = "PROPOSED",
|
|
795
|
+
body: Optional[dict | TemplateRequestBody] = None,
|
|
796
|
+
) -> str:
|
|
797
|
+
"""Create a new term from an existing term.
|
|
798
|
+
|
|
799
|
+
Parameters
|
|
800
|
+
----------
|
|
801
|
+
glossary_guid : str
|
|
802
|
+
Unique identifier for the glossary category to retrieve terms from.
|
|
803
|
+
glossary_term_guid: str
|
|
804
|
+
Unique identifier for the source glossary term.
|
|
805
|
+
new_display_name: str
|
|
806
|
+
The display name of the new term.
|
|
807
|
+
version_id: str
|
|
808
|
+
The version identifier of the new term.
|
|
809
|
+
term_status: str, optional, default = "PROPOSED"
|
|
810
|
+
The status of the term
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
Returns
|
|
814
|
+
-------
|
|
815
|
+
str:
|
|
816
|
+
The unique guid for the created term.
|
|
817
|
+
|
|
818
|
+
Raises
|
|
819
|
+
------
|
|
820
|
+
PyegeriaInvalidParameterException
|
|
821
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
822
|
+
PyegeriaAPIException
|
|
823
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
824
|
+
NotAuthorizedException
|
|
825
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
826
|
+
Notes
|
|
827
|
+
-----
|
|
828
|
+
|
|
829
|
+
"""
|
|
830
|
+
loop = asyncio.get_event_loop()
|
|
831
|
+
response = loop.run_until_complete(
|
|
832
|
+
self._async_create_term_copy(
|
|
833
|
+
glossary_guid,
|
|
834
|
+
glossary_term_guid,
|
|
835
|
+
new_display_name,
|
|
836
|
+
version_id,
|
|
837
|
+
term_status,
|
|
838
|
+
body,
|
|
839
|
+
)
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
return response
|
|
843
|
+
|
|
844
|
+
@dynamic_catch
|
|
845
|
+
async def _async_update_glossary_term(
|
|
846
|
+
self,
|
|
847
|
+
glossary_term_guid: str,
|
|
848
|
+
body: dict | UpdateElementRequestBody,
|
|
849
|
+
) -> None:
|
|
850
|
+
"""Update a term. Async version.
|
|
851
|
+
|
|
852
|
+
Parameters
|
|
853
|
+
----------
|
|
854
|
+
glossary_term_guid: str
|
|
855
|
+
Unique identifier for the source glossary term.
|
|
856
|
+
body: dict
|
|
857
|
+
Body containing information about the data field to add
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
Returns
|
|
861
|
+
-------
|
|
862
|
+
None
|
|
863
|
+
|
|
864
|
+
Raises
|
|
865
|
+
------
|
|
866
|
+
PyegeriaInvalidParameterException
|
|
867
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
868
|
+
PyegeriaAPIException
|
|
869
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
870
|
+
NotAuthorizedException
|
|
871
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
872
|
+
Notes
|
|
873
|
+
-----
|
|
874
|
+
|
|
875
|
+
"""
|
|
876
|
+
|
|
877
|
+
validate_guid(glossary_term_guid)
|
|
878
|
+
|
|
879
|
+
url = (
|
|
880
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/"
|
|
881
|
+
f"{glossary_term_guid}/"
|
|
882
|
+
f"update"
|
|
883
|
+
)
|
|
884
|
+
await self._async_update_element_body_request(url, ["GlossaryTermProperties"], body)
|
|
885
|
+
logger.info(f"Updated digital subscription {glossary_term_guid}")
|
|
886
|
+
@dynamic_catch
|
|
887
|
+
def update_glossary_term(
|
|
888
|
+
self,
|
|
889
|
+
glossary_term_guid: str,
|
|
890
|
+
body: dict | UpdateElementRequestBody,
|
|
891
|
+
|
|
892
|
+
) -> None:
|
|
893
|
+
"""Add the data field values classification to a glossary term
|
|
894
|
+
|
|
895
|
+
Async Version.
|
|
896
|
+
|
|
897
|
+
Parameters
|
|
898
|
+
----------
|
|
899
|
+
glossary_term_guid: str
|
|
900
|
+
Unique identifier for the source glossary term.
|
|
901
|
+
body: dict
|
|
902
|
+
Body containing information about the data field to add
|
|
903
|
+
is_merge_update: bool, optional, default = True
|
|
904
|
+
Whether the data field values should be merged with existing definition or replace it.
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
Returns
|
|
908
|
+
-------
|
|
909
|
+
None
|
|
910
|
+
|
|
911
|
+
Raises
|
|
912
|
+
------
|
|
913
|
+
PyegeriaInvalidParameterException
|
|
914
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
915
|
+
PyegeriaAPIException
|
|
916
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
917
|
+
NotAuthorizedException
|
|
918
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
919
|
+
Notes
|
|
920
|
+
-----
|
|
921
|
+
An example body is:
|
|
922
|
+
|
|
923
|
+
{
|
|
924
|
+
"class" : "ReferenceableRequestBody",
|
|
925
|
+
"elementProperties" :
|
|
926
|
+
{
|
|
927
|
+
"class" : "GlossaryTermProperties",
|
|
928
|
+
"description" : "This is the long description of the term. And this is some more text."
|
|
929
|
+
},
|
|
930
|
+
"updateDescription" : "Final updates based on in-house review comments."
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
"""
|
|
934
|
+
loop = asyncio.get_event_loop()
|
|
935
|
+
loop.run_until_complete(
|
|
936
|
+
self._async_update_glossary_term(
|
|
937
|
+
glossary_term_guid,
|
|
938
|
+
body,
|
|
939
|
+
)
|
|
940
|
+
)
|
|
941
|
+
|
|
942
|
+
@dynamic_catch
|
|
943
|
+
async def _async_update_glossary_term_status(
|
|
944
|
+
self,
|
|
945
|
+
glossary_term_guid: str,
|
|
946
|
+
term_status: str = "DRAFT",
|
|
947
|
+
body: Optional[dict | UpdateElementRequestBody] = None,
|
|
948
|
+
) -> None:
|
|
949
|
+
"""Update the status of a term. Async version.
|
|
950
|
+
|
|
951
|
+
Parameters
|
|
952
|
+
----------
|
|
953
|
+
glossary_term_guid: str
|
|
954
|
+
Unique identifier for the source glossary term.
|
|
955
|
+
term_status: str
|
|
956
|
+
new status of the term.
|
|
957
|
+
body: dict | UpdateElementRequestBody
|
|
958
|
+
Body containing information about the status change. Supersedes other parameters.
|
|
959
|
+
|
|
960
|
+
Returns
|
|
961
|
+
-------
|
|
962
|
+
None
|
|
963
|
+
|
|
964
|
+
Raises
|
|
965
|
+
------
|
|
966
|
+
PyegeriaException
|
|
967
|
+
|
|
968
|
+
"""
|
|
969
|
+
|
|
970
|
+
validate_guid(glossary_term_guid)
|
|
971
|
+
|
|
972
|
+
if body is None:
|
|
973
|
+
body = {
|
|
974
|
+
"class": "UpdateElementRequestBody",
|
|
975
|
+
"contentStatus": term_status,
|
|
976
|
+
"mergeUpdate": True,
|
|
977
|
+
}
|
|
978
|
+
await self._async_update_glossary_term( glossary_term_guid, body)
|
|
979
|
+
logger.info(f"Updated term status {glossary_term_guid}")
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
@dynamic_catch
|
|
983
|
+
def update_glossary_term_status(
|
|
984
|
+
self,
|
|
985
|
+
glossary_term_guid: str, term_status: str = "DRAFT",
|
|
986
|
+
body: Optional[dict | UpdateElementRequestBody] = None,
|
|
987
|
+
) -> None:
|
|
988
|
+
"""Add the data field values classification to a glossary term
|
|
989
|
+
|
|
990
|
+
Async Version.
|
|
991
|
+
|
|
992
|
+
Parameters
|
|
993
|
+
----------
|
|
994
|
+
glossary_term_guid: str
|
|
995
|
+
Unique identifier for the source glossary term.
|
|
996
|
+
term_status: str
|
|
997
|
+
new status of the term.
|
|
998
|
+
body: dict | UpdateStatusRequestBody
|
|
999
|
+
Body containing information about the status change. Supersedes other parameters.
|
|
1000
|
+
|
|
1001
|
+
Returns
|
|
1002
|
+
-------
|
|
1003
|
+
None
|
|
1004
|
+
|
|
1005
|
+
Raises
|
|
1006
|
+
------
|
|
1007
|
+
PyegeriaException
|
|
1008
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1009
|
+
PyegeriaAPIException
|
|
1010
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1011
|
+
NotAuthoclearizedException
|
|
1012
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1013
|
+
Notes
|
|
1014
|
+
-----
|
|
1015
|
+
An example body is:
|
|
1016
|
+
|
|
1017
|
+
{
|
|
1018
|
+
"class" : "UpdateStatusRequestBody",
|
|
1019
|
+
"newStatus" : "DRAFT"
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
"""
|
|
1023
|
+
loop = asyncio.get_event_loop()
|
|
1024
|
+
loop.run_until_complete(
|
|
1025
|
+
self._async_update_glossary_term_status(
|
|
1026
|
+
glossary_term_guid,
|
|
1027
|
+
body,
|
|
1028
|
+
)
|
|
1029
|
+
)
|
|
1030
|
+
|
|
1031
|
+
@dynamic_catch
|
|
1032
|
+
async def _async_delete_term(
|
|
1033
|
+
self,
|
|
1034
|
+
term_guid: str,
|
|
1035
|
+
cascade: bool = False,
|
|
1036
|
+
body: Optional[dict | DeleteElementRequestBody] = None
|
|
1037
|
+
) -> None:
|
|
1038
|
+
"""Delete the glossary terms associated with the specified glossary. Async version.
|
|
1039
|
+
|
|
1040
|
+
Parameters
|
|
1041
|
+
----------
|
|
1042
|
+
term_guid : str,
|
|
1043
|
+
The unique identifier for the term to delete.
|
|
1044
|
+
for_lineage: bool, opt, default = False
|
|
1045
|
+
Set true for lineage processing - generally false.
|
|
1046
|
+
for_duplicate_processing: bool, opt, default = False
|
|
1047
|
+
Set true if duplicate processing handled externally - generally set False.
|
|
1048
|
+
|
|
1049
|
+
Returns
|
|
1050
|
+
-------
|
|
1051
|
+
None
|
|
1052
|
+
|
|
1053
|
+
Raises
|
|
1054
|
+
------
|
|
1055
|
+
PyegeriaInvalidParameterException
|
|
1056
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1057
|
+
PyegeriaAPIException
|
|
1058
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1059
|
+
NotAuthorizedException
|
|
1060
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1061
|
+
Notes
|
|
1062
|
+
-----
|
|
1063
|
+
"""
|
|
1064
|
+
|
|
1065
|
+
validate_guid(term_guid)
|
|
1066
|
+
|
|
1067
|
+
url = (
|
|
1068
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1069
|
+
f"terms/{term_guid}/delete"
|
|
1070
|
+
)
|
|
1071
|
+
await self._async_delete_element_request(url, body, cascade)
|
|
1072
|
+
logger.info(f"Deleted collection {term_guid} with cascade {cascade}")
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
def delete_term(
|
|
1076
|
+
self,
|
|
1077
|
+
term_guid: str,
|
|
1078
|
+
cascade: bool = False,
|
|
1079
|
+
body: Optional[dict | DeleteElementRequestBody] = None
|
|
1080
|
+
) -> None:
|
|
1081
|
+
"""Delete the glossary terms associated with the specified glossary.
|
|
1082
|
+
|
|
1083
|
+
Parameters
|
|
1084
|
+
----------
|
|
1085
|
+
term_guid : str,
|
|
1086
|
+
The unique identifier for the term to delete.
|
|
1087
|
+
for_lineage: bool, opt, default = False
|
|
1088
|
+
Set true for lineage processing - generally false.
|
|
1089
|
+
for_duplicate_processing: bool, opt, default = False
|
|
1090
|
+
Set true if duplicate processing handled externally - generally set False.
|
|
1091
|
+
|
|
1092
|
+
Returns
|
|
1093
|
+
-------
|
|
1094
|
+
None
|
|
1095
|
+
|
|
1096
|
+
Raises
|
|
1097
|
+
------
|
|
1098
|
+
PyegeriaInvalidParameterException
|
|
1099
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1100
|
+
PyegeriaAPIException
|
|
1101
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1102
|
+
NotAuthorizedException
|
|
1103
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1104
|
+
Notes
|
|
1105
|
+
-----
|
|
1106
|
+
"""
|
|
1107
|
+
loop = asyncio.get_event_loop()
|
|
1108
|
+
loop.run_until_complete(
|
|
1109
|
+
self._async_delete_term(term_guid, cascade, body)
|
|
1110
|
+
)
|
|
1111
|
+
|
|
1112
|
+
async def _async_move_term(
|
|
1113
|
+
self,
|
|
1114
|
+
term_guid: str,
|
|
1115
|
+
glossary_guid: str,
|
|
1116
|
+
body: Optional[dict | DeleteRelationshipRequestBody] = None
|
|
1117
|
+
) -> None:
|
|
1118
|
+
"""Move the glossary terms to the specified glossary. Async version.
|
|
1119
|
+
|
|
1120
|
+
Parameters
|
|
1121
|
+
----------
|
|
1122
|
+
term_guid : str,
|
|
1123
|
+
The unique identifier for the term to delete.
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
Returns
|
|
1127
|
+
-------
|
|
1128
|
+
None
|
|
1129
|
+
|
|
1130
|
+
Raises
|
|
1131
|
+
------
|
|
1132
|
+
PyegeriaInvalidParameterException
|
|
1133
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1134
|
+
PyegeriaAPIException
|
|
1135
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1136
|
+
NotAuthorizedException
|
|
1137
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1138
|
+
Notes
|
|
1139
|
+
-----
|
|
1140
|
+
"""
|
|
1141
|
+
|
|
1142
|
+
validate_guid(term_guid)
|
|
1143
|
+
|
|
1144
|
+
url = (
|
|
1145
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1146
|
+
f"terms/{term_guid}/move-to/{glossary_guid}"
|
|
1147
|
+
)
|
|
1148
|
+
await self._async_delete_relationship_request(url, body)
|
|
1149
|
+
logger.info(f"Moved collection {term_guid} to glossary {glossary_guid}")
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
def move_term(
|
|
1153
|
+
self,
|
|
1154
|
+
term_guid: str,
|
|
1155
|
+
glossary_guid: str,
|
|
1156
|
+
body: Optional[dict | DeleteRelationshipRequestBody] = None
|
|
1157
|
+
) -> None:
|
|
1158
|
+
"""Move the glossary terms to the specified glossary.
|
|
1159
|
+
|
|
1160
|
+
Parameters
|
|
1161
|
+
----------
|
|
1162
|
+
term_guid : str,
|
|
1163
|
+
The unique identifier for the term to delete.
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
Returns
|
|
1167
|
+
-------
|
|
1168
|
+
None
|
|
1169
|
+
|
|
1170
|
+
Raises
|
|
1171
|
+
------
|
|
1172
|
+
PyegeriaInvalidParameterException
|
|
1173
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1174
|
+
PyegeriaAPIException
|
|
1175
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1176
|
+
NotAuthorizedException
|
|
1177
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1178
|
+
Notes
|
|
1179
|
+
-----
|
|
1180
|
+
"""
|
|
1181
|
+
loop = asyncio.get_event_loop()
|
|
1182
|
+
loop.run_until_complete(
|
|
1183
|
+
self._async_move_term(term_guid, glossary_guid, body)
|
|
1184
|
+
)
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
#
|
|
1189
|
+
# Categories are just Folders in collection manager
|
|
1190
|
+
#
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
#
|
|
1196
|
+
# From glossary browser
|
|
1197
|
+
#
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
async def _async_add_is_abstract_concepts(
|
|
1202
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1203
|
+
) -> None:
|
|
1204
|
+
"""Add a relationship between terms. Async Version.
|
|
1205
|
+
|
|
1206
|
+
Parameters
|
|
1207
|
+
----------
|
|
1208
|
+
term1_guid : str
|
|
1209
|
+
Unique identifier of the first glossary term in relationship.
|
|
1210
|
+
term2_guid : str
|
|
1211
|
+
Unique identifier of the second glossary term in relationship.
|
|
1212
|
+
relationship_type: str
|
|
1213
|
+
Type of relationship to add.
|
|
1214
|
+
body: dict, optional, default = None
|
|
1215
|
+
Further optional details for the relationship.
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
Returns
|
|
1219
|
+
-------
|
|
1220
|
+
None
|
|
1221
|
+
|
|
1222
|
+
Raises
|
|
1223
|
+
------
|
|
1224
|
+
PyegeriaInvalidParameterException
|
|
1225
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1226
|
+
PyegeriaAPIException
|
|
1227
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1228
|
+
NotAuthorizedException
|
|
1229
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1230
|
+
|
|
1231
|
+
Notes
|
|
1232
|
+
----
|
|
1233
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1234
|
+
|
|
1235
|
+
{
|
|
1236
|
+
"class" : "NewClassificationRequestBody",
|
|
1237
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1238
|
+
"properties" : {
|
|
1239
|
+
"class" : "GlossaryTermRelationship",
|
|
1240
|
+
|
|
1241
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1242
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1243
|
+
"extendedProperties" : {
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
"""
|
|
1248
|
+
|
|
1249
|
+
url = (
|
|
1250
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1251
|
+
f"terms/{term_guid}/is-abstract-concept"
|
|
1252
|
+
)
|
|
1253
|
+
if body is None:
|
|
1254
|
+
body = {
|
|
1255
|
+
"class": "NewClassificationRequestBody",
|
|
1256
|
+
"properties":
|
|
1257
|
+
{
|
|
1258
|
+
"class": "AbstractConceptProperties"
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
await self._async_new_classification_request(url, "AbstractConceptProperties", body)
|
|
1263
|
+
logger.info(f"Added AbstractConcept classification to {term_guid}")
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
def add_is_abstract_concept(
|
|
1267
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1268
|
+
) -> None:
|
|
1269
|
+
"""Add a relationship between terms.
|
|
1270
|
+
|
|
1271
|
+
Parameters
|
|
1272
|
+
----------
|
|
1273
|
+
term1_guid : str
|
|
1274
|
+
Unique identifier of the first glossary term in relationship.
|
|
1275
|
+
term2_guid : str
|
|
1276
|
+
Unique identifier of the second glossary term in relationship.
|
|
1277
|
+
relationship_type: str
|
|
1278
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1279
|
+
body: dict, optional, default = None
|
|
1280
|
+
Further optional details for the relationship.
|
|
1281
|
+
|
|
1282
|
+
Returns
|
|
1283
|
+
-------
|
|
1284
|
+
None
|
|
1285
|
+
|
|
1286
|
+
Raises
|
|
1287
|
+
------
|
|
1288
|
+
PyegeriaInvalidParameterException
|
|
1289
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1290
|
+
PyegeriaAPIException
|
|
1291
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1292
|
+
NotAuthorizedException
|
|
1293
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1294
|
+
|
|
1295
|
+
Notes
|
|
1296
|
+
----
|
|
1297
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1298
|
+
|
|
1299
|
+
{
|
|
1300
|
+
"class" : "NewRelationshipRequestBody",
|
|
1301
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1302
|
+
"properties" : {
|
|
1303
|
+
"class" : "GlossaryTermRelationship",
|
|
1304
|
+
"expression" : "",
|
|
1305
|
+
"confidence" : 0,
|
|
1306
|
+
"description" : "",
|
|
1307
|
+
"status" : "",
|
|
1308
|
+
"steward" : "",
|
|
1309
|
+
"source" : "",
|
|
1310
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1311
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1312
|
+
"extendedProperties" : {
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
"""
|
|
1317
|
+
loop = asyncio.get_event_loop()
|
|
1318
|
+
loop.run_until_complete(
|
|
1319
|
+
self._async_add_is_abstract_concepts(term_guid, body)
|
|
1320
|
+
)
|
|
1321
|
+
|
|
1322
|
+
async def _async_remove_is_abstract_concepts(
|
|
1323
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1324
|
+
) -> None:
|
|
1325
|
+
"""Add a relationship between terms. Async Version.
|
|
1326
|
+
|
|
1327
|
+
Parameters
|
|
1328
|
+
----------
|
|
1329
|
+
term1_guid : str
|
|
1330
|
+
Unique identifier of the first glossary term in relationship.
|
|
1331
|
+
term2_guid : str
|
|
1332
|
+
Unique identifier of the second glossary term in relationship.
|
|
1333
|
+
relationship_type: str
|
|
1334
|
+
Type of relationship to add.
|
|
1335
|
+
body: dict, optional, default = None
|
|
1336
|
+
Further optional details for the relationship.
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
Returns
|
|
1340
|
+
-------
|
|
1341
|
+
None
|
|
1342
|
+
|
|
1343
|
+
Raises
|
|
1344
|
+
------
|
|
1345
|
+
PyegeriaInvalidParameterException
|
|
1346
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1347
|
+
PyegeriaAPIException
|
|
1348
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1349
|
+
NotAuthorizedException
|
|
1350
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1351
|
+
|
|
1352
|
+
Notes
|
|
1353
|
+
----
|
|
1354
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1355
|
+
|
|
1356
|
+
{
|
|
1357
|
+
"class" : "NewClassificationRequestBody",
|
|
1358
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1359
|
+
"properties" : {
|
|
1360
|
+
"class" : "GlossaryTermRelationship",
|
|
1361
|
+
|
|
1362
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1363
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1364
|
+
"extendedProperties" : {
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
"""
|
|
1369
|
+
|
|
1370
|
+
url = (
|
|
1371
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1372
|
+
f"terms/{term_guid}/is-abstract-concept/remove"
|
|
1373
|
+
)
|
|
1374
|
+
await self._async_delete_classification_request(url, body)
|
|
1375
|
+
logger.info(f"Removed AbstractConcept classification to {term_guid}")
|
|
1376
|
+
|
|
1377
|
+
def remove_is_abstract_concept(
|
|
1378
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1379
|
+
) -> None:
|
|
1380
|
+
"""Add a relationship between terms.
|
|
1381
|
+
|
|
1382
|
+
Parameters
|
|
1383
|
+
----------
|
|
1384
|
+
term1_guid : str
|
|
1385
|
+
Unique identifier of the first glossary term in relationship.
|
|
1386
|
+
term2_guid : str
|
|
1387
|
+
Unique identifier of the second glossary term in relationship.
|
|
1388
|
+
relationship_type: str
|
|
1389
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1390
|
+
body: dict, optional, default = None
|
|
1391
|
+
Further optional details for the relationship.
|
|
1392
|
+
|
|
1393
|
+
Returns
|
|
1394
|
+
-------
|
|
1395
|
+
None
|
|
1396
|
+
|
|
1397
|
+
Raises
|
|
1398
|
+
------
|
|
1399
|
+
PyegeriaInvalidParameterException
|
|
1400
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1401
|
+
PyegeriaAPIException
|
|
1402
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1403
|
+
NotAuthorizedException
|
|
1404
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1405
|
+
|
|
1406
|
+
Notes
|
|
1407
|
+
----
|
|
1408
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1409
|
+
|
|
1410
|
+
{
|
|
1411
|
+
"class" : "NewRelationshipRequestBody",
|
|
1412
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1413
|
+
"properties" : {
|
|
1414
|
+
"class" : "GlossaryTermRelationship",
|
|
1415
|
+
"expression" : "",
|
|
1416
|
+
"confidence" : 0,
|
|
1417
|
+
"description" : "",
|
|
1418
|
+
"status" : "",
|
|
1419
|
+
"steward" : "",
|
|
1420
|
+
"source" : "",
|
|
1421
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1422
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1423
|
+
"extendedProperties" : {
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
"""
|
|
1428
|
+
loop = asyncio.get_event_loop()
|
|
1429
|
+
loop.run_until_complete(
|
|
1430
|
+
self._async_remove_is_abstract_concepts(term_guid, body)
|
|
1431
|
+
)
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
async def _async_add_is_context_definition(
|
|
1435
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1436
|
+
) -> None:
|
|
1437
|
+
"""Add a relationship between terms. Async Version.
|
|
1438
|
+
|
|
1439
|
+
Parameters
|
|
1440
|
+
----------
|
|
1441
|
+
term1_guid : str
|
|
1442
|
+
Unique identifier of the first glossary term in relationship.
|
|
1443
|
+
term2_guid : str
|
|
1444
|
+
Unique identifier of the second glossary term in relationship.
|
|
1445
|
+
relationship_type: str
|
|
1446
|
+
Type of relationship to add.
|
|
1447
|
+
body: dict, optional, default = None
|
|
1448
|
+
Further optional details for the relationship.
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
Returns
|
|
1452
|
+
-------
|
|
1453
|
+
None
|
|
1454
|
+
|
|
1455
|
+
Raises
|
|
1456
|
+
------
|
|
1457
|
+
PyegeriaInvalidParameterException
|
|
1458
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1459
|
+
PyegeriaAPIException
|
|
1460
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1461
|
+
NotAuthorizedException
|
|
1462
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1463
|
+
|
|
1464
|
+
Notes
|
|
1465
|
+
----
|
|
1466
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1467
|
+
|
|
1468
|
+
{
|
|
1469
|
+
"class" : "NewClassificationRequestBody",
|
|
1470
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1471
|
+
"properties" : {
|
|
1472
|
+
"class" : "GlossaryTermRelationship",
|
|
1473
|
+
|
|
1474
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1475
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1476
|
+
"extendedProperties" : {
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
"""
|
|
1481
|
+
|
|
1482
|
+
url = (
|
|
1483
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1484
|
+
f"terms/{term_guid}/is-context-definition"
|
|
1485
|
+
)
|
|
1486
|
+
if body is None:
|
|
1487
|
+
body = {
|
|
1488
|
+
"class": "NewClassificationRequestBody",
|
|
1489
|
+
"properties":
|
|
1490
|
+
{
|
|
1491
|
+
"class": "ContextDefinitionProperties"
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
await self._async_new_classification_request(url, "ContextDefinitionProperties", body)
|
|
1496
|
+
logger.info(f"Added AbstractConcept classification to {term_guid}")
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
def add_is_context_definition(
|
|
1501
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1502
|
+
) -> None:
|
|
1503
|
+
"""Add a relationship between terms.
|
|
1504
|
+
|
|
1505
|
+
Parameters
|
|
1506
|
+
----------
|
|
1507
|
+
term1_guid : str
|
|
1508
|
+
Unique identifier of the first glossary term in relationship.
|
|
1509
|
+
term2_guid : str
|
|
1510
|
+
Unique identifier of the second glossary term in relationship.
|
|
1511
|
+
relationship_type: str
|
|
1512
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1513
|
+
body: dict, optional, default = None
|
|
1514
|
+
Further optional details for the relationship.
|
|
1515
|
+
|
|
1516
|
+
Returns
|
|
1517
|
+
-------
|
|
1518
|
+
None
|
|
1519
|
+
|
|
1520
|
+
Raises
|
|
1521
|
+
------
|
|
1522
|
+
PyegeriaInvalidParameterException
|
|
1523
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1524
|
+
PyegeriaAPIException
|
|
1525
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1526
|
+
NotAuthorizedException
|
|
1527
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1528
|
+
|
|
1529
|
+
Notes
|
|
1530
|
+
----
|
|
1531
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1532
|
+
|
|
1533
|
+
{
|
|
1534
|
+
"class" : "NewRelationshipRequestBody",
|
|
1535
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1536
|
+
"properties" : {
|
|
1537
|
+
"class" : "GlossaryTermRelationship",
|
|
1538
|
+
"expression" : "",
|
|
1539
|
+
"confidence" : 0,
|
|
1540
|
+
"description" : "",
|
|
1541
|
+
"status" : "",
|
|
1542
|
+
"steward" : "",
|
|
1543
|
+
"source" : "",
|
|
1544
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1545
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1546
|
+
"extendedProperties" : {
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
"""
|
|
1551
|
+
loop = asyncio.get_event_loop()
|
|
1552
|
+
loop.run_until_complete(
|
|
1553
|
+
self._async_add_is_context_definition(term_guid, body)
|
|
1554
|
+
)
|
|
1555
|
+
|
|
1556
|
+
async def _async_remove_is_context_definition(
|
|
1557
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1558
|
+
) -> None:
|
|
1559
|
+
"""Add a relationship between terms. Async Version.
|
|
1560
|
+
|
|
1561
|
+
Parameters
|
|
1562
|
+
----------
|
|
1563
|
+
term1_guid : str
|
|
1564
|
+
Unique identifier of the first glossary term in relationship.
|
|
1565
|
+
term2_guid : str
|
|
1566
|
+
Unique identifier of the second glossary term in relationship.
|
|
1567
|
+
relationship_type: str
|
|
1568
|
+
Type of relationship to add.
|
|
1569
|
+
body: dict, optional, default = None
|
|
1570
|
+
Further optional details for the relationship.
|
|
1571
|
+
|
|
1572
|
+
|
|
1573
|
+
Returns
|
|
1574
|
+
-------
|
|
1575
|
+
None
|
|
1576
|
+
|
|
1577
|
+
Raises
|
|
1578
|
+
------
|
|
1579
|
+
PyegeriaInvalidParameterException
|
|
1580
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1581
|
+
PyegeriaAPIException
|
|
1582
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1583
|
+
NotAuthorizedException
|
|
1584
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1585
|
+
|
|
1586
|
+
Notes
|
|
1587
|
+
----
|
|
1588
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1589
|
+
|
|
1590
|
+
{
|
|
1591
|
+
"class" : "NewClassificationRequestBody",
|
|
1592
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1593
|
+
"properties" : {
|
|
1594
|
+
"class" : "GlossaryTermRelationship",
|
|
1595
|
+
|
|
1596
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1597
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1598
|
+
"extendedProperties" : {
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
"""
|
|
1603
|
+
|
|
1604
|
+
url = (
|
|
1605
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1606
|
+
f"terms/{term_guid}/is-context-definition/remove"
|
|
1607
|
+
)
|
|
1608
|
+
await self._async_delete_classification_request(url, body)
|
|
1609
|
+
logger.info(f"Removed ContextDefinition classification to {term_guid}")
|
|
1610
|
+
|
|
1611
|
+
def remove_is_context_definition(
|
|
1612
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1613
|
+
) -> None:
|
|
1614
|
+
"""Add a relationship between terms.
|
|
1615
|
+
|
|
1616
|
+
Parameters
|
|
1617
|
+
----------
|
|
1618
|
+
term1_guid : str
|
|
1619
|
+
Unique identifier of the first glossary term in relationship.
|
|
1620
|
+
term2_guid : str
|
|
1621
|
+
Unique identifier of the second glossary term in relationship.
|
|
1622
|
+
relationship_type: str
|
|
1623
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1624
|
+
body: dict, optional, default = None
|
|
1625
|
+
Further optional details for the relationship.
|
|
1626
|
+
|
|
1627
|
+
Returns
|
|
1628
|
+
-------
|
|
1629
|
+
None
|
|
1630
|
+
|
|
1631
|
+
Raises
|
|
1632
|
+
------
|
|
1633
|
+
PyegeriaInvalidParameterException
|
|
1634
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1635
|
+
PyegeriaAPIException
|
|
1636
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1637
|
+
NotAuthorizedException
|
|
1638
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1639
|
+
|
|
1640
|
+
Notes
|
|
1641
|
+
----
|
|
1642
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1643
|
+
|
|
1644
|
+
{
|
|
1645
|
+
"class" : "NewRelationshipRequestBody",
|
|
1646
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1647
|
+
"properties" : {
|
|
1648
|
+
"class" : "GlossaryTermRelationship",
|
|
1649
|
+
"expression" : "",
|
|
1650
|
+
"confidence" : 0,
|
|
1651
|
+
"description" : "",
|
|
1652
|
+
"status" : "",
|
|
1653
|
+
"steward" : "",
|
|
1654
|
+
"source" : "",
|
|
1655
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1656
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1657
|
+
"extendedProperties" : {
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
"""
|
|
1662
|
+
loop = asyncio.get_event_loop()
|
|
1663
|
+
loop.run_until_complete(
|
|
1664
|
+
self._async_remove_is_context_definition(term_guid, body)
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
async def _async_add_is_data_value(
|
|
1669
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1670
|
+
) -> None:
|
|
1671
|
+
"""Add a relationship between terms. Async Version.
|
|
1672
|
+
|
|
1673
|
+
Parameters
|
|
1674
|
+
----------
|
|
1675
|
+
term1_guid : str
|
|
1676
|
+
Unique identifier of the first glossary term in relationship.
|
|
1677
|
+
term2_guid : str
|
|
1678
|
+
Unique identifier of the second glossary term in relationship.
|
|
1679
|
+
relationship_type: str
|
|
1680
|
+
Type of relationship to add.
|
|
1681
|
+
body: dict, optional, default = None
|
|
1682
|
+
Further optional details for the relationship.
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
Returns
|
|
1686
|
+
-------
|
|
1687
|
+
None
|
|
1688
|
+
|
|
1689
|
+
Raises
|
|
1690
|
+
------
|
|
1691
|
+
PyegeriaInvalidParameterException
|
|
1692
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1693
|
+
PyegeriaAPIException
|
|
1694
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1695
|
+
NotAuthorizedException
|
|
1696
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1697
|
+
|
|
1698
|
+
Notes
|
|
1699
|
+
----
|
|
1700
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1701
|
+
|
|
1702
|
+
{
|
|
1703
|
+
"class" : "NewClassificationRequestBody",
|
|
1704
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1705
|
+
"properties" : {
|
|
1706
|
+
"class" : "GlossaryTermRelationship",
|
|
1707
|
+
|
|
1708
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1709
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1710
|
+
"extendedProperties" : {
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
"""
|
|
1715
|
+
|
|
1716
|
+
url = (
|
|
1717
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1718
|
+
f"terms/{term_guid}/is-data-value"
|
|
1719
|
+
)
|
|
1720
|
+
if body is None:
|
|
1721
|
+
body = {
|
|
1722
|
+
"class": "NewClassificationRequestBody",
|
|
1723
|
+
"properties":
|
|
1724
|
+
{
|
|
1725
|
+
"class": "DataValueProperties"
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
await self._async_new_classification_request(url, "DataValueProperties", body)
|
|
1730
|
+
logger.info(f"Added DataValue classification to {term_guid}")
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
def add_is_data_value(
|
|
1735
|
+
self, term_guid: str, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1736
|
+
) -> None:
|
|
1737
|
+
"""Add a relationship between terms.
|
|
1738
|
+
|
|
1739
|
+
Parameters
|
|
1740
|
+
----------
|
|
1741
|
+
term1_guid : str
|
|
1742
|
+
Unique identifier of the first glossary term in relationship.
|
|
1743
|
+
term2_guid : str
|
|
1744
|
+
Unique identifier of the second glossary term in relationship.
|
|
1745
|
+
relationship_type: str
|
|
1746
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1747
|
+
body: dict, optional, default = None
|
|
1748
|
+
Further optional details for the relationship.
|
|
1749
|
+
|
|
1750
|
+
Returns
|
|
1751
|
+
-------
|
|
1752
|
+
None
|
|
1753
|
+
|
|
1754
|
+
Raises
|
|
1755
|
+
------
|
|
1756
|
+
PyegeriaInvalidParameterException
|
|
1757
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1758
|
+
PyegeriaAPIException
|
|
1759
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1760
|
+
NotAuthorizedException
|
|
1761
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1762
|
+
|
|
1763
|
+
Notes
|
|
1764
|
+
----
|
|
1765
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1766
|
+
|
|
1767
|
+
{
|
|
1768
|
+
"class" : "NewRelationshipRequestBody",
|
|
1769
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1770
|
+
"properties" : {
|
|
1771
|
+
"class" : "GlossaryTermRelationship",
|
|
1772
|
+
"expression" : "",
|
|
1773
|
+
"confidence" : 0,
|
|
1774
|
+
"description" : "",
|
|
1775
|
+
"status" : "",
|
|
1776
|
+
"steward" : "",
|
|
1777
|
+
"source" : "",
|
|
1778
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1779
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1780
|
+
"extendedProperties" : {
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
"""
|
|
1785
|
+
loop = asyncio.get_event_loop()
|
|
1786
|
+
loop.run_until_complete(
|
|
1787
|
+
self._async_add_is_data_value(term_guid, body)
|
|
1788
|
+
)
|
|
1789
|
+
|
|
1790
|
+
async def _async_remove_is_data_value(
|
|
1791
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1792
|
+
) -> None:
|
|
1793
|
+
"""Add a relationship between terms. Async Version.
|
|
1794
|
+
|
|
1795
|
+
Parameters
|
|
1796
|
+
----------
|
|
1797
|
+
term1_guid : str
|
|
1798
|
+
Unique identifier of the first glossary term in relationship.
|
|
1799
|
+
term2_guid : str
|
|
1800
|
+
Unique identifier of the second glossary term in relationship.
|
|
1801
|
+
relationship_type: str
|
|
1802
|
+
Type of relationship to add.
|
|
1803
|
+
body: dict, optional, default = None
|
|
1804
|
+
Further optional details for the relationship.
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
Returns
|
|
1808
|
+
-------
|
|
1809
|
+
None
|
|
1810
|
+
|
|
1811
|
+
Raises
|
|
1812
|
+
------
|
|
1813
|
+
PyegeriaInvalidParameterException
|
|
1814
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1815
|
+
PyegeriaAPIException
|
|
1816
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1817
|
+
NotAuthorizedException
|
|
1818
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1819
|
+
|
|
1820
|
+
Notes
|
|
1821
|
+
----
|
|
1822
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1823
|
+
|
|
1824
|
+
{
|
|
1825
|
+
"class" : "NewClassificationRequestBody",
|
|
1826
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1827
|
+
"properties" : {
|
|
1828
|
+
"class" : "GlossaryTermRelationship",
|
|
1829
|
+
|
|
1830
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1831
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1832
|
+
"extendedProperties" : {
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
"""
|
|
1837
|
+
|
|
1838
|
+
url = (
|
|
1839
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1840
|
+
f"terms/{term_guid}/is-data-value/remove"
|
|
1841
|
+
)
|
|
1842
|
+
await self._async_delete_classification_request(url, body)
|
|
1843
|
+
logger.info(f"Removed DataValue classification to {term_guid}")
|
|
1844
|
+
|
|
1845
|
+
def remove_is_data_value(
|
|
1846
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
1847
|
+
) -> None:
|
|
1848
|
+
"""Add a relationship between terms.
|
|
1849
|
+
|
|
1850
|
+
Parameters
|
|
1851
|
+
----------
|
|
1852
|
+
term1_guid : str
|
|
1853
|
+
Unique identifier of the first glossary term in relationship.
|
|
1854
|
+
term2_guid : str
|
|
1855
|
+
Unique identifier of the second glossary term in relationship.
|
|
1856
|
+
relationship_type: str
|
|
1857
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1858
|
+
body: dict, optional, default = None
|
|
1859
|
+
Further optional details for the relationship.
|
|
1860
|
+
|
|
1861
|
+
Returns
|
|
1862
|
+
-------
|
|
1863
|
+
None
|
|
1864
|
+
|
|
1865
|
+
Raises
|
|
1866
|
+
------
|
|
1867
|
+
PyegeriaInvalidParameterException
|
|
1868
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1869
|
+
PyegeriaAPIException
|
|
1870
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1871
|
+
NotAuthorizedException
|
|
1872
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1873
|
+
|
|
1874
|
+
Notes
|
|
1875
|
+
----
|
|
1876
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1877
|
+
|
|
1878
|
+
{
|
|
1879
|
+
"class" : "NewRelationshipRequestBody",
|
|
1880
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1881
|
+
"properties" : {
|
|
1882
|
+
"class" : "GlossaryTermRelationship",
|
|
1883
|
+
"expression" : "",
|
|
1884
|
+
"confidence" : 0,
|
|
1885
|
+
"description" : "",
|
|
1886
|
+
"status" : "",
|
|
1887
|
+
"steward" : "",
|
|
1888
|
+
"source" : "",
|
|
1889
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1890
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1891
|
+
"extendedProperties" : {
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
"""
|
|
1896
|
+
loop = asyncio.get_event_loop()
|
|
1897
|
+
loop.run_until_complete(
|
|
1898
|
+
self._async_remove_is_data_value(term_guid, body)
|
|
1899
|
+
)
|
|
1900
|
+
|
|
1901
|
+
|
|
1902
|
+
async def _async_add_activity_description(
|
|
1903
|
+
self, term_guid: str, activity_type: int = None, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1904
|
+
) -> None:
|
|
1905
|
+
"""Add a relationship between terms. Async Version.
|
|
1906
|
+
|
|
1907
|
+
Parameters
|
|
1908
|
+
----------
|
|
1909
|
+
term1_guid : str
|
|
1910
|
+
Unique identifier of the first glossary term in relationship.
|
|
1911
|
+
term2_guid : str
|
|
1912
|
+
Unique identifier of the second glossary term in relationship.
|
|
1913
|
+
relationship_type: str
|
|
1914
|
+
Type of relationship to add.
|
|
1915
|
+
body: dict, optional, default = None
|
|
1916
|
+
Further optional details for the relationship.
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
Returns
|
|
1920
|
+
-------
|
|
1921
|
+
None
|
|
1922
|
+
|
|
1923
|
+
Raises
|
|
1924
|
+
------
|
|
1925
|
+
PyegeriaInvalidParameterException
|
|
1926
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1927
|
+
PyegeriaAPIException
|
|
1928
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1929
|
+
NotAuthorizedException
|
|
1930
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1931
|
+
|
|
1932
|
+
Notes
|
|
1933
|
+
----
|
|
1934
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
1935
|
+
|
|
1936
|
+
{
|
|
1937
|
+
"class" : "NewClassificationRequestBody",
|
|
1938
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
1939
|
+
"properties" : {
|
|
1940
|
+
"class" : "GlossaryTermRelationship",
|
|
1941
|
+
|
|
1942
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
1943
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
1944
|
+
"extendedProperties" : {
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
"""
|
|
1949
|
+
|
|
1950
|
+
if body is None:
|
|
1951
|
+
body = {
|
|
1952
|
+
"class": "NewClassificationRequestBody",
|
|
1953
|
+
"properties": {
|
|
1954
|
+
"class": "ActivityDescriptionProperties",
|
|
1955
|
+
"type": activity_type,
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
url = (
|
|
1960
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
1961
|
+
f"terms/{term_guid}/is-activity"
|
|
1962
|
+
)
|
|
1963
|
+
await self._async_new_classification_request(url, "ActivityDescriptionProperties", body)
|
|
1964
|
+
logger.info(f"Added DataValue classification to {term_guid}")
|
|
1965
|
+
|
|
1966
|
+
|
|
1967
|
+
|
|
1968
|
+
def add_activity_description(
|
|
1969
|
+
self, term_guid: str, activity_type: int = None, body: Optional[dict | NewClassificationRequestBody] = None,
|
|
1970
|
+
) -> None:
|
|
1971
|
+
"""Add a relationship between terms.
|
|
1972
|
+
|
|
1973
|
+
Parameters
|
|
1974
|
+
----------
|
|
1975
|
+
term1_guid : str
|
|
1976
|
+
Unique identifier of the first glossary term in relationship.
|
|
1977
|
+
term2_guid : str
|
|
1978
|
+
Unique identifier of the second glossary term in relationship.
|
|
1979
|
+
relationship_type: str
|
|
1980
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
1981
|
+
body: dict, optional, default = None
|
|
1982
|
+
Further optional details for the relationship.
|
|
1983
|
+
|
|
1984
|
+
Returns
|
|
1985
|
+
-------
|
|
1986
|
+
None
|
|
1987
|
+
|
|
1988
|
+
Raises
|
|
1989
|
+
------
|
|
1990
|
+
PyegeriaInvalidParameterException
|
|
1991
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
1992
|
+
PyegeriaAPIException
|
|
1993
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
1994
|
+
NotAuthorizedException
|
|
1995
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
1996
|
+
|
|
1997
|
+
Notes
|
|
1998
|
+
----
|
|
1999
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2000
|
+
|
|
2001
|
+
{
|
|
2002
|
+
"class" : "NewRelationshipRequestBody",
|
|
2003
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2004
|
+
"properties" : {
|
|
2005
|
+
"class" : "GlossaryTermRelationship",
|
|
2006
|
+
"expression" : "",
|
|
2007
|
+
"confidence" : 0,
|
|
2008
|
+
"description" : "",
|
|
2009
|
+
"status" : "",
|
|
2010
|
+
"steward" : "",
|
|
2011
|
+
"source" : "",
|
|
2012
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2013
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2014
|
+
"extendedProperties" : {
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
"""
|
|
2019
|
+
loop = asyncio.get_event_loop()
|
|
2020
|
+
loop.run_until_complete(
|
|
2021
|
+
self._async_add_activity_description(term_guid, activity_type, body)
|
|
2022
|
+
)
|
|
2023
|
+
|
|
2024
|
+
async def _async_remove_activity_description(
|
|
2025
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
2026
|
+
) -> None:
|
|
2027
|
+
"""Add a relationship between terms. Async Version.
|
|
2028
|
+
|
|
2029
|
+
Parameters
|
|
2030
|
+
----------
|
|
2031
|
+
term1_guid : str
|
|
2032
|
+
Unique identifier of the first glossary term in relationship.
|
|
2033
|
+
term2_guid : str
|
|
2034
|
+
Unique identifier of the second glossary term in relationship.
|
|
2035
|
+
relationship_type: str
|
|
2036
|
+
Type of relationship to add.
|
|
2037
|
+
body: dict, optional, default = None
|
|
2038
|
+
Further optional details for the relationship.
|
|
2039
|
+
|
|
2040
|
+
|
|
2041
|
+
Returns
|
|
2042
|
+
-------
|
|
2043
|
+
None
|
|
2044
|
+
|
|
2045
|
+
Raises
|
|
2046
|
+
------
|
|
2047
|
+
PyegeriaInvalidParameterException
|
|
2048
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2049
|
+
PyegeriaAPIException
|
|
2050
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2051
|
+
NotAuthorizedException
|
|
2052
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2053
|
+
|
|
2054
|
+
Notes
|
|
2055
|
+
----
|
|
2056
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2057
|
+
|
|
2058
|
+
{
|
|
2059
|
+
"class" : "NewClassificationRequestBody",
|
|
2060
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2061
|
+
"properties" : {
|
|
2062
|
+
"class" : "GlossaryTermRelationship",
|
|
2063
|
+
|
|
2064
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2065
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2066
|
+
"extendedProperties" : {
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
"""
|
|
2071
|
+
|
|
2072
|
+
url = (
|
|
2073
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
2074
|
+
f"terms/{term_guid}/is-activity/remove"
|
|
2075
|
+
)
|
|
2076
|
+
await self._async_delete_classification_request(url, body)
|
|
2077
|
+
logger.info(f"Removed ActivityDescription classification to {term_guid}")
|
|
2078
|
+
|
|
2079
|
+
def remove_activity_description(
|
|
2080
|
+
self, term_guid: str, body: Optional[dict | DeleteClassificationRequestBody] = None,
|
|
2081
|
+
) -> None:
|
|
2082
|
+
"""Add a relationship between terms.
|
|
2083
|
+
|
|
2084
|
+
Parameters
|
|
2085
|
+
----------
|
|
2086
|
+
term1_guid : str
|
|
2087
|
+
Unique identifier of the first glossary term in relationship.
|
|
2088
|
+
term2_guid : str
|
|
2089
|
+
Unique identifier of the second glossary term in relationship.
|
|
2090
|
+
relationship_type: str
|
|
2091
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
2092
|
+
body: dict, optional, default = None
|
|
2093
|
+
Further optional details for the relationship.
|
|
2094
|
+
|
|
2095
|
+
Returns
|
|
2096
|
+
-------
|
|
2097
|
+
None
|
|
2098
|
+
|
|
2099
|
+
Raises
|
|
2100
|
+
------
|
|
2101
|
+
PyegeriaInvalidParameterException
|
|
2102
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2103
|
+
PyegeriaAPIException
|
|
2104
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2105
|
+
NotAuthorizedException
|
|
2106
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2107
|
+
|
|
2108
|
+
Notes
|
|
2109
|
+
----
|
|
2110
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2111
|
+
|
|
2112
|
+
{
|
|
2113
|
+
"class" : "NewRelationshipRequestBody",
|
|
2114
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2115
|
+
"properties" : {
|
|
2116
|
+
"class" : "GlossaryTermRelationship",
|
|
2117
|
+
"expression" : "",
|
|
2118
|
+
"confidence" : 0,
|
|
2119
|
+
"description" : "",
|
|
2120
|
+
"status" : "",
|
|
2121
|
+
"steward" : "",
|
|
2122
|
+
"source" : "",
|
|
2123
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2124
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2125
|
+
"extendedProperties" : {
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
"""
|
|
2130
|
+
loop = asyncio.get_event_loop()
|
|
2131
|
+
loop.run_until_complete(
|
|
2132
|
+
self._async_remove_activity_description(term_guid, body)
|
|
2133
|
+
)
|
|
2134
|
+
|
|
2135
|
+
#
|
|
2136
|
+
# Term - Term Relationships
|
|
2137
|
+
#
|
|
2138
|
+
|
|
2139
|
+
async def _async_add_relationship_between_terms(
|
|
2140
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | NewRelationshipRequestBody] = None,
|
|
2141
|
+
) -> None:
|
|
2142
|
+
"""Add a relationship between terms. Async Version.
|
|
2143
|
+
|
|
2144
|
+
Parameters
|
|
2145
|
+
----------
|
|
2146
|
+
term1_guid : str
|
|
2147
|
+
Unique identifier of the first glossary term in relationship.
|
|
2148
|
+
term2_guid : str
|
|
2149
|
+
Unique identifier of the second glossary term in relationship.
|
|
2150
|
+
relationship_type: str
|
|
2151
|
+
Type of relationship to add.
|
|
2152
|
+
body: dict, optional, default = None
|
|
2153
|
+
Further optional details for the relationship.
|
|
2154
|
+
|
|
2155
|
+
|
|
2156
|
+
Returns
|
|
2157
|
+
-------
|
|
2158
|
+
None
|
|
2159
|
+
|
|
2160
|
+
Raises
|
|
2161
|
+
------
|
|
2162
|
+
PyegeriaInvalidParameterException
|
|
2163
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2164
|
+
PyegeriaAPIException
|
|
2165
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2166
|
+
NotAuthorizedException
|
|
2167
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2168
|
+
|
|
2169
|
+
Notes
|
|
2170
|
+
----
|
|
2171
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2172
|
+
|
|
2173
|
+
{
|
|
2174
|
+
"class" : "NewRelationshipRequestBody",
|
|
2175
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2176
|
+
"properties" : {
|
|
2177
|
+
"class" : "GlossaryTermRelationship",
|
|
2178
|
+
"expression" : "",
|
|
2179
|
+
"confidence" : 0,
|
|
2180
|
+
"description" : "",
|
|
2181
|
+
"status" : "",
|
|
2182
|
+
"steward" : "",
|
|
2183
|
+
"source" : "",
|
|
2184
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2185
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2186
|
+
"extendedProperties" : {
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
"""
|
|
2191
|
+
|
|
2192
|
+
validate_guid(term1_guid)
|
|
2193
|
+
validate_guid(term2_guid)
|
|
2194
|
+
|
|
2195
|
+
if body is None:
|
|
2196
|
+
body = {
|
|
2197
|
+
"class": "NewRelationshipRequestBody",
|
|
2198
|
+
"properties":
|
|
2199
|
+
{"class": "GlossaryTermRelationship" }
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
url = (
|
|
2205
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
2206
|
+
f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}"
|
|
2207
|
+
)
|
|
2208
|
+
await self._async_new_relationship_request(url, ["GlossaryTermRelationship"],body)
|
|
2209
|
+
logger.info(f"Added relationship between {term1_guid} and {term2_guid} of type {relationship_type}")
|
|
2210
|
+
|
|
2211
|
+
def add_relationship_between_terms(
|
|
2212
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | NewRelationshipRequestBody] = None,
|
|
2213
|
+
) -> None:
|
|
2214
|
+
"""Add a relationship between terms.
|
|
2215
|
+
|
|
2216
|
+
Parameters
|
|
2217
|
+
----------
|
|
2218
|
+
term1_guid : str
|
|
2219
|
+
Unique identifier of the first glossary term in relationship.
|
|
2220
|
+
term2_guid : str
|
|
2221
|
+
Unique identifier of the second glossary term in relationship.
|
|
2222
|
+
relationship_type: str
|
|
2223
|
+
Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
|
|
2224
|
+
body: dict, optional, default = None
|
|
2225
|
+
Further optional details for the relationship.
|
|
2226
|
+
|
|
2227
|
+
Returns
|
|
2228
|
+
-------
|
|
2229
|
+
None
|
|
2230
|
+
|
|
2231
|
+
Raises
|
|
2232
|
+
------
|
|
2233
|
+
PyegeriaInvalidParameterException
|
|
2234
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2235
|
+
PyegeriaAPIException
|
|
2236
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2237
|
+
NotAuthorizedException
|
|
2238
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2239
|
+
|
|
2240
|
+
Notes
|
|
2241
|
+
----
|
|
2242
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2243
|
+
|
|
2244
|
+
{
|
|
2245
|
+
"class" : "NewRelationshipRequestBody",
|
|
2246
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2247
|
+
"properties" : {
|
|
2248
|
+
"class" : "GlossaryTermRelationship",
|
|
2249
|
+
"expression" : "",
|
|
2250
|
+
"confidence" : 0,
|
|
2251
|
+
"description" : "",
|
|
2252
|
+
"status" : "",
|
|
2253
|
+
"steward" : "",
|
|
2254
|
+
"source" : "",
|
|
2255
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2256
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2257
|
+
"extendedProperties" : {
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
"""
|
|
2262
|
+
loop = asyncio.get_event_loop()
|
|
2263
|
+
loop.run_until_complete(
|
|
2264
|
+
self._async_add_relationship_between_terms(term1_guid, term2_guid, relationship_type,
|
|
2265
|
+
body)
|
|
2266
|
+
)
|
|
2267
|
+
|
|
2268
|
+
async def _async_update_relationship_between_terms(
|
|
2269
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | UpdateRelationshipRequestBody] = None
|
|
2270
|
+
) -> None:
|
|
2271
|
+
|
|
2272
|
+
"""Update a relationship between terms. Async Version.
|
|
2273
|
+
|
|
2274
|
+
Parameters
|
|
2275
|
+
----------
|
|
2276
|
+
term1_guid : str
|
|
2277
|
+
Unique identifier of the first glossary term in relationship.
|
|
2278
|
+
term2_guid : str
|
|
2279
|
+
Unique identifier of the second glossary term in relationship.
|
|
2280
|
+
relationship_type: str
|
|
2281
|
+
Type of relationship to update.
|
|
2282
|
+
body: dict, optional, default = None
|
|
2283
|
+
Further optional details for the relationship.
|
|
2284
|
+
|
|
2285
|
+
Returns
|
|
2286
|
+
-------
|
|
2287
|
+
None
|
|
2288
|
+
|
|
2289
|
+
Raises
|
|
2290
|
+
------
|
|
2291
|
+
PyegeriaInvalidParameterException
|
|
2292
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2293
|
+
PyegeriaAPIException
|
|
2294
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2295
|
+
NotAuthorizedException
|
|
2296
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2297
|
+
|
|
2298
|
+
Notes
|
|
2299
|
+
----
|
|
2300
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2301
|
+
|
|
2302
|
+
{
|
|
2303
|
+
"class" : "UpdateRelationshipRequestBody",
|
|
2304
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2305
|
+
"properties" : {
|
|
2306
|
+
"class" : "GlossaryTermRelationship",
|
|
2307
|
+
"expression" : "",
|
|
2308
|
+
"confidence" : 0,
|
|
2309
|
+
"description" : "",
|
|
2310
|
+
"status" : "",
|
|
2311
|
+
"steward" : "",
|
|
2312
|
+
"source" : "",
|
|
2313
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2314
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2315
|
+
"extendedProperties" : {
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
"""
|
|
2320
|
+
|
|
2321
|
+
validate_guid(term1_guid)
|
|
2322
|
+
validate_guid(term2_guid)
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
|
|
2326
|
+
url = (
|
|
2327
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
2328
|
+
f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/update")
|
|
2329
|
+
|
|
2330
|
+
await self._async_update_relationship_request(url, "GlossaryTermRelationship", body)
|
|
2331
|
+
logger.info(f"Updated relationship between {term1_guid} and {term2_guid} of type {relationship_type}")
|
|
2332
|
+
|
|
2333
|
+
def update_relationship_between_terms(
|
|
2334
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | UpdateRelationshipRequestBody] = None
|
|
2335
|
+
) -> None:
|
|
2336
|
+
"""Update a relationship between terms.
|
|
2337
|
+
|
|
2338
|
+
Parameters
|
|
2339
|
+
----------
|
|
2340
|
+
term1_guid : str
|
|
2341
|
+
Unique identifier of the first glossary term in relationship.
|
|
2342
|
+
term2_guid : str
|
|
2343
|
+
Unique identifier of the second glossary term in relationship.
|
|
2344
|
+
relationship_type: str
|
|
2345
|
+
Type of relationship to update. A list of relationship types can be found using
|
|
2346
|
+
get_term_relationship_types().
|
|
2347
|
+
body: dict
|
|
2348
|
+
Details of the relationship to update.
|
|
2349
|
+
|
|
2350
|
+
Returns
|
|
2351
|
+
-------
|
|
2352
|
+
None
|
|
2353
|
+
|
|
2354
|
+
Raises
|
|
2355
|
+
------
|
|
2356
|
+
PyegeriaInvalidParameterException
|
|
2357
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2358
|
+
PyegeriaAPIException
|
|
2359
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2360
|
+
NotAuthorizedException
|
|
2361
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2362
|
+
|
|
2363
|
+
Notes
|
|
2364
|
+
----
|
|
2365
|
+
Body is currently required but can be empty except for class. Basic structure is:
|
|
2366
|
+
|
|
2367
|
+
{
|
|
2368
|
+
"class" : "UpdateRelationshipRequestBody",
|
|
2369
|
+
"effectiveTime" : {{@isoTimestamp}},
|
|
2370
|
+
"properties" : {
|
|
2371
|
+
"class" : "GlossaryTermRelationship",
|
|
2372
|
+
"expression" : "",
|
|
2373
|
+
"confidence" : 0,
|
|
2374
|
+
"description" : "",
|
|
2375
|
+
"status" : "",
|
|
2376
|
+
"steward" : "",
|
|
2377
|
+
"source" : "",
|
|
2378
|
+
"effectiveFrom" : "{{@isoTimestamp}}",
|
|
2379
|
+
"effectiveTo" : "{{@isoTimestamp}}",
|
|
2380
|
+
"extendedProperties" : {
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
"""
|
|
2385
|
+
loop = asyncio.get_event_loop()
|
|
2386
|
+
loop.run_until_complete(
|
|
2387
|
+
self._async_update_relationship_between_terms(term1_guid, term2_guid, relationship_type,
|
|
2388
|
+
body)
|
|
2389
|
+
)
|
|
2390
|
+
|
|
2391
|
+
async def _async_remove_relationship_between_terms(
|
|
2392
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | DeleteRelationshipRequestBody] = None,
|
|
2393
|
+
) -> None:
|
|
2394
|
+
"""Remove a relationship between terms. Async Version.
|
|
2395
|
+
|
|
2396
|
+
Parameters
|
|
2397
|
+
----------
|
|
2398
|
+
term1_guid : str
|
|
2399
|
+
Unique identifier of the first glossary term in relationship.
|
|
2400
|
+
term2_guid : str
|
|
2401
|
+
Unique identifier of the second glossary term in relationship.
|
|
2402
|
+
relationship_type: str
|
|
2403
|
+
Type of relationship to add.
|
|
2404
|
+
effective_time: str, optional, default = None
|
|
2405
|
+
Effective time to remove the relationship.
|
|
2406
|
+
for_lineage: bool, default is set by server
|
|
2407
|
+
- determines if elements classified as Memento should be returned - normally false
|
|
2408
|
+
for_duplicate_processing: bool, default is set by server
|
|
2409
|
+
- Normally false. Set true when the caller is part of a deduplication function
|
|
2410
|
+
|
|
2411
|
+
Returns
|
|
2412
|
+
-------
|
|
2413
|
+
None
|
|
2414
|
+
|
|
2415
|
+
Raises
|
|
2416
|
+
------
|
|
2417
|
+
PyegeriaInvalidParameterException
|
|
2418
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2419
|
+
PyegeriaAPIException
|
|
2420
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2421
|
+
NotAuthorizedException
|
|
2422
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2423
|
+
|
|
2424
|
+
|
|
2425
|
+
"""
|
|
2426
|
+
|
|
2427
|
+
validate_guid(term1_guid)
|
|
2428
|
+
validate_guid(term2_guid)
|
|
2429
|
+
|
|
2430
|
+
|
|
2431
|
+
url = (
|
|
2432
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
2433
|
+
f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/remove"
|
|
2434
|
+
)
|
|
2435
|
+
|
|
2436
|
+
await self._async_delete_relationship_request(url, body)
|
|
2437
|
+
|
|
2438
|
+
def remove_relationship_between_terms(
|
|
2439
|
+
self, term1_guid: str, term2_guid: str, relationship_type: str, body: Optional[dict | DeleteRelationshipRequestBody] = None) -> None:
|
|
2440
|
+
|
|
2441
|
+
"""Remove a relationship between terms.
|
|
2442
|
+
|
|
2443
|
+
Parameters
|
|
2444
|
+
----------
|
|
2445
|
+
term1_guid : str
|
|
2446
|
+
Unique identifier of the first glossary term in relationship.
|
|
2447
|
+
term2_guid : str
|
|
2448
|
+
Unique identifier of the second glossary term in relationship.
|
|
2449
|
+
relationship_type: str
|
|
2450
|
+
Type of relationship to remove. A list of relationship types can be found using
|
|
2451
|
+
get_term_relationship_types().
|
|
2452
|
+
|
|
2453
|
+
|
|
2454
|
+
Returns
|
|
2455
|
+
-------
|
|
2456
|
+
None
|
|
2457
|
+
|
|
2458
|
+
Raises
|
|
2459
|
+
------
|
|
2460
|
+
PyegeriaInvalidParameterException
|
|
2461
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
|
|
2462
|
+
PyegeriaAPIException
|
|
2463
|
+
Raised by the server when an issue arises in processing a valid request.
|
|
2464
|
+
NotAuthorizedException
|
|
2465
|
+
The principle specified by the user_id does not have authorization for the requested action.
|
|
2466
|
+
|
|
2467
|
+
"""
|
|
2468
|
+
loop = asyncio.get_event_loop()
|
|
2469
|
+
loop.run_until_complete(
|
|
2470
|
+
self._async_remove_relationship_between_terms(term1_guid, term2_guid, relationship_type,
|
|
2471
|
+
body)
|
|
2472
|
+
)
|
|
2473
|
+
|
|
2474
|
+
#
|
|
2475
|
+
# Integrated Glossary Browser methods
|
|
2476
|
+
#
|
|
2477
|
+
|
|
2478
|
+
def _extract_glossary_properties(self, element: dict, columns_struct: dict) -> dict:
|
|
2479
|
+
"""Extract glossary columns for rendering.
|
|
2480
|
+
|
|
2481
|
+
This extractor uses `populate_common_columns` for standard fields (properties, header, relationships,
|
|
2482
|
+
subject area, mermaid). It then overlays glossary-specific values such as:
|
|
2483
|
+
- categories_names: comma/newline separated Display Names of categories in the glossary
|
|
2484
|
+
- categories_qualified_names: comma/newline separated Qualified Names of categories in the glossary
|
|
2485
|
+
|
|
2486
|
+
Parameters
|
|
2487
|
+
----------
|
|
2488
|
+
element : dict
|
|
2489
|
+
Raw element as returned by the OMVS.
|
|
2490
|
+
columns_struct : dict
|
|
2491
|
+
The selected output format structure (from _output_formats), whose columns' `value` fields will be filled.
|
|
2492
|
+
|
|
2493
|
+
Returns
|
|
2494
|
+
-------
|
|
2495
|
+
dict
|
|
2496
|
+
The same columns_struct with values populated. Non-empty values are not overwritten.
|
|
2497
|
+
"""
|
|
2498
|
+
# Common population first
|
|
2499
|
+
col_data = populate_common_columns(element, columns_struct)
|
|
2500
|
+
# Overlay glossary-specific extras: categories lists
|
|
2501
|
+
header_props = _extract_referenceable_properties(element)
|
|
2502
|
+
guid = header_props.get('GUID')
|
|
2503
|
+
extra: dict = {}
|
|
2504
|
+
if guid:
|
|
2505
|
+
try:
|
|
2506
|
+
categories = self.get_categories_for_glossary(guid)
|
|
2507
|
+
except Exception:
|
|
2508
|
+
categories = None
|
|
2509
|
+
if isinstance(categories, list):
|
|
2510
|
+
cat_display_list = []
|
|
2511
|
+
cat_qn_list = []
|
|
2512
|
+
for category in categories:
|
|
2513
|
+
gcp = category.get('glossaryCategoryProperties', {})
|
|
2514
|
+
dn = (gcp.get('displayName') or '')
|
|
2515
|
+
qn = (gcp.get('qualifiedName') or '')
|
|
2516
|
+
if dn:
|
|
2517
|
+
cat_display_list.append(dn)
|
|
2518
|
+
if qn:
|
|
2519
|
+
cat_qn_list.append(qn)
|
|
2520
|
+
if cat_display_list:
|
|
2521
|
+
extra['categories_names'] = ", \n".join(cat_display_list)
|
|
2522
|
+
if cat_qn_list:
|
|
2523
|
+
extra['categories_qualified_names'] = ", \n".join(cat_qn_list)
|
|
2524
|
+
return overlay_additional_values(col_data, extra)
|
|
2525
|
+
|
|
2526
|
+
def _extract_term_properties(self, element: dict, columns_struct: dict) -> dict:
|
|
2527
|
+
"""Extract glossary term columns for rendering.
|
|
2528
|
+
|
|
2529
|
+
Populates standard columns via `populate_common_columns`, and if requested by the
|
|
2530
|
+
selected columns, derives a classifications string (from `elementHeader.collectionCategories`)
|
|
2531
|
+
into the `classifications` column.
|
|
2532
|
+
|
|
2533
|
+
Parameters
|
|
2534
|
+
----------
|
|
2535
|
+
element : dict
|
|
2536
|
+
Raw term element returned by the OMVS.
|
|
2537
|
+
columns_struct : dict
|
|
2538
|
+
The chosen format-set structure whose column `value`s will be set.
|
|
2539
|
+
|
|
2540
|
+
Returns
|
|
2541
|
+
-------
|
|
2542
|
+
dict
|
|
2543
|
+
The same `columns_struct` with values populated.
|
|
2544
|
+
"""
|
|
2545
|
+
# Use centralized population
|
|
2546
|
+
col_data = populate_common_columns(element, columns_struct)
|
|
2547
|
+
# Term-specific classifications (collectionCategories) to 'classifications' column
|
|
2548
|
+
columns_list = col_data.get('formats', {}).get('attributes', [])
|
|
2549
|
+
try:
|
|
2550
|
+
classification_names = ""
|
|
2551
|
+
classifications = element.get('elementHeader', {}).get("collectionCategories", [])
|
|
2552
|
+
for classification in classifications:
|
|
2553
|
+
nm = classification.get('classificationName')
|
|
2554
|
+
if nm:
|
|
2555
|
+
classification_names += f"{nm}, "
|
|
2556
|
+
if classification_names:
|
|
2557
|
+
for column in columns_list:
|
|
2558
|
+
if column.get('key') == 'classifications' and column.get('value') in (None, ""):
|
|
2559
|
+
column['value'] = classification_names[:-2]
|
|
2560
|
+
break
|
|
2561
|
+
except Exception:
|
|
2562
|
+
pass
|
|
2563
|
+
return col_data
|
|
2564
|
+
|
|
2565
|
+
def _get_term_additional_properties(self, element: dict, term_guid: str, output_format: str = None) -> dict:
|
|
2566
|
+
additional: dict = {}
|
|
2567
|
+
try:
|
|
2568
|
+
classifications = element.get('elementHeader', {}).get('otherClassifications', [])
|
|
2569
|
+
glossary_name = ''
|
|
2570
|
+
if classifications:
|
|
2571
|
+
cls_props = classifications[0].get('classificationProperties', {}) or {}
|
|
2572
|
+
g_guid = cls_props.get('anchorScopeGUID')
|
|
2573
|
+
if g_guid and hasattr(self, 'get_glossary_by_guid'):
|
|
2574
|
+
try:
|
|
2575
|
+
gl = self.get_glossary_by_guid(g_guid)
|
|
2576
|
+
if isinstance(gl, dict):
|
|
2577
|
+
if output_format == 'REPORT':
|
|
2578
|
+
glossary_name = gl.get('glossaryProperties', {}).get('displayName', '')
|
|
2579
|
+
else:
|
|
2580
|
+
glossary_name = gl.get('glossaryProperties', {}).get('qualifiedName', '')
|
|
2581
|
+
except Exception:
|
|
2582
|
+
pass
|
|
2583
|
+
if glossary_name:
|
|
2584
|
+
additional['in_glossary'] = glossary_name
|
|
2585
|
+
except Exception:
|
|
2586
|
+
pass
|
|
2587
|
+
try:
|
|
2588
|
+
if hasattr(self, 'get_categories_for_term') and term_guid:
|
|
2589
|
+
cats = self.get_categories_for_term(term_guid)
|
|
2590
|
+
names = []
|
|
2591
|
+
if isinstance(cats, list):
|
|
2592
|
+
for c in cats:
|
|
2593
|
+
gcp = c.get('glossaryCategoryProperties', {})
|
|
2594
|
+
val = gcp.get('displayName') if output_format in ['REPORT', 'LIST'] else gcp.get('qualifiedName')
|
|
2595
|
+
if val:
|
|
2596
|
+
names.append(val)
|
|
2597
|
+
if names:
|
|
2598
|
+
additional['categories'] = ", \n".join(names)
|
|
2599
|
+
except Exception:
|
|
2600
|
+
pass
|
|
2601
|
+
return additional
|
|
2602
|
+
|
|
2603
|
+
def _generate_glossary_output(self, elements: dict | list[dict], search_string: str,
|
|
2604
|
+
element_type_name: str | None,
|
|
2605
|
+
output_format: str = 'DICT',
|
|
2606
|
+
report_spec: dict | str = None) -> str | list[dict]:
|
|
2607
|
+
entity_type = 'Glossary'
|
|
2608
|
+
output_formats = resolve_output_formats(entity_type, output_format, report_spec)
|
|
2609
|
+
return generate_output(
|
|
2610
|
+
elements=elements,
|
|
2611
|
+
search_string=search_string,
|
|
2612
|
+
entity_type=entity_type,
|
|
2613
|
+
output_format=output_format,
|
|
2614
|
+
extract_properties_func=self._extract_glossary_properties,
|
|
2615
|
+
get_additional_props_func=None,
|
|
2616
|
+
columns_struct=output_formats,
|
|
2617
|
+
)
|
|
2618
|
+
|
|
2619
|
+
def _generate_term_output(self, elements: dict | list[dict], search_string: str,
|
|
2620
|
+
element_type_name: str | None,
|
|
2621
|
+
output_format: str = 'DICT',
|
|
2622
|
+
report_spec: dict | str = None) -> str | list[dict]:
|
|
2623
|
+
entity_type = 'GlossaryTerm'
|
|
2624
|
+
output_formats = resolve_output_formats(entity_type, output_format, report_spec)
|
|
2625
|
+
return generate_output(
|
|
2626
|
+
elements=elements,
|
|
2627
|
+
search_string=search_string,
|
|
2628
|
+
entity_type=entity_type,
|
|
2629
|
+
output_format=output_format,
|
|
2630
|
+
extract_properties_func=self._extract_term_properties,
|
|
2631
|
+
get_additional_props_func=self._get_term_additional_properties,
|
|
2632
|
+
columns_struct=output_formats,
|
|
2633
|
+
)
|
|
2634
|
+
|
|
2635
|
+
async def _async_get_glossary_term_statuses(self) -> [str]:
|
|
2636
|
+
url = (f"{self.platform_url}/servers/{self.view_server}"
|
|
2637
|
+
f"/api/open-metadata/glossary-manager/glossaries/terms/status-list")
|
|
2638
|
+
response = await self._async_make_request("GET", url)
|
|
2639
|
+
return response.json().get("statuses", [])
|
|
2640
|
+
|
|
2641
|
+
def get_glossary_term_statuses(self) -> [str]:
|
|
2642
|
+
loop = asyncio.get_event_loop()
|
|
2643
|
+
response = loop.run_until_complete(self._async_get_glossary_term_statuses())
|
|
2644
|
+
return response
|
|
2645
|
+
|
|
2646
|
+
async def _async_get_glossary_term_rel_statuses(self) -> [str]:
|
|
2647
|
+
url = (f"{self.platform_url}/servers/{self.view_server}"
|
|
2648
|
+
f"/api/open-metadata/glossary-manager/glossaries/terms/relationships/status-list")
|
|
2649
|
+
response = await self._async_make_request("GET", url)
|
|
2650
|
+
return response.json().get("statuses", [])
|
|
2651
|
+
|
|
2652
|
+
def get_glossary_term_rel_statuses(self) -> [str]:
|
|
2653
|
+
loop = asyncio.get_event_loop()
|
|
2654
|
+
response = loop.run_until_complete(self._async_get_glossary_term_rel_statuses())
|
|
2655
|
+
return response
|
|
2656
|
+
|
|
2657
|
+
async def _async_get_glossary_term_activity_types(self) -> [str]:
|
|
2658
|
+
url = (f"{self.platform_url}/servers/{self.view_server}"
|
|
2659
|
+
f"/api/open-metadata/glossary-manager/glossaries/terms/activity-types")
|
|
2660
|
+
response = await self._async_make_request("GET", url)
|
|
2661
|
+
return response.json().get("types", [])
|
|
2662
|
+
|
|
2663
|
+
def get_glossary_term_activity_types(self) -> [str]:
|
|
2664
|
+
loop = asyncio.get_event_loop()
|
|
2665
|
+
response = loop.run_until_complete(self._async_get_glossary_term_statuses())
|
|
2666
|
+
return response
|
|
2667
|
+
|
|
2668
|
+
async def _async_get_term_relationship_types(self) -> [str]:
|
|
2669
|
+
url = (f"{self.platform_url}/servers/{self.view_server}"
|
|
2670
|
+
f"/api/open-metadata/glossary-manager/glossaries/terms/relationships/type-names")
|
|
2671
|
+
response = await self._async_make_request("GET", url)
|
|
2672
|
+
return response.json().get("names", [])
|
|
2673
|
+
|
|
2674
|
+
def get_term_relationship_types(self) -> [str]:
|
|
2675
|
+
loop = asyncio.get_event_loop()
|
|
2676
|
+
response = loop.run_until_complete(self._async_get_term_relationship_types())
|
|
2677
|
+
return response
|
|
2678
|
+
|
|
2679
|
+
@dynamic_catch
|
|
2680
|
+
async def _async_find_glossaries(self, search_string: str = "*",
|
|
2681
|
+
starts_with: bool = True, ends_with: bool = False,
|
|
2682
|
+
ignore_case: bool = False,
|
|
2683
|
+
anchor_domain: Optional[str] = None,
|
|
2684
|
+
metadata_element_type: str = "Glossary",
|
|
2685
|
+
metadata_element_subtypes: Optional[list[str]] = None,
|
|
2686
|
+
skip_relationships: Optional[list[str]] = None,
|
|
2687
|
+
include_only_relationships: Optional[list[str]] = None,
|
|
2688
|
+
skip_classified_elements: Optional[list[str]] = None,
|
|
2689
|
+
include_only_classified_elements: Optional[list[str]] = None,
|
|
2690
|
+
graph_query_depth: int = 3,
|
|
2691
|
+
governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
|
|
2692
|
+
effective_time: Optional[str] = None, relationship_page_size: int = 0,
|
|
2693
|
+
limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
|
|
2694
|
+
sequencing_property: Optional[str] = None,
|
|
2695
|
+
output_format: str = "JSON",
|
|
2696
|
+
report_spec: str | dict = None,
|
|
2697
|
+
start_from: int = 0, page_size: int = 100,
|
|
2698
|
+
property_names: Optional[list[str]] = None,
|
|
2699
|
+
body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
|
|
2700
|
+
""" Retrieve the list of glossary metadata elements that contain the search string. Async Version.
|
|
2701
|
+
|
|
2702
|
+
Parameters
|
|
2703
|
+
----------
|
|
2704
|
+
search_string: str
|
|
2705
|
+
Search string to match against - None or '*' indicate match against all glossaries.
|
|
2706
|
+
starts_with : bool, [default=True], optional
|
|
2707
|
+
Starts with the supplied string.
|
|
2708
|
+
ends_with : bool, [default=False], optional
|
|
2709
|
+
Ends with the supplied string
|
|
2710
|
+
ignore_case : bool, [default=False], optional
|
|
2711
|
+
Ignore case when searching
|
|
2712
|
+
anchor_domain: str, optional
|
|
2713
|
+
The anchor domain to search in.
|
|
2714
|
+
metadata_element_type: str, optional, [default="Glossary"]
|
|
2715
|
+
The type of metadata element to search for.
|
|
2716
|
+
metadata_element_subtypes: list[str], optional
|
|
2717
|
+
The subtypes of metadata element to search for.
|
|
2718
|
+
skip_relationships: list[str], optional
|
|
2719
|
+
The types of relationships to skip.
|
|
2720
|
+
include_only_relationships: list[str], optional
|
|
2721
|
+
The types of relationships to include.
|
|
2722
|
+
skip_classified_elements: list[str], optional
|
|
2723
|
+
The types of classified elements to skip.
|
|
2724
|
+
include_only_classified_elements: list[str], optional
|
|
2725
|
+
The types of classified elements to include.
|
|
2726
|
+
graph_query_depth: int, [default=3], optional
|
|
2727
|
+
The depth of the graph query.
|
|
2728
|
+
governance_zone_filter: list[str], optional
|
|
2729
|
+
The governance zones to search in.
|
|
2730
|
+
as_of_time: str, optional
|
|
2731
|
+
The time to search as of.
|
|
2732
|
+
effective_time: str, optional
|
|
2733
|
+
The effective time to search at.
|
|
2734
|
+
relationship_page_size: int, [default=0], optional
|
|
2735
|
+
The page size for relationships.
|
|
2736
|
+
limit_results_by_status: list[str], optional
|
|
2737
|
+
The statuses to limit results by.
|
|
2738
|
+
sequencing_order: str, optional
|
|
2739
|
+
The order to sequence results by.
|
|
2740
|
+
sequencing_property: str, optional
|
|
2741
|
+
The property to sequence results by.
|
|
2742
|
+
output_format: str, default = "JSON"
|
|
2743
|
+
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
|
2744
|
+
report_spec: str | dict , optional, default = None
|
|
2745
|
+
- The desired output columns/fields to include.
|
|
2746
|
+
start_from: int, [default=0], optional
|
|
2747
|
+
When multiple pages of results are available, the page number to start from.
|
|
2748
|
+
page_size: int, [default=100]
|
|
2749
|
+
The number of items to return in a single page.
|
|
2750
|
+
property_names: list[str], optional
|
|
2751
|
+
The names of properties to search for.
|
|
2752
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
|
2753
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
|
2754
|
+
|
|
2755
|
+
Returns
|
|
2756
|
+
-------
|
|
2757
|
+
List | str
|
|
2758
|
+
|
|
2759
|
+
Output depends on the output format specified.
|
|
2760
|
+
|
|
2761
|
+
Raises
|
|
2762
|
+
------
|
|
2763
|
+
|
|
2764
|
+
ValidationError
|
|
2765
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
|
2766
|
+
PyegeriaException
|
|
2767
|
+
Issues raised in communicating or server side processing.
|
|
2768
|
+
NotAuthorizedException
|
|
2769
|
+
The principle specified by the user_id does not have authorization for the requested action
|
|
2770
|
+
|
|
2771
|
+
"""
|
|
2772
|
+
response = await self._async_find_collections(search_string=search_string, starts_with=starts_with,
|
|
2773
|
+
ends_with=ends_with, ignore_case=ignore_case,
|
|
2774
|
+
anchor_domain=anchor_domain,
|
|
2775
|
+
metadata_element_type=metadata_element_type,
|
|
2776
|
+
metadata_element_subtypes=metadata_element_subtypes,
|
|
2777
|
+
skip_relationships=skip_relationships,
|
|
2778
|
+
include_only_relationships=include_only_relationships,
|
|
2779
|
+
skip_classified_elements=skip_classified_elements,
|
|
2780
|
+
include_only_classified_elements=include_only_classified_elements,
|
|
2781
|
+
graph_query_depth=graph_query_depth,
|
|
2782
|
+
governance_zone_filter=governance_zone_filter,
|
|
2783
|
+
as_of_time=as_of_time, effective_time=effective_time,
|
|
2784
|
+
relationship_page_size=relationship_page_size,
|
|
2785
|
+
limit_results_by_status=limit_results_by_status,
|
|
2786
|
+
sequencing_order=sequencing_order,
|
|
2787
|
+
sequencing_property=sequencing_property,
|
|
2788
|
+
output_format=output_format, report_spec=report_spec,
|
|
2789
|
+
start_from=start_from, page_size=page_size,
|
|
2790
|
+
property_names=property_names, body=body)
|
|
2791
|
+
return response
|
|
2792
|
+
|
|
2793
|
+
@dynamic_catch
|
|
2794
|
+
def find_glossaries(self, search_string: str = "*",
|
|
2795
|
+
starts_with: bool = True, ends_with: bool = False,
|
|
2796
|
+
ignore_case: bool = False,
|
|
2797
|
+
anchor_domain: Optional[str] = None,
|
|
2798
|
+
metadata_element_type: str = "Glossary",
|
|
2799
|
+
metadata_element_subtypes: Optional[list[str]] = None,
|
|
2800
|
+
skip_relationships: Optional[list[str]] = None,
|
|
2801
|
+
include_only_relationships: Optional[list[str]] = None,
|
|
2802
|
+
skip_classified_elements: Optional[list[str]] = None,
|
|
2803
|
+
include_only_classified_elements: Optional[list[str]] = None,
|
|
2804
|
+
graph_query_depth: int = 3,
|
|
2805
|
+
governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
|
|
2806
|
+
effective_time: Optional[str] = None, relationship_page_size: int = 0,
|
|
2807
|
+
limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
|
|
2808
|
+
sequencing_property: Optional[str] = None,
|
|
2809
|
+
output_format: str = "JSON",
|
|
2810
|
+
report_spec: str | dict = None,
|
|
2811
|
+
start_from: int = 0, page_size: int = 100,
|
|
2812
|
+
property_names: Optional[list[str]] = None,
|
|
2813
|
+
body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
|
|
2814
|
+
""" Retrieve the list of glossary metadata elements that contain the search string.
|
|
2815
|
+
|
|
2816
|
+
Parameters
|
|
2817
|
+
----------
|
|
2818
|
+
search_string: str
|
|
2819
|
+
Search string to match against - None or '*' indicate match against all glossaries.
|
|
2820
|
+
starts_with : bool, [default=True], optional
|
|
2821
|
+
Starts with the supplied string.
|
|
2822
|
+
ends_with : bool, [default=False], optional
|
|
2823
|
+
Ends with the supplied string
|
|
2824
|
+
ignore_case : bool, [default=False], optional
|
|
2825
|
+
Ignore case when searching
|
|
2826
|
+
anchor_domain: str, optional
|
|
2827
|
+
The anchor domain to search in.
|
|
2828
|
+
metadata_element_type: str, optional, [default="Glossary"]
|
|
2829
|
+
The type of metadata element to search for.
|
|
2830
|
+
metadata_element_subtypes: list[str], optional
|
|
2831
|
+
The subtypes of metadata element to search for.
|
|
2832
|
+
skip_relationships: list[str], optional
|
|
2833
|
+
The types of relationships to skip.
|
|
2834
|
+
include_only_relationships: list[str], optional
|
|
2835
|
+
The types of relationships to include.
|
|
2836
|
+
skip_classified_elements: list[str], optional
|
|
2837
|
+
The types of classified elements to skip.
|
|
2838
|
+
include_only_classified_elements: list[str], optional
|
|
2839
|
+
The types of classified elements to include.
|
|
2840
|
+
graph_query_depth: int, [default=3], optional
|
|
2841
|
+
The depth of the graph query.
|
|
2842
|
+
governance_zone_filter: list[str], optional
|
|
2843
|
+
The governance zones to search in.
|
|
2844
|
+
as_of_time: str, optional
|
|
2845
|
+
The time to search as of.
|
|
2846
|
+
effective_time: str, optional
|
|
2847
|
+
The effective time to search at.
|
|
2848
|
+
relationship_page_size: int, [default=0], optional
|
|
2849
|
+
The page size for relationships.
|
|
2850
|
+
limit_results_by_status: list[str], optional
|
|
2851
|
+
The statuses to limit results by.
|
|
2852
|
+
sequencing_order: str, optional
|
|
2853
|
+
The order to sequence results by.
|
|
2854
|
+
sequencing_property: str, optional
|
|
2855
|
+
The property to sequence results by.
|
|
2856
|
+
output_format: str, default = "JSON"
|
|
2857
|
+
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
|
2858
|
+
report_spec: str | dict , optional, default = None
|
|
2859
|
+
- The desired output columns/fields to include.
|
|
2860
|
+
start_from: int, [default=0], optional
|
|
2861
|
+
When multiple pages of results are available, the page number to start from.
|
|
2862
|
+
page_size: int, [default=100]
|
|
2863
|
+
The number of items to return in a single page.
|
|
2864
|
+
property_names: list[str], optional
|
|
2865
|
+
The names of properties to search for.
|
|
2866
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
|
2867
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
|
2868
|
+
|
|
2869
|
+
Returns
|
|
2870
|
+
-------
|
|
2871
|
+
List | str
|
|
2872
|
+
|
|
2873
|
+
Output depends on the output format specified.
|
|
2874
|
+
|
|
2875
|
+
Raises
|
|
2876
|
+
-------
|
|
2877
|
+
|
|
2878
|
+
ValidationError
|
|
2879
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
|
2880
|
+
PyegeriaException
|
|
2881
|
+
Issues raised in communicating or server side processing.
|
|
2882
|
+
NotAuthorizedException
|
|
2883
|
+
The principle specified by the user_id does not have authorization for the requested action
|
|
2884
|
+
|
|
2885
|
+
"""
|
|
2886
|
+
loop = asyncio.get_event_loop()
|
|
2887
|
+
return loop.run_until_complete(self._async_find_glossaries(search_string=search_string,
|
|
2888
|
+
starts_with=starts_with,
|
|
2889
|
+
ends_with=ends_with,
|
|
2890
|
+
ignore_case=ignore_case,
|
|
2891
|
+
anchor_domain=anchor_domain,
|
|
2892
|
+
metadata_element_type=metadata_element_type,
|
|
2893
|
+
metadata_element_subtypes=metadata_element_subtypes,
|
|
2894
|
+
skip_relationships=skip_relationships,
|
|
2895
|
+
include_only_relationships=include_only_relationships,
|
|
2896
|
+
skip_classified_elements=skip_classified_elements,
|
|
2897
|
+
include_only_classified_elements=include_only_classified_elements,
|
|
2898
|
+
graph_query_depth=graph_query_depth,
|
|
2899
|
+
governance_zone_filter=governance_zone_filter,
|
|
2900
|
+
as_of_time=as_of_time,
|
|
2901
|
+
effective_time=effective_time,
|
|
2902
|
+
relationship_page_size=relationship_page_size,
|
|
2903
|
+
limit_results_by_status=limit_results_by_status,
|
|
2904
|
+
sequencing_order=sequencing_order,
|
|
2905
|
+
sequencing_property=sequencing_property,
|
|
2906
|
+
output_format=output_format,
|
|
2907
|
+
report_spec=report_spec,
|
|
2908
|
+
start_from=start_from,
|
|
2909
|
+
page_size=page_size,
|
|
2910
|
+
property_names=property_names,
|
|
2911
|
+
body=body))
|
|
2912
|
+
|
|
2913
|
+
async def _async_get_glossaries_by_name(self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
2914
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
2915
|
+
start_from: int = 0, page_size: int = 0,
|
|
2916
|
+
output_format: str = 'JSON',
|
|
2917
|
+
report_spec: str | dict = None) -> dict | str:
|
|
2918
|
+
return await self._async_get_collections_by_name(filter_string, classification_names, body, start_from, page_size, output_format, report_spec)
|
|
2919
|
+
|
|
2920
|
+
|
|
2921
|
+
def get_glossaries_by_name(self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
2922
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
2923
|
+
start_from: int = 0, page_size: int = 0,
|
|
2924
|
+
output_format: str = 'JSON',
|
|
2925
|
+
report_spec: str | dict = None) -> dict | str:
|
|
2926
|
+
loop = asyncio.get_event_loop()
|
|
2927
|
+
response = loop.run_until_complete(
|
|
2928
|
+
self._async_get_glossaries_by_name(filter_string, classification_names, body,start_from, page_size,
|
|
2929
|
+
output_format, report_spec))
|
|
2930
|
+
return response
|
|
2931
|
+
|
|
2932
|
+
async def _async_get_glossary_by_guid(self, glossary_guid: str, element_type: str = "Glossary", body: Optional[dict | GetRequestBody] = None,
|
|
2933
|
+
output_format: str = "JSON", report_spec: str | dict = None) -> dict | str:
|
|
2934
|
+
|
|
2935
|
+
return await self._async_get_collection_by_guid(glossary_guid, element_type, body, output_format, report_spec)
|
|
2936
|
+
|
|
2937
|
+
|
|
2938
|
+
|
|
2939
|
+
def get_glossary_by_guid(self, glossary_guid: str, element_type: str = "Glossary", body: dict| GetRequestBody=None,
|
|
2940
|
+
output_format: str = "JSON", report_spec: str | dict = None) -> dict | str:
|
|
2941
|
+
loop = asyncio.get_event_loop()
|
|
2942
|
+
response = loop.run_until_complete(
|
|
2943
|
+
self._async_get_glossary_by_guid(glossary_guid, element_type, body,output_format, report_spec))
|
|
2944
|
+
return response
|
|
2945
|
+
|
|
2946
|
+
|
|
2947
|
+
|
|
2948
|
+
async def _async_get_terms_by_name(self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
2949
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
2950
|
+
start_from: int = 0, page_size: int = 0,
|
|
2951
|
+
output_format: str = 'JSON',
|
|
2952
|
+
report_spec: str | dict = None) -> list:
|
|
2953
|
+
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
|
2954
|
+
f"terms/by-name")
|
|
2955
|
+
response = await self._async_get_name_request(url, _type="GlossaryTerm",
|
|
2956
|
+
_gen_output=self._generate_term_output,
|
|
2957
|
+
filter_string=filter_string,
|
|
2958
|
+
classification_names=classification_names,
|
|
2959
|
+
start_from=start_from, page_size=page_size,
|
|
2960
|
+
output_format=output_format, report_spec=report_spec,
|
|
2961
|
+
body=body)
|
|
2962
|
+
return response
|
|
2963
|
+
|
|
2964
|
+
def get_terms_by_name(self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
2965
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
2966
|
+
start_from: int = 0, page_size: int = 0,
|
|
2967
|
+
output_format: str = 'JSON',
|
|
2968
|
+
report_spec: str | dict = None) -> list:
|
|
2969
|
+
loop = asyncio.get_event_loop()
|
|
2970
|
+
response = loop.run_until_complete(
|
|
2971
|
+
self._async_get_terms_by_name(filter_string, classification_names, body,start_from, page_size,
|
|
2972
|
+
output_format, report_spec))
|
|
2973
|
+
return response
|
|
2974
|
+
|
|
2975
|
+
async def _async_get_term_by_guid(self, term_guid: str, element_type: str = "GlossaryTerm", body: dict| GetRequestBody=None,
|
|
2976
|
+
output_format: str = "JSON", report_spec: str | dict = None) -> dict | str:
|
|
2977
|
+
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/"
|
|
2978
|
+
f"{term_guid}")
|
|
2979
|
+
response = await self._async_get_guid_request(url, _type=element_type,
|
|
2980
|
+
_gen_output=self._generate_term_output,
|
|
2981
|
+
output_format=output_format, report_spec=report_spec,
|
|
2982
|
+
body=body)
|
|
2983
|
+
return response
|
|
2984
|
+
|
|
2985
|
+
def get_term_by_guid(self, term_guid: str, element_type: str = "GlossaryTerm", body: dict| GetRequestBody=None,
|
|
2986
|
+
output_format: str = "JSON", report_spec: str | dict = None) -> dict | str:
|
|
2987
|
+
loop = asyncio.get_event_loop()
|
|
2988
|
+
response = loop.run_until_complete(self._async_get_term_by_guid(term_guid, element_type, body, output_format, report_spec))
|
|
2989
|
+
return response
|
|
2990
|
+
|
|
2991
|
+
@dynamic_catch
|
|
2992
|
+
async def _async_find_glossary_terms(self, search_string: str = "*",
|
|
2993
|
+
starts_with: bool = True, ends_with: bool = False,
|
|
2994
|
+
ignore_case: bool = False,
|
|
2995
|
+
anchor_domain: Optional[str] = None,
|
|
2996
|
+
metadata_element_type: str = "GlossaryTerm",
|
|
2997
|
+
metadata_element_subtypes: Optional[list[str]] = None,
|
|
2998
|
+
skip_relationships: Optional[list[str]] = None,
|
|
2999
|
+
include_only_relationships: Optional[list[str]] = None,
|
|
3000
|
+
skip_classified_elements: Optional[list[str]] = None,
|
|
3001
|
+
include_only_classified_elements: Optional[list[str]] = None,
|
|
3002
|
+
graph_query_depth: int = 3,
|
|
3003
|
+
governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
|
|
3004
|
+
effective_time: Optional[str] = None, relationship_page_size: int = 0,
|
|
3005
|
+
limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
|
|
3006
|
+
sequencing_property: Optional[str] = None,
|
|
3007
|
+
output_format: str = "JSON",
|
|
3008
|
+
report_spec: str | dict = "Glossary-Term-DrE",
|
|
3009
|
+
start_from: int = 0, page_size: int = 100,
|
|
3010
|
+
property_names: Optional[list[str]] = None,
|
|
3011
|
+
body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
|
|
3012
|
+
""" Retrieve the list of glossary term metadata elements that contain the search string. Async Version.
|
|
3013
|
+
|
|
3014
|
+
Parameters
|
|
3015
|
+
----------
|
|
3016
|
+
search_string: str
|
|
3017
|
+
Search string to match against - None or '*' indicate match against all glossary terms.
|
|
3018
|
+
starts_with : bool, [default=True], optional
|
|
3019
|
+
Starts with the supplied string.
|
|
3020
|
+
ends_with : bool, [default=False], optional
|
|
3021
|
+
Ends with the supplied string
|
|
3022
|
+
ignore_case : bool, [default=False], optional
|
|
3023
|
+
Ignore case when searching
|
|
3024
|
+
anchor_domain: str, optional
|
|
3025
|
+
The anchor domain to search in.
|
|
3026
|
+
metadata_element_type: str, optional, [default="GlossaryTerm"]
|
|
3027
|
+
The type of metadata element to search for.
|
|
3028
|
+
metadata_element_subtypes: list[str], optional
|
|
3029
|
+
The subtypes of metadata element to search for.
|
|
3030
|
+
skip_relationships: list[str], optional
|
|
3031
|
+
The types of relationships to skip.
|
|
3032
|
+
include_only_relationships: list[str], optional
|
|
3033
|
+
The types of relationships to include.
|
|
3034
|
+
skip_classified_elements: list[str], optional
|
|
3035
|
+
The types of classified elements to skip.
|
|
3036
|
+
include_only_classified_elements: list[str], optional
|
|
3037
|
+
The types of classified elements to include.
|
|
3038
|
+
graph_query_depth: int, [default=3], optional
|
|
3039
|
+
The depth of the graph query.
|
|
3040
|
+
governance_zone_filter: list[str], optional
|
|
3041
|
+
The governance zones to search in.
|
|
3042
|
+
as_of_time: str, optional
|
|
3043
|
+
The time to search as of.
|
|
3044
|
+
effective_time: str, optional
|
|
3045
|
+
The effective time to search at.
|
|
3046
|
+
relationship_page_size: int, [default=0], optional
|
|
3047
|
+
The page size for relationships.
|
|
3048
|
+
limit_results_by_status: list[str], optional
|
|
3049
|
+
The statuses to limit results by.
|
|
3050
|
+
sequencing_order: str, optional
|
|
3051
|
+
The order to sequence results by.
|
|
3052
|
+
sequencing_property: str, optional
|
|
3053
|
+
The property to sequence results by.
|
|
3054
|
+
output_format: str, default = "JSON"
|
|
3055
|
+
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
|
3056
|
+
report_spec: str | dict , optional, default = "Glossary-Term-DrE"
|
|
3057
|
+
- The desired output columns/fields to include.
|
|
3058
|
+
start_from: int, [default=0], optional
|
|
3059
|
+
When multiple pages of results are available, the page number to start from.
|
|
3060
|
+
page_size: int, [default=100]
|
|
3061
|
+
The number of items to return in a single page.
|
|
3062
|
+
property_names: list[str], optional
|
|
3063
|
+
The names of properties to search for.
|
|
3064
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
|
3065
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
|
3066
|
+
|
|
3067
|
+
Returns
|
|
3068
|
+
-------
|
|
3069
|
+
List | str
|
|
3070
|
+
|
|
3071
|
+
Output depends on the output format specified.
|
|
3072
|
+
|
|
3073
|
+
Raises
|
|
3074
|
+
------
|
|
3075
|
+
|
|
3076
|
+
ValidationError
|
|
3077
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
|
3078
|
+
PyegeriaException
|
|
3079
|
+
Issues raised in communicating or server side processing.
|
|
3080
|
+
NotAuthorizedException
|
|
3081
|
+
The principle specified by the user_id does not have authorization for the requested action
|
|
3082
|
+
|
|
3083
|
+
"""
|
|
3084
|
+
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/"
|
|
3085
|
+
f"by-search-string")
|
|
3086
|
+
response = await self._async_find_request(url, _type=metadata_element_type, _gen_output=self._generate_term_output,
|
|
3087
|
+
search_string=search_string, starts_with=starts_with,
|
|
3088
|
+
ends_with=ends_with, ignore_case=ignore_case,
|
|
3089
|
+
anchor_domain=anchor_domain,
|
|
3090
|
+
metadata_element_type=metadata_element_type,
|
|
3091
|
+
metadata_element_subtypes=metadata_element_subtypes,
|
|
3092
|
+
skip_relationships=skip_relationships,
|
|
3093
|
+
include_only_relationships=include_only_relationships,
|
|
3094
|
+
skip_classified_elements=skip_classified_elements,
|
|
3095
|
+
include_only_classified_elements=include_only_classified_elements,
|
|
3096
|
+
graph_query_depth=graph_query_depth,
|
|
3097
|
+
governance_zone_filter=governance_zone_filter,
|
|
3098
|
+
as_of_time=as_of_time, effective_time=effective_time,
|
|
3099
|
+
relationship_page_size=relationship_page_size,
|
|
3100
|
+
limit_results_by_status=limit_results_by_status,
|
|
3101
|
+
sequencing_order=sequencing_order,
|
|
3102
|
+
sequencing_property=sequencing_property,
|
|
3103
|
+
output_format=output_format, report_spec=report_spec,
|
|
3104
|
+
start_from=start_from, page_size=page_size,
|
|
3105
|
+
property_names=property_names, body=body)
|
|
3106
|
+
|
|
3107
|
+
return response
|
|
3108
|
+
|
|
3109
|
+
@dynamic_catch
|
|
3110
|
+
def find_glossary_terms(self, search_string: str = "*",
|
|
3111
|
+
starts_with: bool = True, ends_with: bool = False,
|
|
3112
|
+
ignore_case: bool = False,
|
|
3113
|
+
anchor_domain: Optional[str] = None,
|
|
3114
|
+
metadata_element_type: str = "GlossaryTerm",
|
|
3115
|
+
metadata_element_subtypes: Optional[list[str]] = None,
|
|
3116
|
+
skip_relationships: Optional[list[str]] = None,
|
|
3117
|
+
include_only_relationships: Optional[list[str]] = None,
|
|
3118
|
+
skip_classified_elements: Optional[list[str]] = None,
|
|
3119
|
+
include_only_classified_elements: Optional[list[str]] = None,
|
|
3120
|
+
graph_query_depth: int = 3,
|
|
3121
|
+
governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
|
|
3122
|
+
effective_time: Optional[str] = None, relationship_page_size: int = 0,
|
|
3123
|
+
limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
|
|
3124
|
+
sequencing_property: Optional[str] = None,
|
|
3125
|
+
output_format: str = "JSON",
|
|
3126
|
+
report_spec: str | dict = "Glossary-Term-DrE",
|
|
3127
|
+
start_from: int = 0, page_size: int = 100,
|
|
3128
|
+
property_names: Optional[list[str]] = None,
|
|
3129
|
+
body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
|
|
3130
|
+
""" Retrieve the list of glossary term metadata elements that contain the search string.
|
|
3131
|
+
|
|
3132
|
+
Parameters
|
|
3133
|
+
----------
|
|
3134
|
+
search_string: str
|
|
3135
|
+
Search string to match against - None or '*' indicate match against all glossary terms.
|
|
3136
|
+
starts_with : bool, [default=True], optional
|
|
3137
|
+
Starts with the supplied string.
|
|
3138
|
+
ends_with : bool, [default=False], optional
|
|
3139
|
+
Ends with the supplied string
|
|
3140
|
+
ignore_case : bool, [default=False], optional
|
|
3141
|
+
Ignore case when searching
|
|
3142
|
+
anchor_domain: str, optional
|
|
3143
|
+
The anchor domain to search in.
|
|
3144
|
+
metadata_element_type: str, optional, [default="GlossaryTerm"]
|
|
3145
|
+
The type of metadata element to search for.
|
|
3146
|
+
metadata_element_subtypes: list[str], optional
|
|
3147
|
+
The subtypes of metadata element to search for.
|
|
3148
|
+
skip_relationships: list[str], optional
|
|
3149
|
+
The types of relationships to skip.
|
|
3150
|
+
include_only_relationships: list[str], optional
|
|
3151
|
+
The types of relationships to include.
|
|
3152
|
+
skip_classified_elements: list[str], optional
|
|
3153
|
+
The types of classified elements to skip.
|
|
3154
|
+
include_only_classified_elements: list[str], optional
|
|
3155
|
+
The types of classified elements to include.
|
|
3156
|
+
graph_query_depth: int, [default=3], optional
|
|
3157
|
+
The depth of the graph query.
|
|
3158
|
+
governance_zone_filter: list[str], optional
|
|
3159
|
+
The governance zones to search in.
|
|
3160
|
+
as_of_time: str, optional
|
|
3161
|
+
The time to search as of.
|
|
3162
|
+
effective_time: str, optional
|
|
3163
|
+
The effective time to search at.
|
|
3164
|
+
relationship_page_size: int, [default=0], optional
|
|
3165
|
+
The page size for relationships.
|
|
3166
|
+
limit_results_by_status: list[str], optional
|
|
3167
|
+
The statuses to limit results by.
|
|
3168
|
+
sequencing_order: str, optional
|
|
3169
|
+
The order to sequence results by.
|
|
3170
|
+
sequencing_property: str, optional
|
|
3171
|
+
The property to sequence results by.
|
|
3172
|
+
output_format: str, default = "JSON"
|
|
3173
|
+
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
|
3174
|
+
report_spec: str | dict , optional, default = "Glossary-Term-DrE"
|
|
3175
|
+
- The desired output columns/fields to include.
|
|
3176
|
+
start_from: int, [default=0], optional
|
|
3177
|
+
When multiple pages of results are available, the page number to start from.
|
|
3178
|
+
page_size: int, [default=100]
|
|
3179
|
+
The number of items to return in a single page.
|
|
3180
|
+
property_names: list[str], optional
|
|
3181
|
+
The names of properties to search for.
|
|
3182
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
|
3183
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
|
3184
|
+
|
|
3185
|
+
Returns
|
|
3186
|
+
-------
|
|
3187
|
+
List | str
|
|
3188
|
+
|
|
3189
|
+
Output depends on the output format specified.
|
|
3190
|
+
|
|
3191
|
+
Raises
|
|
3192
|
+
-------
|
|
3193
|
+
|
|
3194
|
+
ValidationError
|
|
3195
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
|
3196
|
+
PyegeriaException
|
|
3197
|
+
Issues raised in communicating or server side processing.
|
|
3198
|
+
NotAuthorizedException
|
|
3199
|
+
The principle specified by the user_id does not have authorization for the requested action
|
|
3200
|
+
|
|
3201
|
+
"""
|
|
3202
|
+
loop = asyncio.get_event_loop()
|
|
3203
|
+
return loop.run_until_complete(self._async_find_glossary_terms(search_string=search_string,
|
|
3204
|
+
starts_with=starts_with,
|
|
3205
|
+
ends_with=ends_with,
|
|
3206
|
+
ignore_case=ignore_case,
|
|
3207
|
+
anchor_domain=anchor_domain,
|
|
3208
|
+
metadata_element_type=metadata_element_type,
|
|
3209
|
+
metadata_element_subtypes=metadata_element_subtypes,
|
|
3210
|
+
skip_relationships=skip_relationships,
|
|
3211
|
+
include_only_relationships=include_only_relationships,
|
|
3212
|
+
skip_classified_elements=skip_classified_elements,
|
|
3213
|
+
include_only_classified_elements=include_only_classified_elements,
|
|
3214
|
+
graph_query_depth=graph_query_depth,
|
|
3215
|
+
governance_zone_filter=governance_zone_filter,
|
|
3216
|
+
as_of_time=as_of_time,
|
|
3217
|
+
effective_time=effective_time,
|
|
3218
|
+
relationship_page_size=relationship_page_size,
|
|
3219
|
+
limit_results_by_status=limit_results_by_status,
|
|
3220
|
+
sequencing_order=sequencing_order,
|
|
3221
|
+
sequencing_property=sequencing_property,
|
|
3222
|
+
output_format=output_format,
|
|
3223
|
+
report_spec=report_spec,
|
|
3224
|
+
start_from=start_from,
|
|
3225
|
+
page_size=page_size,
|
|
3226
|
+
property_names=property_names,
|
|
3227
|
+
body=body))
|
|
3228
|
+
|
|
3229
|
+
|
|
3230
|
+
if __name__ == "__main__":
|
|
3231
|
+
print("Main-Glossary Manager")
|