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,1140 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
Copyright Contributors to the ODPi Egeria project.
|
|
4
|
+
|
|
5
|
+
Create, maintain reference data.
|
|
6
|
+
https://egeria-project.org/concepts/project
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
from typing import Any, Optional
|
|
12
|
+
|
|
13
|
+
from pyegeria.view.base_report_formats import select_report_spec
|
|
14
|
+
from pyegeria.core._server_client import ServerClient
|
|
15
|
+
from pyegeria.view.base_report_formats import get_report_spec_match
|
|
16
|
+
from pyegeria.core.config import settings as app_settings
|
|
17
|
+
from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequestBody, NewElementRequestBody,
|
|
18
|
+
TemplateRequestBody, UpdateElementRequestBody,
|
|
19
|
+
NewRelationshipRequestBody, DeleteElementRequestBody, DeleteRelationshipRequestBody)
|
|
20
|
+
from pyegeria.view.output_formatter import generate_output, populate_common_columns
|
|
21
|
+
from pyegeria.core.utils import dynamic_catch
|
|
22
|
+
|
|
23
|
+
EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
|
|
24
|
+
from loguru import logger
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ReferenceDataManager(ServerClient):
|
|
28
|
+
"""
|
|
29
|
+
Manage Reference Data in Egeria..
|
|
30
|
+
|
|
31
|
+
This client provides asynchronous and synchronous helpers to create, update, search,
|
|
32
|
+
and relate Reference Data elements and their subtypes (Campaign, StudyProject, Task, PersonalProject).
|
|
33
|
+
|
|
34
|
+
References
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
-----------
|
|
39
|
+
view_server : str
|
|
40
|
+
The name of the View Server to connect to.
|
|
41
|
+
platform_url : str
|
|
42
|
+
URL of the server platform to connect to.
|
|
43
|
+
user_id : str
|
|
44
|
+
Default user identity for calls (can be overridden per call).
|
|
45
|
+
user_pwd : str, optional
|
|
46
|
+
Password for the user_id. If a token is supplied, this may be None.
|
|
47
|
+
|
|
48
|
+
Notes
|
|
49
|
+
-----
|
|
50
|
+
- Most high-level list/report methods accept an `output_format` and an optional `report_spec` and
|
|
51
|
+
delegate rendering to `pyegeria.output_formatter.generate_output` along with shared helpers such as
|
|
52
|
+
`populate_common_columns`.
|
|
53
|
+
- Private extractor methods follow the convention: `_extract_<entity>_properties(element, columns_struct)` and
|
|
54
|
+
must return the same `columns_struct` with per-column `value` fields populated.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
view_server: str,
|
|
60
|
+
platform_url: str,
|
|
61
|
+
user_id: str,
|
|
62
|
+
user_pwd: Optional[str] = None,
|
|
63
|
+
token: Optional[str] = None,
|
|
64
|
+
):
|
|
65
|
+
self.view_server = view_server
|
|
66
|
+
self.platform_url = platform_url
|
|
67
|
+
self.user_id = user_id
|
|
68
|
+
self.user_pwd = user_pwd
|
|
69
|
+
self.ref_data_command_base: str = (
|
|
70
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/reference-data"
|
|
71
|
+
)
|
|
72
|
+
self.url_marker = 'reference-data'
|
|
73
|
+
ServerClient.__init__(self, view_server, platform_url, user_id, user_pwd, token)
|
|
74
|
+
|
|
75
|
+
def _extract_additional_valid_value_definition_properties(self, element: dict, columns_struct: dict)-> dict:
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
roles_required = any(column.get('key') == 'project_roles'
|
|
79
|
+
for column in columns_struct.get('formats', {}).get('attributes', []))
|
|
80
|
+
project_props = {}
|
|
81
|
+
|
|
82
|
+
if roles_required:
|
|
83
|
+
project_roles = element['elementHeader'].get('projectRoles', [])
|
|
84
|
+
project_roles_list = []
|
|
85
|
+
for project_role in project_roles:
|
|
86
|
+
project_roles_list.append(project_role.get('classificationName', ""))
|
|
87
|
+
project_roles_md = (", \n".join(project_roles_list)).rstrip(',') if project_roles_list else ''
|
|
88
|
+
project_props = {
|
|
89
|
+
'project_roles': project_roles_md,
|
|
90
|
+
}
|
|
91
|
+
return project_props
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _extract_valid_value_definition_properties(self, element: dict, columns_struct: dict) -> dict:
|
|
97
|
+
props = element.get('properties', {}) or {}
|
|
98
|
+
normalized = {
|
|
99
|
+
'properties': props,
|
|
100
|
+
'elementHeader': element.get('elementHeader', {}),
|
|
101
|
+
}
|
|
102
|
+
# Common population pipeline
|
|
103
|
+
col_data = populate_common_columns(element, columns_struct)
|
|
104
|
+
columns_list = col_data.get('formats', {}).get('attributes', [])
|
|
105
|
+
# Overlay extras (project perspectives) only where empty
|
|
106
|
+
|
|
107
|
+
# extra = self._extract_additional_project_properties(element, columns_struct)
|
|
108
|
+
|
|
109
|
+
# col_data = overlay_additional_values(col_data, extra)
|
|
110
|
+
return col_data
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _generate_vv_def_output(self, elements: dict | list[dict], search_string: str,
|
|
114
|
+
element_type_name: str | None,
|
|
115
|
+
output_format: str = 'DICT',
|
|
116
|
+
report_spec: dict | str = None) -> str | list[dict]:
|
|
117
|
+
entity_type = 'ValidValueDefinition'
|
|
118
|
+
if report_spec:
|
|
119
|
+
if isinstance(report_spec, str):
|
|
120
|
+
output_formats = select_report_spec(report_spec, output_format)
|
|
121
|
+
elif isinstance(report_spec, dict):
|
|
122
|
+
output_formats = get_report_spec_match(report_spec, output_format)
|
|
123
|
+
else:
|
|
124
|
+
output_formats = None
|
|
125
|
+
else:
|
|
126
|
+
output_formats = select_report_spec(entity_type, output_format)
|
|
127
|
+
if output_formats is None:
|
|
128
|
+
output_formats = select_report_spec('Default', output_format)
|
|
129
|
+
return generate_output(
|
|
130
|
+
elements=elements,
|
|
131
|
+
search_string=search_string,
|
|
132
|
+
entity_type=entity_type,
|
|
133
|
+
output_format=output_format,
|
|
134
|
+
extract_properties_func=self._extract_valid_value_definition_properties,
|
|
135
|
+
get_additional_props_func=None,
|
|
136
|
+
columns_struct=output_formats,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
# Retrieving Projects= Information - https://egeria-project.org/concepts/project
|
|
141
|
+
#
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@dynamic_catch
|
|
145
|
+
async def _async_find_valid_value_definitions(
|
|
146
|
+
self,
|
|
147
|
+
search_string: str, classification_names: Optional[list[str]] = None, metadata_element_subtypes: Optional[list[str]] = None,
|
|
148
|
+
starts_with: bool = False,
|
|
149
|
+
ends_with: bool = False,
|
|
150
|
+
ignore_case: bool = False,
|
|
151
|
+
start_from: int = 0,
|
|
152
|
+
page_size: int = 0,
|
|
153
|
+
output_format: str = "json", report_spec: str | dict = None,
|
|
154
|
+
body: Optional[dict | SearchStringRequestBody] = None
|
|
155
|
+
) -> list | str:
|
|
156
|
+
""" Returns the list of valid value definitions matching the search string.
|
|
157
|
+
The search string is located in the request body and is interpreted as a plain string.
|
|
158
|
+
The request parameters, startsWith, endsWith,and ignoreCase can be used to allow a fuzzy search.
|
|
159
|
+
Async version.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
search_string: str,
|
|
164
|
+
Search string to use to find matching projects. If the search string is '*' then all projects returned.
|
|
165
|
+
effective_time: str, [default=None], optional
|
|
166
|
+
Effective time of the query. If not specified will default to any time.
|
|
167
|
+
output_format: str, default = "JSON"
|
|
168
|
+
- Type of output to return.
|
|
169
|
+
report_spec: dict | str, default = None
|
|
170
|
+
- Output format set to use. If None, the default output format set is used.
|
|
171
|
+
|
|
172
|
+
starts_with : bool, [default=False], optional
|
|
173
|
+
Starts with the supplied string.
|
|
174
|
+
ends_with : bool, [default=False], optional
|
|
175
|
+
Ends with the supplied string
|
|
176
|
+
ignore_case : bool, [default=False], optional
|
|
177
|
+
Ignore case when searching
|
|
178
|
+
start_from: int, [default=0], optional
|
|
179
|
+
When multiple pages of results are available, the page number to start from.
|
|
180
|
+
page_size: int, [default=None]
|
|
181
|
+
The number of items to return in a single page. If not specified, the default will be taken from
|
|
182
|
+
the class instance.
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
List | str
|
|
186
|
+
|
|
187
|
+
A list of projects matching the search string. Returns a string if none found.
|
|
188
|
+
|
|
189
|
+
Raises
|
|
190
|
+
------
|
|
191
|
+
|
|
192
|
+
PyegeriaException
|
|
193
|
+
ValidationError
|
|
194
|
+
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/by-search-string"
|
|
198
|
+
|
|
199
|
+
response = await self._async_find_request(url, _type="ValidValuesDefinition",
|
|
200
|
+
_gen_output=self._generate_vv_def_output, search_string=search_string,
|
|
201
|
+
output_format="JSON", page_size=0, body=body)
|
|
202
|
+
|
|
203
|
+
return response
|
|
204
|
+
|
|
205
|
+
@dynamic_catch
|
|
206
|
+
def find_valid_value_definitions(
|
|
207
|
+
self,
|
|
208
|
+
search_string: str, classification_names: Optional[list[str]] = None, metadata_element_subtypes: Optional[list[str]] = None,
|
|
209
|
+
starts_with: bool = False,
|
|
210
|
+
ends_with: bool = False,
|
|
211
|
+
ignore_case: bool = False,
|
|
212
|
+
start_from: int = 0,
|
|
213
|
+
page_size: int = 0,
|
|
214
|
+
output_format: str = "json", report_spec: str | dict = None,
|
|
215
|
+
body: Optional[dict | SearchStringRequestBody] = None
|
|
216
|
+
) -> list | str:
|
|
217
|
+
|
|
218
|
+
""" Returns the list of valid value definitions matching the search string.
|
|
219
|
+
The search string is located in the request body and is interpreted as a plain string.
|
|
220
|
+
The request parameters, startsWith, endsWith, and ignoreCase can be used to allow a fuzzy search.
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
search_string: str,
|
|
225
|
+
Search string to use to find matching projects. If the search string is '*' then all projects returned.
|
|
226
|
+
effective_time: str, [default=None], optional
|
|
227
|
+
Effective time of the query. If not specified will default to any time.
|
|
228
|
+
|
|
229
|
+
starts_with : bool, [default=False], optional
|
|
230
|
+
Starts with the supplied string.
|
|
231
|
+
ends_with : bool, [default=False], optional
|
|
232
|
+
Ends with the supplied string
|
|
233
|
+
ignore_case : bool, [default=False], optional
|
|
234
|
+
Ignore case when searching
|
|
235
|
+
start_from: int, [default=0], optional
|
|
236
|
+
When multiple pages of results are available, the page number to start from.
|
|
237
|
+
page_size: int, [default=None]
|
|
238
|
+
The number of items to return in a single page. If not specified, the default will be taken from
|
|
239
|
+
the class instance.
|
|
240
|
+
Returns
|
|
241
|
+
-------
|
|
242
|
+
List | str
|
|
243
|
+
|
|
244
|
+
A list of projects matching the search string. Returns a string if none found.
|
|
245
|
+
|
|
246
|
+
Raises
|
|
247
|
+
------
|
|
248
|
+
|
|
249
|
+
PyegeriaException
|
|
250
|
+
ValidationError
|
|
251
|
+
|
|
252
|
+
"""
|
|
253
|
+
loop = asyncio.get_event_loop()
|
|
254
|
+
resp = loop.run_until_complete(
|
|
255
|
+
self._async_find_valid_value_definitions(
|
|
256
|
+
search_string,
|
|
257
|
+
classification_names,
|
|
258
|
+
metadata_element_subtypes,
|
|
259
|
+
starts_with,
|
|
260
|
+
ends_with,
|
|
261
|
+
ignore_case,
|
|
262
|
+
start_from,
|
|
263
|
+
page_size,
|
|
264
|
+
output_format,
|
|
265
|
+
report_spec,
|
|
266
|
+
body,
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
return resp
|
|
271
|
+
|
|
272
|
+
@dynamic_catch
|
|
273
|
+
async def _async_get_valid_value_definitions_by_name(
|
|
274
|
+
self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
275
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
276
|
+
start_from: int = 0, page_size: int = 0,
|
|
277
|
+
output_format: str = 'JSON',
|
|
278
|
+
report_spec: str | dict = None) -> list | str:
|
|
279
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/by-name"
|
|
280
|
+
|
|
281
|
+
response = await self._async_get_name_request(url, _type="ValidValuesDefinition",
|
|
282
|
+
_gen_output=self._generate_vv_def_output,
|
|
283
|
+
filter_string=filter_string,
|
|
284
|
+
classification_names=classification_names,
|
|
285
|
+
start_from=start_from, page_size=page_size,
|
|
286
|
+
output_format=output_format, report_spec=report_spec,
|
|
287
|
+
body=body)
|
|
288
|
+
|
|
289
|
+
return response
|
|
290
|
+
|
|
291
|
+
@dynamic_catch
|
|
292
|
+
def get_valid_value_definitions_by_name(
|
|
293
|
+
self, filter_string: Optional[str] = None, classification_names: Optional[list[str]] = None,
|
|
294
|
+
body: Optional[dict | FilterRequestBody] = None,
|
|
295
|
+
start_from: int = 0, page_size: int = 0,
|
|
296
|
+
output_format: str = 'JSON',
|
|
297
|
+
report_spec: str | dict = None) -> list | str:
|
|
298
|
+
|
|
299
|
+
loop = asyncio.get_event_loop()
|
|
300
|
+
resp = loop.run_until_complete(
|
|
301
|
+
self._async_get_valid_value_definitions_by_name(
|
|
302
|
+
filter_string,
|
|
303
|
+
classification_names,
|
|
304
|
+
body,
|
|
305
|
+
start_from,
|
|
306
|
+
page_size,
|
|
307
|
+
output_format,
|
|
308
|
+
report_spec,
|
|
309
|
+
)
|
|
310
|
+
)
|
|
311
|
+
return resp
|
|
312
|
+
|
|
313
|
+
@dynamic_catch
|
|
314
|
+
async def _async_get_valid_value_definition_by_guid(self, vv_def_guid: str, element_type: Optional[str] = None,
|
|
315
|
+
body: Optional[dict | GetRequestBody] = None,
|
|
316
|
+
output_format: str = 'JSON',
|
|
317
|
+
report_spec: str | dict = None) -> dict | str:
|
|
318
|
+
"""Return the properties of a specific project. Async version.
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
vv_def_guid: str,
|
|
323
|
+
unique identifier of the collection.
|
|
324
|
+
element_type: str, default = None, optional
|
|
325
|
+
type of valid value
|
|
326
|
+
body: dict | GetRequestBody, optional, default = None
|
|
327
|
+
full request body.
|
|
328
|
+
output_format: str, default = "JSON"
|
|
329
|
+
- one of "DICT", "MERMAID" or "JSON"
|
|
330
|
+
report_spec: str | dict, optional, default = None
|
|
331
|
+
The desired output columns/fields to include.
|
|
332
|
+
|
|
333
|
+
Returns
|
|
334
|
+
-------
|
|
335
|
+
dict | str
|
|
336
|
+
|
|
337
|
+
A JSON dict representing the specified collection. Returns a string if none found.
|
|
338
|
+
|
|
339
|
+
Raises
|
|
340
|
+
------
|
|
341
|
+
PyegeriaException
|
|
342
|
+
ValidationError
|
|
343
|
+
|
|
344
|
+
Notes
|
|
345
|
+
----
|
|
346
|
+
Body sample:
|
|
347
|
+
{
|
|
348
|
+
"class": "GetRequestBody",
|
|
349
|
+
"asOfTime": "{{$isoTimestamp}}",
|
|
350
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
|
351
|
+
"forLineage": false,
|
|
352
|
+
"forDuplicateProcessing": false
|
|
353
|
+
}
|
|
354
|
+
"""
|
|
355
|
+
|
|
356
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/{vv_def_guid}/retrieve"
|
|
357
|
+
type = element_type if element_type else "ValidValueDefinition"
|
|
358
|
+
|
|
359
|
+
response = await self._async_get_guid_request(url, _type=type,
|
|
360
|
+
_gen_output=self._generate_vv_def_output,
|
|
361
|
+
output_format=output_format, report_spec=report_spec,
|
|
362
|
+
body=body)
|
|
363
|
+
|
|
364
|
+
return response
|
|
365
|
+
|
|
366
|
+
@dynamic_catch
|
|
367
|
+
def get_valid_value_definition_by_guid(self, vv_def_guid: str, element_type: Optional[str] = None,
|
|
368
|
+
body: Optional[dict | GetRequestBody] = None,
|
|
369
|
+
output_format: str = 'JSON',
|
|
370
|
+
report_spec: str | dict = None) -> dict | str:
|
|
371
|
+
"""Return the properties of a specific project.
|
|
372
|
+
|
|
373
|
+
Parameters
|
|
374
|
+
----------
|
|
375
|
+
vv_def_guid: str,
|
|
376
|
+
unique identifier of the collection.
|
|
377
|
+
element_type: str, default = None, optional
|
|
378
|
+
type of collection - Collection, DataSpec, Agreement, etc.
|
|
379
|
+
body: dict | GetRequestBody, optional, default = None
|
|
380
|
+
full request body.
|
|
381
|
+
output_format: str, default = "JSON"
|
|
382
|
+
- one of "DICT", "MERMAID" or "JSON"
|
|
383
|
+
report_spec: str | dict, optional, default = None
|
|
384
|
+
The desired output columns/fields to include.
|
|
385
|
+
|
|
386
|
+
Returns
|
|
387
|
+
-------
|
|
388
|
+
dict | str
|
|
389
|
+
|
|
390
|
+
A JSON dict representing the specified collection. Returns a string if none found.
|
|
391
|
+
|
|
392
|
+
Raises
|
|
393
|
+
------
|
|
394
|
+
|
|
395
|
+
PyegeriaInvalidParameterException
|
|
396
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
|
397
|
+
PyegeriaAPIException
|
|
398
|
+
Raised by the server when an issue arises in processing a valid request
|
|
399
|
+
NotAuthorizedException
|
|
400
|
+
The principle specified by the user_id does not have authorization for the requested action
|
|
401
|
+
|
|
402
|
+
Notes
|
|
403
|
+
----
|
|
404
|
+
Body sample:
|
|
405
|
+
{
|
|
406
|
+
"class": "GetRequestBody",
|
|
407
|
+
"asOfTime": "{{$isoTimestamp}}",
|
|
408
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
|
409
|
+
"forLineage": false,
|
|
410
|
+
"forDuplicateProcessing": false
|
|
411
|
+
}
|
|
412
|
+
"""
|
|
413
|
+
loop = asyncio.get_event_loop()
|
|
414
|
+
resp = loop.run_until_complete(
|
|
415
|
+
self._async_get_valid_value_definition_by_guid(vv_def_guid, element_type, body, output_format, report_spec)
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
return resp
|
|
419
|
+
|
|
420
|
+
#
|
|
421
|
+
# Create Valid Value Definition methods
|
|
422
|
+
#
|
|
423
|
+
@dynamic_catch
|
|
424
|
+
async def _async_create_valid_value_definition(self, body: dict | NewElementRequestBody) -> str:
|
|
425
|
+
"""Create Valid Value definition. Async version.
|
|
426
|
+
|
|
427
|
+
Parameters
|
|
428
|
+
----------.
|
|
429
|
+
body: dict
|
|
430
|
+
A dict representing the details of the valid value definition to create. .
|
|
431
|
+
|
|
432
|
+
Returns
|
|
433
|
+
-------
|
|
434
|
+
str - the guid of the created valid value definition.
|
|
435
|
+
|
|
436
|
+
Raises
|
|
437
|
+
------
|
|
438
|
+
PyegeriaException
|
|
439
|
+
ValidationError
|
|
440
|
+
|
|
441
|
+
Notes
|
|
442
|
+
-----
|
|
443
|
+
|
|
444
|
+
Body structure like:
|
|
445
|
+
{
|
|
446
|
+
"class" : "NewElementRequestBody",
|
|
447
|
+
"anchorGUID" : "add guid here",
|
|
448
|
+
"isOwnAnchor": false,
|
|
449
|
+
"parentGUID": "add guid here",
|
|
450
|
+
"parentRelationshipTypeName": "add type name here",
|
|
451
|
+
"parentRelationshipProperties": {
|
|
452
|
+
"class": "RelationshipElementProperties",
|
|
453
|
+
"propertyValueMap" : {
|
|
454
|
+
"description" : {
|
|
455
|
+
"class": "PrimitiveTypePropertyValue",
|
|
456
|
+
"typeName": "string",
|
|
457
|
+
"primitiveValue" : "New description"
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
"parentAtEnd1": false,
|
|
462
|
+
"initialClassifications" : {
|
|
463
|
+
"ZoneMembership" : { "class" : "ZoneMembershipProperties" ,
|
|
464
|
+
"zoneMembership" : ["QuarantineZone", "Production"]}
|
|
465
|
+
},
|
|
466
|
+
"properties": {
|
|
467
|
+
"class" : "ValidValueDefinitionProperties",
|
|
468
|
+
"qualifiedName": "add unique name here",
|
|
469
|
+
"displayName": "add short name here",
|
|
470
|
+
"description": "add description here",
|
|
471
|
+
"category": "add description here",
|
|
472
|
+
"namespace" : "add namespace here",
|
|
473
|
+
"userDefinedStatus" : "add status here",
|
|
474
|
+
"usage": "add usage here",
|
|
475
|
+
"dataType" : "add data type here",
|
|
476
|
+
"scope" : "add scope here",
|
|
477
|
+
"preferredValue" : "add preferred value here",
|
|
478
|
+
"isCaseSensitive" : false,
|
|
479
|
+
"additionalProperties": {
|
|
480
|
+
"property1" : "propertyValue1",
|
|
481
|
+
"property2" : "propertyValue2"
|
|
482
|
+
},
|
|
483
|
+
"extendedProperties": {
|
|
484
|
+
"property1" : "propertyValue1",
|
|
485
|
+
"property2" : "propertyValue2"
|
|
486
|
+
},
|
|
487
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
488
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
489
|
+
},
|
|
490
|
+
"externalSourceGUID": "add guid here",
|
|
491
|
+
"externalSourceName": "add qualified name here",
|
|
492
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
493
|
+
"forLineage" : false,
|
|
494
|
+
"forDuplicateProcessing" : false
|
|
495
|
+
}
|
|
496
|
+
"""
|
|
497
|
+
|
|
498
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions"
|
|
499
|
+
|
|
500
|
+
return await self._async_create_element_body_request(url, ["ValidValueDefinitionProperties"], body)
|
|
501
|
+
|
|
502
|
+
@dynamic_catch
|
|
503
|
+
def create_valid_value_definition(self, body: dict | NewElementRequestBody) -> str:
|
|
504
|
+
"""Create Valid Value definition. Async version.
|
|
505
|
+
|
|
506
|
+
Parameters
|
|
507
|
+
----------.
|
|
508
|
+
body: dict
|
|
509
|
+
A dict representing the details of the valid value definition to create. .
|
|
510
|
+
|
|
511
|
+
Returns
|
|
512
|
+
-------
|
|
513
|
+
str - the guid of the created valid value definition.
|
|
514
|
+
|
|
515
|
+
Raises
|
|
516
|
+
------
|
|
517
|
+
PyegeriaException
|
|
518
|
+
ValidationError
|
|
519
|
+
|
|
520
|
+
Notes
|
|
521
|
+
-----
|
|
522
|
+
|
|
523
|
+
Body structure like:
|
|
524
|
+
{
|
|
525
|
+
"class" : "NewElementRequestBody",
|
|
526
|
+
"anchorGUID" : "add guid here",
|
|
527
|
+
"isOwnAnchor": false,
|
|
528
|
+
"parentGUID": "add guid here",
|
|
529
|
+
"parentRelationshipTypeName": "add type name here",
|
|
530
|
+
"parentRelationshipProperties": {
|
|
531
|
+
"class": "RelationshipElementProperties",
|
|
532
|
+
"propertyValueMap" : {
|
|
533
|
+
"description" : {
|
|
534
|
+
"class": "PrimitiveTypePropertyValue",
|
|
535
|
+
"typeName": "string",
|
|
536
|
+
"primitiveValue" : "New description"
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
"parentAtEnd1": false,
|
|
541
|
+
"initialClassifications" : {
|
|
542
|
+
"ZoneMembership" : { "class" : "ZoneMembershipProperties" ,
|
|
543
|
+
"zoneMembership" : ["QuarantineZone", "Production"]}
|
|
544
|
+
},
|
|
545
|
+
"properties": {
|
|
546
|
+
"class" : "ValidValueDefinitionProperties",
|
|
547
|
+
"qualifiedName": "add unique name here",
|
|
548
|
+
"displayName": "add short name here",
|
|
549
|
+
"description": "add description here",
|
|
550
|
+
"category": "add description here",
|
|
551
|
+
"namespace" : "add namespace here",
|
|
552
|
+
"userDefinedStatus" : "add status here",
|
|
553
|
+
"usage": "add usage here",
|
|
554
|
+
"dataType" : "add data type here",
|
|
555
|
+
"scope" : "add scope here",
|
|
556
|
+
"preferredValue" : "add preferred value here",
|
|
557
|
+
"isCaseSensitive" : false,
|
|
558
|
+
"additionalProperties": {
|
|
559
|
+
"property1" : "propertyValue1",
|
|
560
|
+
"property2" : "propertyValue2"
|
|
561
|
+
},
|
|
562
|
+
"extendedProperties": {
|
|
563
|
+
"property1" : "propertyValue1",
|
|
564
|
+
"property2" : "propertyValue2"
|
|
565
|
+
},
|
|
566
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
567
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
568
|
+
},
|
|
569
|
+
"externalSourceGUID": "add guid here",
|
|
570
|
+
"externalSourceName": "add qualified name here",
|
|
571
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
572
|
+
"forLineage" : false,
|
|
573
|
+
"forDuplicateProcessing" : false
|
|
574
|
+
}
|
|
575
|
+
"""
|
|
576
|
+
loop = asyncio.get_event_loop()
|
|
577
|
+
resp = loop.run_until_complete(
|
|
578
|
+
self._async_create_valid_value_definition(body)
|
|
579
|
+
)
|
|
580
|
+
return resp
|
|
581
|
+
|
|
582
|
+
@dynamic_catch
|
|
583
|
+
async def _async_create_valid_value_definition_from_template(
|
|
584
|
+
self,
|
|
585
|
+
body: dict | TemplateRequestBody,
|
|
586
|
+
) -> str:
|
|
587
|
+
""" Create a new metadata element to represent a valid value definition using an existing metadata element as a template.
|
|
588
|
+
The template defines additional classifications and relationships that should be added to the new element.
|
|
589
|
+
Request body provides properties that override the template
|
|
590
|
+
Async version.
|
|
591
|
+
|
|
592
|
+
Parameters
|
|
593
|
+
----------
|
|
594
|
+
|
|
595
|
+
body: dict
|
|
596
|
+
A dict representing the details of the valid value definition to create and the over-rides to the template..
|
|
597
|
+
|
|
598
|
+
Returns
|
|
599
|
+
-------
|
|
600
|
+
str - the guid of the created valid value definition.
|
|
601
|
+
|
|
602
|
+
Raises
|
|
603
|
+
------
|
|
604
|
+
PyegeriaException
|
|
605
|
+
ValidationError
|
|
606
|
+
|
|
607
|
+
Notes
|
|
608
|
+
-----
|
|
609
|
+
JSON Structure looks like:
|
|
610
|
+
|
|
611
|
+
{
|
|
612
|
+
"class" : "TemplateRequestBody",
|
|
613
|
+
"anchorGUID" : "add guid here",
|
|
614
|
+
"isOwnAnchor": false,
|
|
615
|
+
"parentGUID": "add guid here",
|
|
616
|
+
"parentRelationshipTypeName": "add type name here",
|
|
617
|
+
"parentRelationshipProperties": {
|
|
618
|
+
"class": "RelationshipElementProperties",
|
|
619
|
+
"propertyValueMap" : {
|
|
620
|
+
"description" : {
|
|
621
|
+
"class": "PrimitiveTypePropertyValue",
|
|
622
|
+
"typeName": "string",
|
|
623
|
+
"primitiveValue" : "New description"
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
"parentAtEnd1": false,
|
|
628
|
+
"templateGUID": "add guid here",
|
|
629
|
+
"replacementProperties": {
|
|
630
|
+
"class": "ElementProperties",
|
|
631
|
+
"propertyValueMap" : {
|
|
632
|
+
"description" : {
|
|
633
|
+
"class": "PrimitiveTypePropertyValue",
|
|
634
|
+
"typeName": "string",
|
|
635
|
+
"primitiveValue" : "New description"
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
"placeholderPropertyValues": {
|
|
640
|
+
"placeholder1" : "propertyValue1",
|
|
641
|
+
"placeholder2" : "propertyValue2"
|
|
642
|
+
},
|
|
643
|
+
"externalSourceGUID": "add guid here",
|
|
644
|
+
"externalSourceName": "add qualified name here",
|
|
645
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
646
|
+
"forLineage" : false,
|
|
647
|
+
"forDuplicateProcessing" : false
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
"""
|
|
651
|
+
|
|
652
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/from-template"
|
|
653
|
+
return await self._async_create_element_from_template(url, body)
|
|
654
|
+
|
|
655
|
+
@dynamic_catch
|
|
656
|
+
def create_valid_value_definition_from_template(
|
|
657
|
+
self,
|
|
658
|
+
body: dict | TemplateRequestBody,
|
|
659
|
+
) -> str:
|
|
660
|
+
""" Create a new metadata element to represent a valid value definition using an existing metadata element as a template.
|
|
661
|
+
The template defines additional classifications and relationships that should be added to the new element.
|
|
662
|
+
Request body provides properties that override the template
|
|
663
|
+
|
|
664
|
+
Parameters
|
|
665
|
+
----------
|
|
666
|
+
|
|
667
|
+
body: dict
|
|
668
|
+
A dict representing the details of the valid value definition to create and the over-rides to the template..
|
|
669
|
+
|
|
670
|
+
Returns
|
|
671
|
+
-------
|
|
672
|
+
str - the guid of the created valid value definition.
|
|
673
|
+
|
|
674
|
+
Raises
|
|
675
|
+
------
|
|
676
|
+
PyegeriaException
|
|
677
|
+
ValidationError
|
|
678
|
+
|
|
679
|
+
Notes
|
|
680
|
+
-----
|
|
681
|
+
JSON Structure looks like:
|
|
682
|
+
|
|
683
|
+
{
|
|
684
|
+
"class" : "TemplateRequestBody",
|
|
685
|
+
"anchorGUID" : "add guid here",
|
|
686
|
+
"isOwnAnchor": false,
|
|
687
|
+
"parentGUID": "add guid here",
|
|
688
|
+
"parentRelationshipTypeName": "add type name here",
|
|
689
|
+
"parentRelationshipProperties": {
|
|
690
|
+
"class": "RelationshipElementProperties",
|
|
691
|
+
"propertyValueMap" : {
|
|
692
|
+
"description" : {
|
|
693
|
+
"class": "PrimitiveTypePropertyValue",
|
|
694
|
+
"typeName": "string",
|
|
695
|
+
"primitiveValue" : "New description"
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
"parentAtEnd1": false,
|
|
700
|
+
"templateGUID": "add guid here",
|
|
701
|
+
"replacementProperties": {
|
|
702
|
+
"class": "ElementProperties",
|
|
703
|
+
"propertyValueMap" : {
|
|
704
|
+
"description" : {
|
|
705
|
+
"class": "PrimitiveTypePropertyValue",
|
|
706
|
+
"typeName": "string",
|
|
707
|
+
"primitiveValue" : "New description"
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
},
|
|
711
|
+
"placeholderPropertyValues": {
|
|
712
|
+
"placeholder1" : "propertyValue1",
|
|
713
|
+
"placeholder2" : "propertyValue2"
|
|
714
|
+
},
|
|
715
|
+
"externalSourceGUID": "add guid here",
|
|
716
|
+
"externalSourceName": "add qualified name here",
|
|
717
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
718
|
+
"forLineage" : false,
|
|
719
|
+
"forDuplicateProcessing" : false
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
"""
|
|
723
|
+
|
|
724
|
+
loop = asyncio.get_event_loop()
|
|
725
|
+
resp = loop.run_until_complete(self._async_create_valid_value_definition_from_template(body))
|
|
726
|
+
return resp
|
|
727
|
+
|
|
728
|
+
#
|
|
729
|
+
#
|
|
730
|
+
#
|
|
731
|
+
|
|
732
|
+
@dynamic_catch
|
|
733
|
+
async def _async_update_valid_value_definition(
|
|
734
|
+
self,
|
|
735
|
+
vv_def_guid: str,
|
|
736
|
+
body: dict | UpdateElementRequestBody
|
|
737
|
+
) -> None:
|
|
738
|
+
"""Update the properties of a valid value definition. Async Version.
|
|
739
|
+
|
|
740
|
+
Parameters
|
|
741
|
+
----------
|
|
742
|
+
vv_def_guid: str
|
|
743
|
+
Unique identifier for the valid value definition.
|
|
744
|
+
body: dict | UpdateElementRequestBody
|
|
745
|
+
A dict representing the details of the valid value definition to update.
|
|
746
|
+
|
|
747
|
+
Returns
|
|
748
|
+
-------
|
|
749
|
+
None
|
|
750
|
+
|
|
751
|
+
Raises
|
|
752
|
+
------
|
|
753
|
+
PyegeriaException
|
|
754
|
+
ValidationError
|
|
755
|
+
|
|
756
|
+
Notes
|
|
757
|
+
_____
|
|
758
|
+
Sample body:
|
|
759
|
+
{
|
|
760
|
+
"class" : "UpdateElementRequestBody",
|
|
761
|
+
"mergeUpdate": true,
|
|
762
|
+
"properties": {
|
|
763
|
+
"class" : "ValidValueDefinitionProperties",
|
|
764
|
+
"qualifiedName": "add unique name here",
|
|
765
|
+
"displayName": "add short name here",
|
|
766
|
+
"description": "add description here",
|
|
767
|
+
"category": "add description here",
|
|
768
|
+
"namespace" : "add namespace here",
|
|
769
|
+
"userDefinedStatus" : "add status here",
|
|
770
|
+
"usage": "add usage here",
|
|
771
|
+
"dataType" : "add data type here",
|
|
772
|
+
"scope" : "add scope here",
|
|
773
|
+
"preferredValue" : "add preferred value here",
|
|
774
|
+
"isCaseSensitive" : false,
|
|
775
|
+
"additionalProperties": {
|
|
776
|
+
"property1" : "propertyValue1",
|
|
777
|
+
"property2" : "propertyValue2"
|
|
778
|
+
},
|
|
779
|
+
"extendedProperties": {
|
|
780
|
+
"property1" : "propertyValue1",
|
|
781
|
+
"property2" : "propertyValue2"
|
|
782
|
+
},
|
|
783
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
784
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
785
|
+
},
|
|
786
|
+
"externalSourceGUID": "add guid here",
|
|
787
|
+
"externalSourceName": "add qualified name here",
|
|
788
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
789
|
+
"forLineage" : false,
|
|
790
|
+
"forDuplicateProcessing" : false
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
"""
|
|
794
|
+
|
|
795
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/{vv_def_guid}/update"
|
|
796
|
+
|
|
797
|
+
await self._async_update_element_body_request(url, ["ValidValueDefinitionProperties"], body)
|
|
798
|
+
logger.info(f"Updated valid value definition {vv_def_guid}")
|
|
799
|
+
|
|
800
|
+
@dynamic_catch
|
|
801
|
+
def update_valid_value_definition(
|
|
802
|
+
self,
|
|
803
|
+
vv_def_guid: str,
|
|
804
|
+
body: dict | UpdateElementRequestBody
|
|
805
|
+
) -> None:
|
|
806
|
+
"""Update the properties of a valid value definition.
|
|
807
|
+
|
|
808
|
+
Parameters
|
|
809
|
+
----------
|
|
810
|
+
vv_def_guid: str
|
|
811
|
+
Unique identifier for the valid value definition.
|
|
812
|
+
body: dict | UpdateElementRequestBody
|
|
813
|
+
A dict representing the details of the valid value definition to update.
|
|
814
|
+
|
|
815
|
+
Returns
|
|
816
|
+
-------
|
|
817
|
+
None
|
|
818
|
+
|
|
819
|
+
Raises
|
|
820
|
+
------
|
|
821
|
+
PyegeriaException
|
|
822
|
+
ValidationError
|
|
823
|
+
|
|
824
|
+
Notes
|
|
825
|
+
_____
|
|
826
|
+
Sample body:
|
|
827
|
+
{
|
|
828
|
+
"class" : "UpdateElementRequestBody",
|
|
829
|
+
"mergeUpdate": true,
|
|
830
|
+
"properties": {
|
|
831
|
+
"class" : "ValidValueDefinitionProperties",
|
|
832
|
+
"qualifiedName": "add unique name here",
|
|
833
|
+
"displayName": "add short name here",
|
|
834
|
+
"description": "add description here",
|
|
835
|
+
"category": "add description here",
|
|
836
|
+
"namespace" : "add namespace here",
|
|
837
|
+
"userDefinedStatus" : "add status here",
|
|
838
|
+
"usage": "add usage here",
|
|
839
|
+
"dataType" : "add data type here",
|
|
840
|
+
"scope" : "add scope here",
|
|
841
|
+
"preferredValue" : "add preferred value here",
|
|
842
|
+
"isCaseSensitive" : false,
|
|
843
|
+
"additionalProperties": {
|
|
844
|
+
"property1" : "propertyValue1",
|
|
845
|
+
"property2" : "propertyValue2"
|
|
846
|
+
},
|
|
847
|
+
"extendedProperties": {
|
|
848
|
+
"property1" : "propertyValue1",
|
|
849
|
+
"property2" : "propertyValue2"
|
|
850
|
+
},
|
|
851
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
852
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
853
|
+
},
|
|
854
|
+
"externalSourceGUID": "add guid here",
|
|
855
|
+
"externalSourceName": "add qualified name here",
|
|
856
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
857
|
+
"forLineage" : false,
|
|
858
|
+
"forDuplicateProcessing" : false
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
"""
|
|
862
|
+
loop = asyncio.get_event_loop()
|
|
863
|
+
loop.run_until_complete(
|
|
864
|
+
self._async_update_valid_value_definition(vv_def_guid, body))
|
|
865
|
+
|
|
866
|
+
@dynamic_catch
|
|
867
|
+
async def _async_link_valid_value_member(self, vv_set_guid:str, vv_member_guid: str, body: dict | NewRelationshipRequestBody):
|
|
868
|
+
""" Link a valid value definition to another valid value definition. Async version.
|
|
869
|
+
|
|
870
|
+
Parameters
|
|
871
|
+
__________
|
|
872
|
+
vv_set_guid: str
|
|
873
|
+
Unique identifier for the valid value definition set in the role of parent.
|
|
874
|
+
vv_member_guid: str
|
|
875
|
+
Unique identifier for the valid value definition member.(Child)
|
|
876
|
+
body: dict | NewRelationshipRequestBody
|
|
877
|
+
A dict representing the details of the relationship.
|
|
878
|
+
|
|
879
|
+
Returns
|
|
880
|
+
______
|
|
881
|
+
None
|
|
882
|
+
|
|
883
|
+
Raises
|
|
884
|
+
______
|
|
885
|
+
PyegeriaException
|
|
886
|
+
ValidationError
|
|
887
|
+
|
|
888
|
+
Notes
|
|
889
|
+
-----
|
|
890
|
+
Sample body:
|
|
891
|
+
{
|
|
892
|
+
"class" : "NewRelationshipRequestBody",
|
|
893
|
+
"externalSourceGUID": "add guid here",
|
|
894
|
+
"externalSourceName": "add qualified name here",
|
|
895
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
896
|
+
"forLineage" : false,
|
|
897
|
+
"forDuplicateProcessing" : false,
|
|
898
|
+
"properties": {
|
|
899
|
+
"class": "ValidValueMemberProperties",
|
|
900
|
+
"isDefaultValue": false,
|
|
901
|
+
"label": "",
|
|
902
|
+
"description": "",
|
|
903
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
904
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
"""
|
|
909
|
+
url = f"{self.ref_data_command_base}/valid-values/{vv_set_guid}/members/{vv_member_guid}/attach"
|
|
910
|
+
await self._async_create_element_body_request(url, ["ValidValueMemberProperties"], body)
|
|
911
|
+
logger.info(f"Linked valid value definition {vv_set_guid} to {vv_member_guid}")
|
|
912
|
+
|
|
913
|
+
@dynamic_catch
|
|
914
|
+
def link_valid_value_definition(
|
|
915
|
+
self,
|
|
916
|
+
vv_set_guid: str, vv_member_guid: str, body: Optional[dict | NewRelationshipRequestBody] = None) -> None:
|
|
917
|
+
""" Link a valid value definition to another valid value definition.
|
|
918
|
+
|
|
919
|
+
Parameters
|
|
920
|
+
__________
|
|
921
|
+
vv_set_guid: str
|
|
922
|
+
Unique identifier for the valid value definition set in the role of parent.
|
|
923
|
+
vv_member_guid: str
|
|
924
|
+
Unique identifier for the valid value definition member.(Child)
|
|
925
|
+
body: dict | NewRelationshipRequestBody
|
|
926
|
+
A dict representing the details of the relationship.
|
|
927
|
+
|
|
928
|
+
Returns
|
|
929
|
+
______
|
|
930
|
+
None
|
|
931
|
+
|
|
932
|
+
Raises
|
|
933
|
+
______
|
|
934
|
+
PyegeriaException
|
|
935
|
+
ValidationError
|
|
936
|
+
|
|
937
|
+
Notes
|
|
938
|
+
-----
|
|
939
|
+
Sample body:
|
|
940
|
+
{
|
|
941
|
+
"class" : "NewRelationshipRequestBody",
|
|
942
|
+
"externalSourceGUID": "add guid here",
|
|
943
|
+
"externalSourceName": "add qualified name here",
|
|
944
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
945
|
+
"forLineage" : false,
|
|
946
|
+
"forDuplicateProcessing" : false,
|
|
947
|
+
"properties": {
|
|
948
|
+
"class": "ValidValueMemberProperties",
|
|
949
|
+
"isDefaultValue": false,
|
|
950
|
+
"label": "",
|
|
951
|
+
"description": "",
|
|
952
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
953
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
"""
|
|
958
|
+
loop = asyncio.get_event_loop()
|
|
959
|
+
loop.run_until_complete(self._async_link_valid_value_member(vv_set_guid, vv_member_guid, body))
|
|
960
|
+
|
|
961
|
+
@dynamic_catch
|
|
962
|
+
async def _async_detach_valid_value_member(self, vv_set_guid: str, vv_member_guid: str,
|
|
963
|
+
body: dict | DeleteRelationshipRequestBody):
|
|
964
|
+
""" Link a valid value definition to another valid value definition. Async version.
|
|
965
|
+
|
|
966
|
+
Parameters
|
|
967
|
+
__________
|
|
968
|
+
vv_set_guid: str
|
|
969
|
+
Unique identifier for the valid value definition set in the role of parent.
|
|
970
|
+
vv_member_guid: str
|
|
971
|
+
Unique identifier for the valid value definition member.(Child)
|
|
972
|
+
body: dict | NewRelationshipRequestBody
|
|
973
|
+
A dict representing the details of the relationship.
|
|
974
|
+
|
|
975
|
+
Returns
|
|
976
|
+
______
|
|
977
|
+
None
|
|
978
|
+
|
|
979
|
+
Raises
|
|
980
|
+
______
|
|
981
|
+
PyegeriaException
|
|
982
|
+
ValidationError
|
|
983
|
+
|
|
984
|
+
Notes
|
|
985
|
+
-----
|
|
986
|
+
Sample body:
|
|
987
|
+
{
|
|
988
|
+
"class" : "NewRelationshipRequestBody",
|
|
989
|
+
"externalSourceGUID": "add guid here",
|
|
990
|
+
"externalSourceName": "add qualified name here",
|
|
991
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
992
|
+
"forLineage" : false,
|
|
993
|
+
"forDuplicateProcessing" : false,
|
|
994
|
+
"properties": {
|
|
995
|
+
"class": "ValidValueMemberProperties",
|
|
996
|
+
"isDefaultValue": false,
|
|
997
|
+
"label": "",
|
|
998
|
+
"description": "",
|
|
999
|
+
"effectiveFrom": "{{$isoTimestamp}}",
|
|
1000
|
+
"effectiveTo": "{{$isoTimestamp}}"
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
"""
|
|
1005
|
+
url = f"{self.ref_data_command_base}/valid-values/{vv_set_guid}/members/{vv_member_guid}/attach"
|
|
1006
|
+
await self._async_create_element_body_request(url, ["ValidValueMemberProperties"], body)
|
|
1007
|
+
logger.info(f"Linked valid value definition {vv_set_guid} to {vv_member_guid}")
|
|
1008
|
+
|
|
1009
|
+
@dynamic_catch
|
|
1010
|
+
def detach_valid_value_definition(
|
|
1011
|
+
self,
|
|
1012
|
+
vv_set_guid: str, vv_member_guid: str, body: Optional[dict | DeleteRelationshipRequestBody] = None) -> None:
|
|
1013
|
+
""" Detach a valid value definition from another valid value definition.
|
|
1014
|
+
|
|
1015
|
+
Parameters
|
|
1016
|
+
__________
|
|
1017
|
+
vv_set_guid: str
|
|
1018
|
+
Unique identifier for the valid value definition set in the role of parent.
|
|
1019
|
+
vv_member_guid: str
|
|
1020
|
+
Unique identifier for the valid value definition member.(Child)
|
|
1021
|
+
body: dict | NewRelationshipRequestBody
|
|
1022
|
+
A dict representing the details of the relationship.
|
|
1023
|
+
|
|
1024
|
+
Returns
|
|
1025
|
+
______
|
|
1026
|
+
None
|
|
1027
|
+
|
|
1028
|
+
Raises
|
|
1029
|
+
______
|
|
1030
|
+
PyegeriaException
|
|
1031
|
+
ValidationError
|
|
1032
|
+
|
|
1033
|
+
Notes
|
|
1034
|
+
-----
|
|
1035
|
+
Sample body:
|
|
1036
|
+
|
|
1037
|
+
{
|
|
1038
|
+
"class": "DeleteRelationshipRequestBody",
|
|
1039
|
+
"deleteMethod": "LOOK_FOR_LINEAGE",
|
|
1040
|
+
"externalSourceGUID": "add guid here",
|
|
1041
|
+
"externalSourceName": "add qualified name here",
|
|
1042
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
|
1043
|
+
"forLineage": false,
|
|
1044
|
+
"forDuplicateProcessing": false
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
"""
|
|
1048
|
+
loop = asyncio.get_event_loop()
|
|
1049
|
+
loop.run_until_complete(self._async_detach_valid_value_member(vv_set_guid, vv_member_guid, body))
|
|
1050
|
+
|
|
1051
|
+
@dynamic_catch
|
|
1052
|
+
async def _async_delete_valid_value_definition(
|
|
1053
|
+
self,
|
|
1054
|
+
vv_def_guid: str, cascade_delete: bool = False, body: Optional[dict | DeleteElementRequestBody] = None) -> None:
|
|
1055
|
+
"""Delete a valid value definition. Async version
|
|
1056
|
+
|
|
1057
|
+
Parameters
|
|
1058
|
+
----------
|
|
1059
|
+
vv_def_guid: str
|
|
1060
|
+
The guid of the valid value definition to delete.
|
|
1061
|
+
cascade_delete: bool, optional, default = False
|
|
1062
|
+
If true, delete all elements anchored to this definition.
|
|
1063
|
+
body: dict | DeleteElementRequestBody, optional
|
|
1064
|
+
A dict representing the details of the valid value definition to delete.
|
|
1065
|
+
|
|
1066
|
+
Returns
|
|
1067
|
+
-------
|
|
1068
|
+
Nothing
|
|
1069
|
+
|
|
1070
|
+
Raises
|
|
1071
|
+
------
|
|
1072
|
+
PyegeriaException
|
|
1073
|
+
ValidationError
|
|
1074
|
+
|
|
1075
|
+
Notes
|
|
1076
|
+
_____
|
|
1077
|
+
Sample body:
|
|
1078
|
+
{
|
|
1079
|
+
"class" : "DeleteElementRequestBody",
|
|
1080
|
+
"cascadeDelete" : false,
|
|
1081
|
+
"externalSourceGUID": "add guid here",
|
|
1082
|
+
"externalSourceName": "add qualified name here",
|
|
1083
|
+
"effectiveTime" : "{{$isoTimestamp}}",
|
|
1084
|
+
"forLineage" : false,
|
|
1085
|
+
"forDuplicateProcessing" : false
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
"""
|
|
1089
|
+
|
|
1090
|
+
url = f"{self.ref_data_command_base}/valid-value-definitions/{vv_def_guid}/delete"
|
|
1091
|
+
|
|
1092
|
+
await self._async_delete_element_request(url, body, cascade_delete)
|
|
1093
|
+
logger.info(f"Deleted valid value definition {vv_def_guid} with cascade {cascade_delete}")
|
|
1094
|
+
|
|
1095
|
+
@dynamic_catch
|
|
1096
|
+
def delete_valid_value_definition(
|
|
1097
|
+
self,
|
|
1098
|
+
vv_def_guid: str, cascade_delete: bool = False, body: Optional[dict | DeleteElementRequestBody] = None) -> None:
|
|
1099
|
+
"""Delete a valid value definition.
|
|
1100
|
+
|
|
1101
|
+
Parameters
|
|
1102
|
+
----------
|
|
1103
|
+
vv_def_guid: str
|
|
1104
|
+
The guid of the valid value definition to delete.
|
|
1105
|
+
cascade_delete: bool, optional, default = False
|
|
1106
|
+
If true, delete all elements anchored to this definition.
|
|
1107
|
+
body: dict | DeleteElementRequestBody, optional
|
|
1108
|
+
A dict representing the details of the valid value definition to delete.
|
|
1109
|
+
|
|
1110
|
+
Returns
|
|
1111
|
+
-------
|
|
1112
|
+
Nothing
|
|
1113
|
+
|
|
1114
|
+
Raises
|
|
1115
|
+
------
|
|
1116
|
+
PyegeriaException
|
|
1117
|
+
ValidationError
|
|
1118
|
+
|
|
1119
|
+
Notes
|
|
1120
|
+
_____
|
|
1121
|
+
Sample body:
|
|
1122
|
+
{
|
|
1123
|
+
"class": "DeleteElementRequestBody",
|
|
1124
|
+
"cascadeDelete": false,
|
|
1125
|
+
"externalSourceGUID": "add guid here",
|
|
1126
|
+
"externalSourceName": "add qualified name here",
|
|
1127
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
|
1128
|
+
"forLineage": false,
|
|
1129
|
+
"forDuplicateProcessing": false
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
"""
|
|
1133
|
+
loop = asyncio.get_event_loop()
|
|
1134
|
+
loop.run_until_complete(self._async_delete_valid_value_definition(vv_def_guid, cascade_delete, body))
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
if __name__ == "__main__":
|
|
1140
|
+
print("Main-Project Manager")
|