pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0__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.
- commands/cat/debug_log +2806 -0
- commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
- commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
- commands/cat/dr_egeria_command_help.py +273 -0
- commands/cat/dr_egeria_md.py +90 -20
- commands/cat/glossary_actions.py +2 -2
- commands/cat/list_collections.py +24 -10
- commands/cat/list_data_designer.py +183 -0
- md_processing/__init__.py +28 -5
- md_processing/data/commands.json +31474 -1096
- md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
- md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
- md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
- md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
- md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
- md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
- md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
- md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
- md_processing/family_docs/Data Designer.md +842 -0
- md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
- md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
- md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
- md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
- md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
- md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
- md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
- md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
- md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
- md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
- md_processing/family_docs/Digital Product Manager.md +668 -0
- md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
- md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
- md_processing/family_docs/Glossary/Create_Category.md +38 -0
- md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
- md_processing/family_docs/Glossary/Create_Term.md +70 -0
- md_processing/family_docs/Glossary.md +206 -0
- md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
- md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
- md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
- md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
- md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
- md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
- md_processing/family_docs/Governance Officer.md +2412 -0
- md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
- md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
- md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
- md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
- md_processing/family_docs/Solution Architect.md +490 -0
- md_processing/md_commands/data_designer_commands.py +1192 -710
- md_processing/md_commands/glossary_commands.py +19 -32
- md_processing/md_commands/governance_officer_commands.py +420 -0
- md_processing/md_commands/product_manager_commands.py +1180 -0
- md_processing/md_commands/project_commands.py +5 -2
- md_processing/md_commands/solution_architect_commands.py +1140 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
- md_processing/md_processing_utils/common_md_utils.py +205 -6
- md_processing/md_processing_utils/debug_log +574 -0
- md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
- md_processing/md_processing_utils/extraction_utils.py +1 -1
- md_processing/md_processing_utils/generate_dr_help.py +165 -0
- md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
- md_processing/md_processing_utils/generate_md_templates.py +92 -0
- md_processing/md_processing_utils/generated_help_terms.md +842 -0
- md_processing/md_processing_utils/md_processing_constants.py +94 -17
- pyegeria/__init__.py +1 -0
- pyegeria/_client.py +39 -1
- pyegeria/classification_manager_omvs.py +1 -1
- pyegeria/collection_manager_omvs.py +4667 -1178
- pyegeria/data_designer_omvs.py +348 -31
- pyegeria/egeria_tech_client.py +9 -25
- pyegeria/glossary_browser_omvs.py +5 -6
- pyegeria/glossary_manager_omvs.py +2 -2
- pyegeria/governance_officer_omvs.py +2367 -0
- pyegeria/output_formatter.py +157 -32
- pyegeria/solution_architect_omvs.py +5063 -1110
- pyegeria/utils.py +22 -2
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
- pyegeria-5.4.0.dist-info/RECORD +243 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
- commands/cat/.DS_Store +0 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
- md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
- md_processing/dr_egeria_inbox/cat_test.md +0 -100
- md_processing/dr_egeria_inbox/data_field.md +0 -54
- md_processing/dr_egeria_inbox/data_spec.md +0 -77
- md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
- md_processing/dr_egeria_inbox/data_test.md +0 -86
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
- md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
- md_processing/dr_egeria_inbox/rel.md +0 -8
- md_processing/dr_egeria_inbox/sb.md +0 -119
- md_processing/dr_egeria_inbox/search_test.md +0 -39
- md_processing/dr_egeria_inbox/solution-components.md +0 -154
- md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
- md_processing/dr_egeria_inbox/synonym_test.md +0 -42
- md_processing/dr_egeria_inbox/t1.md +0 -0
- md_processing/dr_egeria_inbox/t2.md +0 -268
- md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
- md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
- md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
- md_processing/md_commands/blueprint_commands.py +0 -303
- pyegeria/.DS_Store +0 -0
- pyegeria/m_test.py +0 -118
- pyegeria-5.3.9.9.7.dist-info/RECORD +0 -196
- /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -5,13 +5,12 @@ import os
|
|
5
5
|
import sys
|
6
6
|
from typing import List
|
7
7
|
|
8
|
-
from
|
8
|
+
from loguru import logger
|
9
9
|
from rich import print
|
10
|
+
from rich.console import Console
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, print_msg,
|
14
|
-
get_element_dictionary, update_element_dictionary,
|
12
|
+
from md_processing.md_processing_utils.common_md_utils import (get_current_datetime_string, get_element_dictionary,
|
13
|
+
update_element_dictionary,
|
15
14
|
split_tb_string, str_to_bool, )
|
16
15
|
from md_processing.md_processing_utils.extraction_utils import (process_simple_attribute, extract_attribute,
|
17
16
|
get_element_by_name)
|
@@ -20,6 +19,11 @@ from md_processing.md_processing_utils.message_constants import (ERROR, INFO, WA
|
|
20
19
|
from pyegeria import EgeriaTech
|
21
20
|
from pyegeria._globals import DEBUG_LEVEL
|
22
21
|
|
22
|
+
log_format = "P {time} | {level} | {function} | {line} | {message} | {extra}"
|
23
|
+
logger.remove()
|
24
|
+
logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
|
25
|
+
logger.add("debug_log.log", rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
|
26
|
+
colorize=True)
|
23
27
|
# Constants
|
24
28
|
EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "200"))
|
25
29
|
EGERIA_USAGE_LEVEL = os.environ.get("EGERIA_USAGE_LEVEL", "Basic")
|
@@ -29,6 +33,7 @@ debug_level = DEBUG_LEVEL
|
|
29
33
|
global COMMAND_DEFINITIONS
|
30
34
|
|
31
35
|
|
36
|
+
@logger.catch
|
32
37
|
def process_provenance_command(file_path: str, txt: [str]) -> str:
|
33
38
|
"""
|
34
39
|
Processes a provenance object_action by extracting the file path and current datetime.
|
@@ -46,7 +51,8 @@ def process_provenance_command(file_path: str, txt: [str]) -> str:
|
|
46
51
|
return provenance
|
47
52
|
|
48
53
|
|
49
|
-
|
54
|
+
@logger.catch
|
55
|
+
def parse_upsert_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
|
50
56
|
directive: str = "display") -> dict:
|
51
57
|
parsed_attributes, parsed_output = {}, {}
|
52
58
|
|
@@ -56,7 +62,7 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
56
62
|
display_name = ""
|
57
63
|
labels = {}
|
58
64
|
|
59
|
-
command_spec = get_command_spec(object_type)
|
65
|
+
command_spec = get_command_spec(f"Create {object_type}")
|
60
66
|
attributes = command_spec.get('Attributes', [])
|
61
67
|
command_display_name = command_spec.get('display_name', None)
|
62
68
|
command_qn_prefix = command_spec.get('qn_prefix', None)
|
@@ -69,7 +75,7 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
69
75
|
parsed_output['reason'] = ""
|
70
76
|
|
71
77
|
msg = f"\tProcessing {object_action} on a {object_type} \n"
|
72
|
-
|
78
|
+
logger.info(msg)
|
73
79
|
|
74
80
|
# get the version early because we may need it to construct qualified names.
|
75
81
|
version = process_simple_attribute(txt, {'Version', "Version Identifier", "Published Version"}, INFO)
|
@@ -81,29 +87,32 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
81
87
|
for_update = attr[key].get('inUpdate', True)
|
82
88
|
level = attr[key].get('level', 'Basic')
|
83
89
|
msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
|
84
|
-
|
85
|
-
|
90
|
+
f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` and attribute level `{level}` and for_update `"
|
91
|
+
f"{for_update}`\n")
|
92
|
+
logger.trace(msg)
|
86
93
|
if for_update is False and object_action == "Update":
|
87
|
-
|
94
|
+
logger.trace(f"Attribute `{key}`is not allowed for `Update`", highlight=True)
|
88
95
|
continue
|
89
96
|
if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
|
90
|
-
|
97
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
98
|
+
highlight=True)
|
91
99
|
continue
|
92
|
-
if EGERIA_USAGE_LEVEL == "Advanced" and level in [
|
93
|
-
|
100
|
+
if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
|
101
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
102
|
+
highlight=True)
|
94
103
|
continue
|
95
104
|
if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
|
96
|
-
|
105
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
106
|
+
highlight=True)
|
97
107
|
continue
|
98
108
|
|
99
|
-
|
100
109
|
if attr[key].get('input_required', False) is True:
|
101
110
|
if_missing = ERROR
|
102
111
|
else:
|
103
112
|
if_missing = INFO
|
104
113
|
|
105
114
|
# lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
|
106
|
-
lab =split_tb_string(attr[key]['attr_labels']
|
115
|
+
lab = split_tb_string(attr[key]['attr_labels'])
|
107
116
|
labels: set = set()
|
108
117
|
labels.add(key.strip())
|
109
118
|
if key == 'Display Name':
|
@@ -111,7 +120,6 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
111
120
|
if lab is not None and lab != [""]:
|
112
121
|
labels.update(lab)
|
113
122
|
|
114
|
-
|
115
123
|
default_value = attr[key].get('default_value', None)
|
116
124
|
|
117
125
|
style = attr[key]['style']
|
@@ -124,7 +132,8 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
124
132
|
elif style == 'QN':
|
125
133
|
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
126
134
|
object_action, version, if_missing)
|
127
|
-
if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
|
135
|
+
if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
|
136
|
+
'exists'] is False:
|
128
137
|
parsed_output['exists'] = False
|
129
138
|
elif style == 'ID':
|
130
139
|
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
@@ -139,19 +148,22 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
139
148
|
|
140
149
|
elif style == 'Reference Name':
|
141
150
|
parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
|
142
|
-
if ((if_missing==ERROR) and parsed_attributes[key].get("value", None) and
|
143
|
-
|
151
|
+
if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) and parsed_attributes[key][
|
152
|
+
'exists'] is False):
|
144
153
|
msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
|
145
|
-
|
154
|
+
logger.error(msg)
|
146
155
|
parsed_output['valid'] = False
|
147
156
|
parsed_output['reason'] += msg
|
157
|
+
elif parsed_attributes[key]['valid'] is False:
|
158
|
+
parsed_output['valid'] = False
|
159
|
+
parsed_output['reason'] += parsed_attributes[key]['reason']
|
148
160
|
|
149
161
|
elif style == 'GUID':
|
150
162
|
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
151
163
|
elif style == 'Ordered Int':
|
152
164
|
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
153
165
|
elif style == 'Simple Int':
|
154
|
-
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
166
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
|
155
167
|
elif style == 'Simple List':
|
156
168
|
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
157
169
|
name_list = parsed_attributes[key]['value']
|
@@ -167,65 +179,239 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
167
179
|
|
168
180
|
elif style == 'Reference Name List':
|
169
181
|
parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
|
170
|
-
|
182
|
+
if (parsed_attributes[key].get("value", None) and (
|
183
|
+
parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
|
184
|
+
msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
|
185
|
+
f"does not exist")
|
186
|
+
logger.error(msg)
|
187
|
+
parsed_output['valid'] = False
|
188
|
+
parsed_output['reason'] += msg
|
171
189
|
else:
|
172
|
-
msg = f"Unknown attribute style: {style}"
|
173
|
-
|
190
|
+
msg = f"Unknown attribute style: {style} for key `{key}`"
|
191
|
+
logger.error(msg)
|
174
192
|
sys.exit(1)
|
175
193
|
parsed_attributes[key]['valid'] = False
|
176
194
|
parsed_attributes[key]['value'] = None
|
177
195
|
if key == "Display Name":
|
178
196
|
display_name = parsed_attributes[key]['value']
|
179
197
|
|
180
|
-
|
181
|
-
|
182
|
-
value = parsed_attributes[key].get('value',None)
|
198
|
+
value = parsed_attributes[key].get('value', None)
|
183
199
|
|
184
200
|
if value is not None:
|
185
201
|
# if the value is a dict, get the flattened name list
|
186
|
-
value = parsed_attributes[key].get('name_list', None) if isinstance(value,(dict, list)) else value
|
187
|
-
|
202
|
+
value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
|
188
203
|
parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
|
189
204
|
|
190
205
|
|
206
|
+
parsed_output['attributes'] = parsed_attributes
|
207
|
+
|
208
|
+
if display_name is None:
|
209
|
+
msg = f"No display name or name identifier found"
|
210
|
+
logger.error(msg)
|
211
|
+
parsed_output['valid'] = False
|
212
|
+
parsed_output['reason'] = msg
|
213
|
+
return parsed_output
|
214
|
+
|
215
|
+
|
191
216
|
if parsed_attributes.get('Parent ID', {}).get('value', None) is not None:
|
192
217
|
if (parsed_attributes['Parent Relationship Type Name']['value'] is None) or (
|
193
218
|
parsed_attributes['Parent at End1']['value'] is None):
|
194
219
|
msg = "Parent ID was found but either Parent `Relationship Type Name` or `Parent at End1` are missing"
|
195
|
-
|
220
|
+
logger.error(msg)
|
196
221
|
parsed_output['valid'] = False
|
197
222
|
parsed_output['reason'] = msg
|
198
223
|
if parsed_attributes['Parent Relationship Type Name'].get('exists', False) is False:
|
199
224
|
msg = "Parent ID was found but does not exist"
|
200
|
-
|
225
|
+
logger.error(msg)
|
201
226
|
parsed_output['valid'] = False
|
202
227
|
parsed_output['reason'] = msg
|
203
228
|
|
204
229
|
if directive in ["validate", "process"] and object_action == "Update" and not parsed_output[
|
205
230
|
'exists']: # check to see if provided information exists and is consistent with existing info
|
206
|
-
msg = f"Update request invalid,
|
207
|
-
|
231
|
+
msg = f"Update request invalid, element `{display_name}` does not exist\n"
|
232
|
+
logger.error(msg)
|
208
233
|
parsed_output['valid'] = False
|
209
234
|
if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
|
210
235
|
msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
|
211
|
-
|
236
|
+
logger.error(msg)
|
212
237
|
|
213
238
|
elif directive in ["validate",
|
214
239
|
"process"] and object_action == 'Create': # if the object_action is create, check that it
|
215
240
|
# doesn't already exist
|
216
241
|
if parsed_output['exists']:
|
217
242
|
msg = f"Element `{display_name}` cannot be created since it already exists\n"
|
218
|
-
|
243
|
+
logger.error(msg)
|
219
244
|
parsed_output['valid'] = False
|
220
245
|
else:
|
221
|
-
msg = f"
|
222
|
-
|
246
|
+
msg = f"Element `{display_name}` does not exist so it can be created\n"
|
247
|
+
logger.info(msg)
|
248
|
+
|
249
|
+
|
250
|
+
if parsed_output.get('qualified_name',None) and "* Qualified Name" not in parsed_output['display']:
|
251
|
+
parsed_output['display'] += f"\n\t* Qualified Name: `{parsed_output['qualified_name']}`\n\t"
|
252
|
+
if parsed_output.get('guid',None):
|
253
|
+
parsed_output['display'] += f"\n\t* GUID: `{parsed_output['guid']}`\n\t"
|
254
|
+
|
255
|
+
return parsed_output
|
256
|
+
|
257
|
+
|
258
|
+
@logger.catch
|
259
|
+
def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
|
260
|
+
directive: str = "display") -> dict:
|
261
|
+
parsed_attributes, parsed_output = {}, {}
|
262
|
+
|
263
|
+
parsed_output['valid'] = True
|
264
|
+
parsed_output['exists'] = False
|
265
|
+
|
266
|
+
labels = {}
|
267
|
+
if object_action in ["Unlink","Detach"]:
|
268
|
+
command_spec = get_command_spec(f"Link {object_type}")
|
269
|
+
else:
|
270
|
+
command_spec = get_command_spec(f"{object_action} {object_type}")
|
271
|
+
attributes = command_spec.get('Attributes', [])
|
272
|
+
command_display_name = command_spec.get('display_name', None)
|
273
|
+
|
274
|
+
parsed_output['reason'] = ""
|
275
|
+
parsed_output['display'] = ""
|
276
|
+
|
277
|
+
msg = f"\tProcessing {object_action} on {object_type} \n"
|
278
|
+
logger.info(msg)
|
279
|
+
|
280
|
+
# get the version early because we may need it to construct qualified names.
|
281
|
+
|
282
|
+
for attr in attributes:
|
283
|
+
for key in attr:
|
284
|
+
# Run some checks to see if the attribute is appropriate to the operation and usage level
|
285
|
+
|
286
|
+
level = attr[key].get('level', 'Basic')
|
287
|
+
msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
|
288
|
+
f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` ")
|
289
|
+
logger.trace(msg)
|
290
|
+
|
291
|
+
if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
|
292
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
293
|
+
highlight=True)
|
294
|
+
continue
|
295
|
+
if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
|
296
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
297
|
+
highlight=True)
|
298
|
+
continue
|
299
|
+
if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
|
300
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
301
|
+
highlight=True)
|
302
|
+
continue
|
303
|
+
|
304
|
+
if attr[key].get('input_required', False) is True:
|
305
|
+
if_missing = ERROR
|
306
|
+
else:
|
307
|
+
if_missing = INFO
|
308
|
+
|
309
|
+
# lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
|
310
|
+
lab = split_tb_string(attr[key]['attr_labels'])
|
311
|
+
labels: set = set()
|
312
|
+
labels.add(key.strip())
|
313
|
+
|
314
|
+
if lab is not None and lab != [""]:
|
315
|
+
labels.update(lab)
|
316
|
+
|
317
|
+
# set these to none since not needed for view commands
|
318
|
+
version = None
|
319
|
+
command_qn_prefix = None
|
320
|
+
|
321
|
+
default_value = attr[key].get('default_value', None)
|
322
|
+
|
323
|
+
style = attr[key]['style']
|
324
|
+
if style in ['Simple', 'Dictionary', 'Comment']:
|
325
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
326
|
+
elif style == 'Valid Value':
|
327
|
+
parsed_attributes[key] = proc_valid_value(txt, object_action, labels,
|
328
|
+
attr[key].get('valid_values', None), if_missing,
|
329
|
+
default_value)
|
330
|
+
elif style == 'QN':
|
331
|
+
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
332
|
+
object_action, version, if_missing)
|
333
|
+
if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
|
334
|
+
'exists'] is False:
|
335
|
+
parsed_output['exists'] = False
|
336
|
+
elif style == 'ID':
|
337
|
+
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
338
|
+
object_action, version, if_missing)
|
339
|
+
|
340
|
+
parsed_output['guid'] = parsed_attributes[key].get('guid', None)
|
341
|
+
parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
|
342
|
+
parsed_output['exists'] = parsed_attributes[key]['exists']
|
343
|
+
if parsed_attributes[key]['valid'] is False:
|
344
|
+
parsed_output['valid'] = False
|
345
|
+
parsed_output['reason'] += parsed_attributes[key]['reason']
|
346
|
+
|
347
|
+
elif style == 'Reference Name':
|
348
|
+
parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
|
349
|
+
if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) is None):
|
350
|
+
msg = f"Required parameter `{parsed_attributes[key]['value']}` is missing"
|
351
|
+
logger.error(msg)
|
352
|
+
parsed_output['valid'] = False
|
353
|
+
parsed_output['reason'] += msg
|
354
|
+
elif parsed_attributes[key]['value'] and parsed_attributes[key]['exists'] is False:
|
355
|
+
msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
|
356
|
+
logger.error(msg)
|
357
|
+
parsed_output['valid'] = False
|
358
|
+
parsed_output['reason'] += msg
|
359
|
+
|
360
|
+
elif style == 'GUID':
|
361
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
362
|
+
elif style == 'Ordered Int':
|
363
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
364
|
+
elif style == 'Simple Int':
|
365
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value, "int")
|
366
|
+
elif style == 'Simple List':
|
367
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
368
|
+
name_list = parsed_attributes[key]['value']
|
369
|
+
# attribute = re.split(r'[;,\n]+', name_list) if name_list is not None else None
|
370
|
+
attribute = split_tb_string(name_list)
|
371
|
+
parsed_attributes[key]['value'] = attribute
|
372
|
+
parsed_attributes[key]['name_list'] = name_list
|
373
|
+
elif style == 'Parent':
|
374
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
375
|
+
elif style == 'Bool':
|
376
|
+
parsed_attributes[key] = proc_bool_attribute(txt, object_action, labels, if_missing, default_value)
|
377
|
+
|
378
|
+
elif style == 'Reference Name List':
|
379
|
+
parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
|
380
|
+
if (parsed_attributes[key].get("value", None) and (
|
381
|
+
parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
|
382
|
+
msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
|
383
|
+
f"does not exist")
|
384
|
+
logger.error(msg)
|
385
|
+
parsed_output['valid'] = False
|
386
|
+
parsed_output['reason'] += msg
|
387
|
+
else:
|
388
|
+
msg = f"Unknown attribute style: {style}"
|
389
|
+
logger.error(msg)
|
390
|
+
sys.exit(1)
|
391
|
+
parsed_attributes[key]['valid'] = False
|
392
|
+
parsed_attributes[key]['value'] = None
|
393
|
+
|
394
|
+
value = parsed_attributes[key].get('value', None)
|
395
|
+
|
396
|
+
if value is not None:
|
397
|
+
# if the value is a dict, get the flattened name list
|
398
|
+
value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
|
399
|
+
parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
|
223
400
|
|
224
401
|
parsed_output['attributes'] = parsed_attributes
|
402
|
+
|
403
|
+
|
404
|
+
if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
|
405
|
+
msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
|
406
|
+
logger.error(msg)
|
407
|
+
|
408
|
+
|
225
409
|
return parsed_output
|
226
410
|
|
227
411
|
|
228
|
-
|
412
|
+
@logger.catch
|
413
|
+
def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None,
|
414
|
+
simp_type: str = None) -> dict:
|
229
415
|
"""Process a simple attribute based on the provided labels and if_missing value.
|
230
416
|
Extract the attribute value from the text and store it in a dictionary along with valid.
|
231
417
|
If it doesn`t exist, mark the dictionary entry as invalid and print an error message with severity of if_missing.
|
@@ -245,27 +431,34 @@ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str =
|
|
245
431
|
|
246
432
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
247
433
|
msg = "Invalid severity for missing attribute"
|
248
|
-
|
434
|
+
logger.error(msg)
|
249
435
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
250
436
|
|
251
|
-
attribute = extract_attribute(txt, labels)
|
252
437
|
if default_value == "":
|
253
438
|
default_value = None
|
254
|
-
attribute = default_value if attribute is None else attribute
|
255
439
|
|
256
|
-
|
440
|
+
attribute = extract_attribute(txt, labels)
|
441
|
+
|
442
|
+
attribute = default_value if attribute is None else attribute.replace('\n', '')
|
257
443
|
|
444
|
+
if attribute is None:
|
258
445
|
if if_missing == INFO or if_missing == WARNING:
|
259
446
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
260
447
|
valid = True
|
448
|
+
logger.info(msg)
|
261
449
|
else:
|
262
450
|
msg = f"Missing attribute with labels `{labels}` "
|
263
451
|
valid = False
|
264
|
-
|
452
|
+
logger.error(msg)
|
265
453
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
454
|
+
|
455
|
+
if attribute and simp_type == "int" :
|
456
|
+
attribute = int(attribute)
|
457
|
+
|
266
458
|
return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
|
267
459
|
|
268
460
|
|
461
|
+
@logger.catch
|
269
462
|
def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_missing: str = INFO,
|
270
463
|
default_value=None) -> dict:
|
271
464
|
"""Process a string attribute to check that it is a member of the associated value values list.
|
@@ -288,22 +481,22 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
|
|
288
481
|
|
289
482
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
290
483
|
msg = "Invalid severity for missing attribute"
|
291
|
-
|
484
|
+
logger.error(msg)
|
292
485
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
293
486
|
if valid_values is None:
|
294
487
|
msg = "Missing valid values list"
|
295
|
-
|
488
|
+
logger.error(msg)
|
296
489
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
297
490
|
if isinstance(valid_values, str):
|
298
491
|
# v_values = [item.strip() for item in re.split(r'[;,\n]+', valid_values)]
|
299
492
|
v_values = split_tb_string(valid_values)
|
300
493
|
if not isinstance(v_values, list):
|
301
494
|
msg = "Valid values list is not a list"
|
302
|
-
|
495
|
+
logger.error(msg)
|
303
496
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
304
497
|
if len(v_values) == 0:
|
305
498
|
msg = "Valid values list is empty"
|
306
|
-
|
499
|
+
logger.error(msg)
|
307
500
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
308
501
|
|
309
502
|
attribute = extract_attribute(txt, labels)
|
@@ -314,21 +507,23 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
|
|
314
507
|
if attribute is None:
|
315
508
|
if if_missing == INFO or if_missing == WARNING:
|
316
509
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
510
|
+
logger.info(msg)
|
317
511
|
valid = True
|
318
512
|
else:
|
319
513
|
msg = f"Missing attribute with labels `{labels}` "
|
320
514
|
valid = False
|
321
|
-
|
515
|
+
logger.error(msg)
|
322
516
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
323
517
|
else:
|
324
518
|
if attribute not in v_values:
|
325
519
|
msg = f"Invalid value for attribute `{labels}`"
|
326
|
-
|
520
|
+
logger.warning(msg)
|
327
521
|
return {"status": WARNING, "reason": msg, "value": attribute, "valid": False, "exists": True}
|
328
522
|
|
329
523
|
return {"status": INFO, "OK": "OK", "value": attribute, "valid": valid, "exists": True}
|
330
524
|
|
331
525
|
|
526
|
+
@logger.catch
|
332
527
|
def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None) -> dict:
|
333
528
|
"""Process a boolean attribute based on the provided labels and if_missing value.
|
334
529
|
Extract the attribute value from the text and store it in a dictionary along with valid.
|
@@ -349,7 +544,7 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
349
544
|
|
350
545
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
351
546
|
msg = "Invalid severity for missing attribute"
|
352
|
-
|
547
|
+
logger.error(msg)
|
353
548
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
354
549
|
|
355
550
|
attribute = extract_attribute(txt, labels)
|
@@ -362,11 +557,12 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
362
557
|
if attribute is None:
|
363
558
|
if if_missing == INFO or if_missing == WARNING:
|
364
559
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
560
|
+
logger.info(msg)
|
365
561
|
valid = True
|
366
562
|
else:
|
367
563
|
msg = f"Missing attribute with labels `{labels}` "
|
368
564
|
valid = False
|
369
|
-
|
565
|
+
logger.error(msg)
|
370
566
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
371
567
|
|
372
568
|
if isinstance(attribute, str):
|
@@ -377,12 +573,13 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
377
573
|
attribute = False
|
378
574
|
else:
|
379
575
|
msg = f"Invalid value for boolean attribute `{labels}`"
|
380
|
-
|
576
|
+
logger.error(msg)
|
381
577
|
return {"status": ERROR, "reason": msg, "value": attribute, "valid": False, "exists": True}
|
382
578
|
|
383
579
|
return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
|
384
580
|
|
385
581
|
|
582
|
+
@logger.catch
|
386
583
|
def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, element_labels: list[str], txt: str,
|
387
584
|
action: str, version: str = None, if_missing: str = INFO) -> dict:
|
388
585
|
"""
|
@@ -422,7 +619,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
422
619
|
|
423
620
|
if element_name is None:
|
424
621
|
msg = f"Optional attribute with label`{element_type}` missing"
|
425
|
-
|
622
|
+
logger.info(msg)
|
426
623
|
identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": False, "exists": False, }
|
427
624
|
return identifier_output
|
428
625
|
|
@@ -436,18 +633,18 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
436
633
|
|
437
634
|
if unique is False:
|
438
635
|
msg = f"Multiple elements named {element_name} found"
|
439
|
-
|
636
|
+
logger.error(msg)
|
440
637
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
|
441
638
|
valid = False
|
442
639
|
|
443
640
|
if action == "Update" and not exists:
|
444
641
|
msg = f"Element {element_name} does not exist"
|
445
|
-
|
642
|
+
logger.error(msg)
|
446
643
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
|
447
644
|
|
448
|
-
elif action
|
645
|
+
elif action in ["Update", "View"] and exists:
|
449
646
|
msg = f"Element {element_name} exists"
|
450
|
-
|
647
|
+
logger.info(msg)
|
451
648
|
identifier_output = {
|
452
649
|
"status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
|
453
650
|
'qualified_name': q_name, 'guid': guid
|
@@ -455,7 +652,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
455
652
|
|
456
653
|
elif action == "Create" and exists:
|
457
654
|
msg = f"Element {element_name} already exists"
|
458
|
-
|
655
|
+
logger.error(msg)
|
459
656
|
identifier_output = {
|
460
657
|
"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True,
|
461
658
|
'qualified_name': qualified_name, 'guid': guid,
|
@@ -463,7 +660,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
463
660
|
|
464
661
|
elif action == "Create" and not exists and valid:
|
465
662
|
msg = f"{element_type} `{element_name}` does not exist"
|
466
|
-
|
663
|
+
logger.info(msg)
|
467
664
|
|
468
665
|
if q_name is None and qualified_name is None:
|
469
666
|
q_name = egeria_client.__create_qualified_name__(qn_prefix, element_name, version_identifier=version)
|
@@ -481,11 +678,13 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
481
678
|
return identifier_output
|
482
679
|
|
483
680
|
|
681
|
+
@logger.catch
|
484
682
|
def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set, txt: str, action: str,
|
485
683
|
if_missing: str = INFO, version: str = None) -> dict:
|
486
684
|
"""
|
487
685
|
Processes element identifiers from the input text using the labels supplied,
|
488
686
|
checking if the element exists in Egeria, and validating the information.
|
687
|
+
Only a single element is allowed.
|
489
688
|
|
490
689
|
Parameters
|
491
690
|
----------
|
@@ -519,7 +718,12 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
|
|
519
718
|
value = None
|
520
719
|
|
521
720
|
element_name = extract_attribute(txt, element_labels)
|
721
|
+
|
522
722
|
if element_name:
|
723
|
+
if '\n' in element_name or ',' in element_name:
|
724
|
+
msg = f"Element name `{element_name}` appears to be a list rather than a single element"
|
725
|
+
logger.error(msg)
|
726
|
+
return {"status": ERROR, "reason": msg, "value": None, "valid": False, "exists": False, }
|
523
727
|
q_name, guid, unique, exists = get_element_by_name(egeria_client, element_type, element_name)
|
524
728
|
value = element_name
|
525
729
|
else:
|
@@ -530,30 +734,30 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
|
|
530
734
|
if exists is True and unique is False:
|
531
735
|
# Multiple elements found - so need to respecify with qualified name
|
532
736
|
msg = f"Multiple elements named {element_name} found"
|
533
|
-
|
737
|
+
logger.error(msg)
|
534
738
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
|
535
739
|
|
536
740
|
|
537
741
|
elif action == EXISTS_REQUIRED or if_missing == ERROR and not exists:
|
538
742
|
# a required identifier doesn't exist
|
539
743
|
msg = f"Required {element_type} `{element_name}` does not exist"
|
540
|
-
|
744
|
+
logger.error(msg)
|
541
745
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
|
542
|
-
elif value is None
|
746
|
+
elif value is None and if_missing == INFO:
|
543
747
|
# an optional identifier is empty
|
544
748
|
msg = f"Optional attribute with label`{element_type}` missing"
|
545
|
-
|
749
|
+
logger.info(msg)
|
546
750
|
identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": True, "exists": False, }
|
547
751
|
elif value and exists is False:
|
548
752
|
# optional identifier specified but doesn't exist
|
549
753
|
msg = f"Optional attribute with label`{element_type}` specified but doesn't exist"
|
550
|
-
|
754
|
+
logger.error(msg)
|
551
755
|
identifier_output = {"status": ERROR, "reason": msg, "value": value, "valid": False, "exists": False, }
|
552
756
|
|
553
757
|
else:
|
554
758
|
# all good.
|
555
759
|
msg = f"Element {element_type} `{element_name}` exists"
|
556
|
-
|
760
|
+
logger.info(msg)
|
557
761
|
identifier_output = {
|
558
762
|
"status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
|
559
763
|
"qualified_name": q_name, 'guid': guid
|
@@ -562,6 +766,7 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
|
|
562
766
|
return identifier_output
|
563
767
|
|
564
768
|
|
769
|
+
@logger.catch
|
565
770
|
def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, element_labels: set,
|
566
771
|
if_missing: str = INFO) -> dict:
|
567
772
|
"""
|
@@ -595,12 +800,12 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
595
800
|
id_list_output = {}
|
596
801
|
elements = ""
|
597
802
|
new_element_list = []
|
598
|
-
|
803
|
+
guid_list = []
|
599
804
|
elements_txt = extract_attribute(txt, element_labels)
|
600
805
|
|
601
806
|
if elements_txt is None:
|
602
807
|
msg = f"Attribute with labels `{{element_type}}` missing"
|
603
|
-
|
808
|
+
logger.debug(msg)
|
604
809
|
return {"status": if_missing, "reason": msg, "value": None, "valid": False, "exists": False, }
|
605
810
|
else:
|
606
811
|
# element_list = re.split(r'[;,\n]+', elements_txt)
|
@@ -610,13 +815,14 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
610
815
|
# Get the element using the generalized function
|
611
816
|
known_q_name, known_guid, el_valid, el_exists = get_element_by_name(egeria_client, element_type, element)
|
612
817
|
details = {"known_q_name": known_q_name, "known_guid": known_guid, "el_valid": el_valid}
|
613
|
-
elements
|
818
|
+
elements += element + ", " # list of the input names
|
614
819
|
|
615
820
|
if el_exists and el_valid:
|
616
821
|
new_element_list.append(known_q_name) # list of qualified names
|
822
|
+
guid_list.append(known_guid)
|
617
823
|
elif not el_exists:
|
618
824
|
msg = f"No {element_type} `{element}` found"
|
619
|
-
|
825
|
+
logger.debug(msg)
|
620
826
|
valid = False
|
621
827
|
valid = valid if el_valid is None else (valid and el_valid)
|
622
828
|
exists = exists and el_exists
|
@@ -624,19 +830,22 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
624
830
|
|
625
831
|
if elements:
|
626
832
|
msg = f"Found {element_type}: {elements}"
|
627
|
-
|
833
|
+
logger.debug(msg)
|
628
834
|
id_list_output = {
|
629
835
|
"status": INFO, "reason": msg, "value": element_details, "valid": valid, "exists": exists,
|
630
|
-
"name_list": new_element_list,
|
836
|
+
"name_list": new_element_list, "guid_list": guid_list,
|
631
837
|
}
|
632
838
|
else:
|
633
839
|
msg = f" Name list contains one or more invalid qualified names."
|
634
|
-
|
635
|
-
id_list_output = {
|
636
|
-
|
840
|
+
logger.debug(msg)
|
841
|
+
id_list_output = {
|
842
|
+
"status": if_missing, "reason": msg, "value": elements, "valid": valid, "exists": exists,
|
843
|
+
"dict_list": element_details, "guid_list": guid_list
|
844
|
+
}
|
637
845
|
return id_list_output
|
638
846
|
|
639
847
|
|
848
|
+
@logger.catch
|
640
849
|
def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories_exist: bool,
|
641
850
|
categories_list: List[str]) -> None:
|
642
851
|
"""
|
@@ -689,36 +898,19 @@ def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories
|
|
689
898
|
egeria_client.add_term_to_category(term_guid, cat)
|
690
899
|
current_categories.append(cat)
|
691
900
|
msg = f"Added term {term_guid} to category {cat}"
|
692
|
-
|
901
|
+
logger.info(msg)
|
693
902
|
|
694
903
|
for cat in current_categories:
|
695
904
|
if cat not in to_be_cat_guids:
|
696
905
|
egeria_client.remove_term_from_category(term_guid, cat)
|
697
906
|
msg = f"Removed term {term_guid} from category {cat}"
|
698
|
-
|
907
|
+
logger.info(msg)
|
699
908
|
else: # No categories specified - so remove any categories a term is in
|
700
909
|
for cat in current_categories:
|
701
910
|
egeria_client.remove_term_from_category(term_guid, cat)
|
702
911
|
msg = f"Removed term {term_guid} from category {cat}"
|
703
|
-
|
704
|
-
|
705
|
-
def sync_data_dict_membership(egeria_client: EgeriaTech, in_data_dictionary_names: list , in_data_dictionary: dict,
|
706
|
-
guid:str, object_type:str)->dict:
|
707
|
-
pass
|
708
|
-
|
709
|
-
def sync_data_structure_membership(egeria_client: EgeriaTech, in_data_structure_names: list , in_data_structure: dict,
|
710
|
-
guid:str, object_type:str)->dict:
|
912
|
+
logger.info(msg)
|
711
913
|
|
712
|
-
pass
|
713
914
|
|
714
|
-
def sync_data_spec_membership(egeria_client: EgeriaTech, in_data_spec_names: list , in_data_spec: dict,
|
715
|
-
guid:str, object_type:str)->dict:
|
716
|
-
pass
|
717
915
|
|
718
|
-
def sync_term_links(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
|
719
|
-
links_list: List[str]) -> None:
|
720
|
-
pass
|
721
916
|
|
722
|
-
def sync_parent_data_field(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
|
723
|
-
links_list: List[str]) -> None:
|
724
|
-
pass
|