pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0.dev2__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.2025-06-05_20-24-18_123924.log.zip +0 -0
- commands/cat/debug_log.2025-06-10_08-45-03_929921.log.zip +0 -0
- commands/cat/debug_log.2025-06-11_09-57-21_247890.log.zip +0 -0
- commands/cat/debug_log.2025-06-12_16-14-31_212042.log.zip +0 -0
- commands/cat/dr_egeria_md.py +32 -5
- commands/cat/list_collections.py +10 -4
- commands/cat/list_data_designer.py +171 -0
- md_processing/__init__.py +7 -2
- md_processing/data/commands.json +4666 -848
- md_processing/md_commands/data_designer_commands.py +840 -557
- md_processing/md_commands/solution_architect_commands.py +985 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +262 -89
- md_processing/md_processing_utils/common_md_utils.py +11 -4
- md_processing/md_processing_utils/md_processing_constants.py +18 -16
- pyegeria/_client.py +39 -0
- pyegeria/classification_manager_omvs.py +1 -1
- pyegeria/collection_manager_omvs.py +248 -188
- pyegeria/data_designer_omvs.py +217 -9
- pyegeria/governance_officer_omvs.py +2349 -0
- pyegeria/output_formatter.py +24 -12
- pyegeria/solution_architect_omvs.py +4219 -1084
- pyegeria/utils.py +15 -2
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/METADATA +2 -1
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/RECORD +27 -62
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/entry_points.txt +3 -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-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.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="SUCCESS", 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
|
|
@@ -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,10 +148,10 @@ 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
|
148
157
|
|
@@ -167,64 +176,232 @@ def parse_user_command(egeria_client: EgeriaTech, object_type: str, object_actio
|
|
167
176
|
|
168
177
|
elif style == 'Reference Name List':
|
169
178
|
parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
|
170
|
-
|
179
|
+
if (parsed_attributes[key].get("value", None) and (
|
180
|
+
parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
|
181
|
+
msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
|
182
|
+
f"does not exist")
|
183
|
+
logger.error(msg)
|
184
|
+
parsed_output['valid'] = False
|
185
|
+
parsed_output['reason'] += msg
|
171
186
|
else:
|
172
187
|
msg = f"Unknown attribute style: {style}"
|
173
|
-
|
188
|
+
logger.error(msg)
|
174
189
|
sys.exit(1)
|
175
190
|
parsed_attributes[key]['valid'] = False
|
176
191
|
parsed_attributes[key]['value'] = None
|
177
192
|
if key == "Display Name":
|
178
193
|
display_name = parsed_attributes[key]['value']
|
179
194
|
|
180
|
-
|
181
|
-
|
182
|
-
value = parsed_attributes[key].get('value',None)
|
195
|
+
value = parsed_attributes[key].get('value', None)
|
183
196
|
|
184
197
|
if value is not None:
|
185
198
|
# 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
|
-
|
199
|
+
value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
|
188
200
|
parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
|
189
201
|
|
190
202
|
|
203
|
+
parsed_output['attributes'] = parsed_attributes
|
204
|
+
|
205
|
+
if display_name is None:
|
206
|
+
msg = f"No display name or name identifier found"
|
207
|
+
logger.error(msg)
|
208
|
+
parsed_output['valid'] = False
|
209
|
+
parsed_output['reason'] = msg
|
210
|
+
return parsed_output
|
211
|
+
|
212
|
+
|
191
213
|
if parsed_attributes.get('Parent ID', {}).get('value', None) is not None:
|
192
214
|
if (parsed_attributes['Parent Relationship Type Name']['value'] is None) or (
|
193
215
|
parsed_attributes['Parent at End1']['value'] is None):
|
194
216
|
msg = "Parent ID was found but either Parent `Relationship Type Name` or `Parent at End1` are missing"
|
195
|
-
|
217
|
+
logger.error(msg)
|
196
218
|
parsed_output['valid'] = False
|
197
219
|
parsed_output['reason'] = msg
|
198
220
|
if parsed_attributes['Parent Relationship Type Name'].get('exists', False) is False:
|
199
221
|
msg = "Parent ID was found but does not exist"
|
200
|
-
|
222
|
+
logger.error(msg)
|
201
223
|
parsed_output['valid'] = False
|
202
224
|
parsed_output['reason'] = msg
|
203
225
|
|
204
226
|
if directive in ["validate", "process"] and object_action == "Update" and not parsed_output[
|
205
227
|
'exists']: # check to see if provided information exists and is consistent with existing info
|
206
|
-
msg = f"Update request invalid,
|
207
|
-
|
228
|
+
msg = f"Update request invalid, element `{display_name}` does not exist\n"
|
229
|
+
logger.error(msg)
|
208
230
|
parsed_output['valid'] = False
|
209
231
|
if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
|
210
232
|
msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
|
211
|
-
|
233
|
+
logger.error(msg)
|
212
234
|
|
213
235
|
elif directive in ["validate",
|
214
236
|
"process"] and object_action == 'Create': # if the object_action is create, check that it
|
215
237
|
# doesn't already exist
|
216
238
|
if parsed_output['exists']:
|
217
239
|
msg = f"Element `{display_name}` cannot be created since it already exists\n"
|
218
|
-
|
240
|
+
logger.error(msg)
|
219
241
|
parsed_output['valid'] = False
|
220
242
|
else:
|
221
|
-
msg = f"
|
222
|
-
|
243
|
+
msg = f"Element `{display_name}` does not exist so it can be created\n"
|
244
|
+
logger.info(msg)
|
245
|
+
|
246
|
+
|
247
|
+
if parsed_output.get('qualified_name',None):
|
248
|
+
parsed_output['display'] += f"\n\t* Qualified Name: `{parsed_output['qualified_name']}`\n\t"
|
249
|
+
if parsed_output.get('guid',None):
|
250
|
+
parsed_output['display'] += f"\n\t* GUID: `{parsed_output['guid']}`\n\t"
|
251
|
+
|
252
|
+
return parsed_output
|
253
|
+
|
254
|
+
|
255
|
+
@logger.catch
|
256
|
+
def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_action: str, txt: str,
|
257
|
+
directive: str = "display") -> dict:
|
258
|
+
parsed_attributes, parsed_output = {}, {}
|
259
|
+
|
260
|
+
parsed_output['valid'] = True
|
261
|
+
parsed_output['exists'] = False
|
262
|
+
|
263
|
+
labels = {}
|
264
|
+
|
265
|
+
command_spec = get_command_spec(f"{object_action} {object_type}")
|
266
|
+
attributes = command_spec.get('Attributes', [])
|
267
|
+
command_display_name = command_spec.get('display_name', None)
|
268
|
+
|
269
|
+
parsed_output['reason'] = ""
|
270
|
+
parsed_output['display'] = ""
|
271
|
+
|
272
|
+
msg = f"\tProcessing {object_action} on {object_type} \n"
|
273
|
+
logger.info(msg)
|
274
|
+
|
275
|
+
# get the version early because we may need it to construct qualified names.
|
276
|
+
|
277
|
+
for attr in attributes:
|
278
|
+
for key in attr:
|
279
|
+
# Run some checks to see if the attribute is appropriate to the operation and usage level
|
280
|
+
|
281
|
+
level = attr[key].get('level', 'Basic')
|
282
|
+
msg = (f"___\nProcessing `{key}` in `{object_action}` on a `{object_type}` "
|
283
|
+
f"\n\twith usage level: `{EGERIA_USAGE_LEVEL}` ")
|
284
|
+
logger.trace(msg)
|
285
|
+
|
286
|
+
if EGERIA_USAGE_LEVEL == "Basic" and level != "Basic":
|
287
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
288
|
+
highlight=True)
|
289
|
+
continue
|
290
|
+
if EGERIA_USAGE_LEVEL == "Advanced" and level in ["Expert", "Invisible"]:
|
291
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
292
|
+
highlight=True)
|
293
|
+
continue
|
294
|
+
if EGERIA_USAGE_LEVEL == "Expert" and level == "Invisible":
|
295
|
+
logger.trace(f"Attribute `{key}` is not supported for `{EGERIA_USAGE_LEVEL}` usage level. Skipping.",
|
296
|
+
highlight=True)
|
297
|
+
continue
|
298
|
+
|
299
|
+
if attr[key].get('input_required', False) is True:
|
300
|
+
if_missing = ERROR
|
301
|
+
else:
|
302
|
+
if_missing = INFO
|
303
|
+
|
304
|
+
# lab = [item.strip() for item in re.split(r'[;,\n]+',attr[key]['attr_labels'])]
|
305
|
+
lab = split_tb_string(attr[key]['attr_labels'])
|
306
|
+
labels: set = set()
|
307
|
+
labels.add(key.strip())
|
308
|
+
|
309
|
+
if lab is not None and lab != [""]:
|
310
|
+
labels.update(lab)
|
311
|
+
|
312
|
+
# set these to none since not needed for view commands
|
313
|
+
version = None
|
314
|
+
command_qn_prefix = None
|
315
|
+
|
316
|
+
default_value = attr[key].get('default_value', None)
|
317
|
+
|
318
|
+
style = attr[key]['style']
|
319
|
+
if style in ['Simple', 'Dictionary', 'Comment']:
|
320
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
321
|
+
elif style == 'Valid Value':
|
322
|
+
parsed_attributes[key] = proc_valid_value(txt, object_action, labels,
|
323
|
+
attr[key].get('valid_values', None), if_missing,
|
324
|
+
default_value)
|
325
|
+
elif style == 'QN':
|
326
|
+
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
327
|
+
object_action, version, if_missing)
|
328
|
+
if key == 'Qualified Name' and parsed_attributes[key]['value'] and parsed_attributes[key][
|
329
|
+
'exists'] is False:
|
330
|
+
parsed_output['exists'] = False
|
331
|
+
elif style == 'ID':
|
332
|
+
parsed_attributes[key] = proc_el_id(egeria_client, command_display_name, command_qn_prefix, labels, txt,
|
333
|
+
object_action, version, if_missing)
|
334
|
+
|
335
|
+
parsed_output['guid'] = parsed_attributes[key].get('guid', None)
|
336
|
+
parsed_output['qualified_name'] = parsed_attributes[key].get('qualified_name', None)
|
337
|
+
parsed_output['exists'] = parsed_attributes[key]['exists']
|
338
|
+
if parsed_attributes[key]['valid'] is False:
|
339
|
+
parsed_output['valid'] = False
|
340
|
+
parsed_output['reason'] += parsed_attributes[key]['reason']
|
341
|
+
|
342
|
+
elif style == 'Reference Name':
|
343
|
+
parsed_attributes[key] = proc_ids(egeria_client, key, labels, txt, object_action, if_missing)
|
344
|
+
if ((if_missing == ERROR) and parsed_attributes[key].get("value", None) and parsed_attributes[key][
|
345
|
+
'exists'] is False):
|
346
|
+
msg = f"Reference Name `{parsed_attributes[key]['value']}` is specified but does not exist"
|
347
|
+
logger.error(msg)
|
348
|
+
parsed_output['valid'] = False
|
349
|
+
parsed_output['reason'] += msg
|
350
|
+
|
351
|
+
elif style == 'GUID':
|
352
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
353
|
+
elif style == 'Ordered Int':
|
354
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing)
|
355
|
+
elif style == 'Simple Int':
|
356
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
357
|
+
elif style == 'Simple List':
|
358
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
359
|
+
name_list = parsed_attributes[key]['value']
|
360
|
+
# attribute = re.split(r'[;,\n]+', name_list) if name_list is not None else None
|
361
|
+
attribute = split_tb_string(name_list)
|
362
|
+
parsed_attributes[key]['value'] = attribute
|
363
|
+
parsed_attributes[key]['name_list'] = name_list
|
364
|
+
elif style == 'Parent':
|
365
|
+
parsed_attributes[key] = proc_simple_attribute(txt, object_action, labels, if_missing, default_value)
|
366
|
+
elif style == 'Bool':
|
367
|
+
parsed_attributes[key] = proc_bool_attribute(txt, object_action, labels, if_missing, default_value)
|
368
|
+
|
369
|
+
|
370
|
+
elif style == 'Reference Name List':
|
371
|
+
parsed_attributes[key] = proc_name_list(egeria_client, key, txt, labels, if_missing)
|
372
|
+
if (parsed_attributes[key].get("value", None) and (
|
373
|
+
parsed_attributes[key]['exists'] is False or parsed_attributes[key]['valid'] is False)):
|
374
|
+
msg = (f"A Reference Name in `{parsed_attributes[key].get('name_list', None)}` is specified but "
|
375
|
+
f"does not exist")
|
376
|
+
logger.error(msg)
|
377
|
+
parsed_output['valid'] = False
|
378
|
+
parsed_output['reason'] += msg
|
379
|
+
else:
|
380
|
+
msg = f"Unknown attribute style: {style}"
|
381
|
+
logger.error(msg)
|
382
|
+
sys.exit(1)
|
383
|
+
parsed_attributes[key]['valid'] = False
|
384
|
+
parsed_attributes[key]['value'] = None
|
385
|
+
|
386
|
+
value = parsed_attributes[key].get('value', None)
|
387
|
+
|
388
|
+
if value is not None:
|
389
|
+
# if the value is a dict, get the flattened name list
|
390
|
+
value = parsed_attributes[key].get('name_list', None) if isinstance(value, (dict, list)) else value
|
391
|
+
parsed_output['display'] += f"\n\t* {key}: `{value}`\n\t"
|
223
392
|
|
224
393
|
parsed_output['attributes'] = parsed_attributes
|
394
|
+
|
395
|
+
|
396
|
+
if directive in ["validate", "process"] and not parsed_output['valid'] and object_action == "Update":
|
397
|
+
msg = f"Request is invalid, `{object_action} {object_type}` is not valid - see previous messages\n"
|
398
|
+
logger.error(msg)
|
399
|
+
|
400
|
+
|
225
401
|
return parsed_output
|
226
402
|
|
227
403
|
|
404
|
+
@logger.catch
|
228
405
|
def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None) -> dict:
|
229
406
|
"""Process a simple attribute based on the provided labels and if_missing value.
|
230
407
|
Extract the attribute value from the text and store it in a dictionary along with valid.
|
@@ -245,27 +422,30 @@ def proc_simple_attribute(txt: str, action: str, labels: set, if_missing: str =
|
|
245
422
|
|
246
423
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
247
424
|
msg = "Invalid severity for missing attribute"
|
248
|
-
|
425
|
+
logger.error(msg)
|
249
426
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
250
427
|
|
251
428
|
attribute = extract_attribute(txt, labels)
|
429
|
+
|
252
430
|
if default_value == "":
|
253
431
|
default_value = None
|
254
|
-
attribute = default_value if attribute is None else attribute
|
432
|
+
attribute = default_value if attribute is None else attribute.replace('\n','')
|
255
433
|
|
256
434
|
if attribute is None:
|
257
435
|
|
258
436
|
if if_missing == INFO or if_missing == WARNING:
|
259
437
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
260
438
|
valid = True
|
439
|
+
logger.info(msg)
|
261
440
|
else:
|
262
441
|
msg = f"Missing attribute with labels `{labels}` "
|
263
442
|
valid = False
|
264
|
-
|
443
|
+
logger.error(msg)
|
265
444
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
266
445
|
return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
|
267
446
|
|
268
447
|
|
448
|
+
@logger.catch
|
269
449
|
def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_missing: str = INFO,
|
270
450
|
default_value=None) -> dict:
|
271
451
|
"""Process a string attribute to check that it is a member of the associated value values list.
|
@@ -288,22 +468,22 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
|
|
288
468
|
|
289
469
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
290
470
|
msg = "Invalid severity for missing attribute"
|
291
|
-
|
471
|
+
logger.error(msg)
|
292
472
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
293
473
|
if valid_values is None:
|
294
474
|
msg = "Missing valid values list"
|
295
|
-
|
475
|
+
logger.error(msg)
|
296
476
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
297
477
|
if isinstance(valid_values, str):
|
298
478
|
# v_values = [item.strip() for item in re.split(r'[;,\n]+', valid_values)]
|
299
479
|
v_values = split_tb_string(valid_values)
|
300
480
|
if not isinstance(v_values, list):
|
301
481
|
msg = "Valid values list is not a list"
|
302
|
-
|
482
|
+
logger.error(msg)
|
303
483
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
304
484
|
if len(v_values) == 0:
|
305
485
|
msg = "Valid values list is empty"
|
306
|
-
|
486
|
+
logger.error(msg)
|
307
487
|
return {"status": WARNING, "reason": msg, "value": None, "valid": False}
|
308
488
|
|
309
489
|
attribute = extract_attribute(txt, labels)
|
@@ -314,21 +494,23 @@ def proc_valid_value(txt: str, action: str, labels: set, valid_values: [], if_mi
|
|
314
494
|
if attribute is None:
|
315
495
|
if if_missing == INFO or if_missing == WARNING:
|
316
496
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
497
|
+
logger.info(msg)
|
317
498
|
valid = True
|
318
499
|
else:
|
319
500
|
msg = f"Missing attribute with labels `{labels}` "
|
320
501
|
valid = False
|
321
|
-
|
502
|
+
logger.error(msg)
|
322
503
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
323
504
|
else:
|
324
505
|
if attribute not in v_values:
|
325
506
|
msg = f"Invalid value for attribute `{labels}`"
|
326
|
-
|
507
|
+
logger.warning(msg)
|
327
508
|
return {"status": WARNING, "reason": msg, "value": attribute, "valid": False, "exists": True}
|
328
509
|
|
329
510
|
return {"status": INFO, "OK": "OK", "value": attribute, "valid": valid, "exists": True}
|
330
511
|
|
331
512
|
|
513
|
+
@logger.catch
|
332
514
|
def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = INFO, default_value=None) -> dict:
|
333
515
|
"""Process a boolean attribute based on the provided labels and if_missing value.
|
334
516
|
Extract the attribute value from the text and store it in a dictionary along with valid.
|
@@ -349,7 +531,7 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
349
531
|
|
350
532
|
if if_missing not in ["WARNING", "ERROR", "INFO"]:
|
351
533
|
msg = "Invalid severity for missing attribute"
|
352
|
-
|
534
|
+
logger.error(msg)
|
353
535
|
return {"status": ERROR, "reason": msg, "value": None, "valid": False}
|
354
536
|
|
355
537
|
attribute = extract_attribute(txt, labels)
|
@@ -362,11 +544,12 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
362
544
|
if attribute is None:
|
363
545
|
if if_missing == INFO or if_missing == WARNING:
|
364
546
|
msg = f"Optional attribute with labels: `{labels}` missing"
|
547
|
+
logger.info(msg)
|
365
548
|
valid = True
|
366
549
|
else:
|
367
550
|
msg = f"Missing attribute with labels `{labels}` "
|
368
551
|
valid = False
|
369
|
-
|
552
|
+
logger.error(msg)
|
370
553
|
return {"status": if_missing, "reason": msg, "value": None, "valid": valid, "exists": False}
|
371
554
|
|
372
555
|
if isinstance(attribute, str):
|
@@ -377,12 +560,13 @@ def proc_bool_attribute(txt: str, action: str, labels: set, if_missing: str = IN
|
|
377
560
|
attribute = False
|
378
561
|
else:
|
379
562
|
msg = f"Invalid value for boolean attribute `{labels}`"
|
380
|
-
|
563
|
+
logger.error(msg)
|
381
564
|
return {"status": ERROR, "reason": msg, "value": attribute, "valid": False, "exists": True}
|
382
565
|
|
383
566
|
return {"status": INFO, "OK": None, "value": attribute, "valid": valid, "exists": True}
|
384
567
|
|
385
568
|
|
569
|
+
@logger.catch
|
386
570
|
def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, element_labels: list[str], txt: str,
|
387
571
|
action: str, version: str = None, if_missing: str = INFO) -> dict:
|
388
572
|
"""
|
@@ -422,7 +606,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
422
606
|
|
423
607
|
if element_name is None:
|
424
608
|
msg = f"Optional attribute with label`{element_type}` missing"
|
425
|
-
|
609
|
+
logger.info(msg)
|
426
610
|
identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": False, "exists": False, }
|
427
611
|
return identifier_output
|
428
612
|
|
@@ -436,18 +620,18 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
436
620
|
|
437
621
|
if unique is False:
|
438
622
|
msg = f"Multiple elements named {element_name} found"
|
439
|
-
|
623
|
+
logger.error(msg)
|
440
624
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
|
441
625
|
valid = False
|
442
626
|
|
443
627
|
if action == "Update" and not exists:
|
444
628
|
msg = f"Element {element_name} does not exist"
|
445
|
-
|
629
|
+
logger.error(msg)
|
446
630
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
|
447
631
|
|
448
632
|
elif action == "Update" and exists:
|
449
633
|
msg = f"Element {element_name} exists"
|
450
|
-
|
634
|
+
logger.info(msg)
|
451
635
|
identifier_output = {
|
452
636
|
"status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
|
453
637
|
'qualified_name': q_name, 'guid': guid
|
@@ -455,7 +639,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
455
639
|
|
456
640
|
elif action == "Create" and exists:
|
457
641
|
msg = f"Element {element_name} already exists"
|
458
|
-
|
642
|
+
logger.error(msg)
|
459
643
|
identifier_output = {
|
460
644
|
"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True,
|
461
645
|
'qualified_name': qualified_name, 'guid': guid,
|
@@ -463,7 +647,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
463
647
|
|
464
648
|
elif action == "Create" and not exists and valid:
|
465
649
|
msg = f"{element_type} `{element_name}` does not exist"
|
466
|
-
|
650
|
+
logger.info(msg)
|
467
651
|
|
468
652
|
if q_name is None and qualified_name is None:
|
469
653
|
q_name = egeria_client.__create_qualified_name__(qn_prefix, element_name, version_identifier=version)
|
@@ -481,6 +665,7 @@ def proc_el_id(egeria_client: EgeriaTech, element_type: str, qn_prefix: str, ele
|
|
481
665
|
return identifier_output
|
482
666
|
|
483
667
|
|
668
|
+
@logger.catch
|
484
669
|
def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set, txt: str, action: str,
|
485
670
|
if_missing: str = INFO, version: str = None) -> dict:
|
486
671
|
"""
|
@@ -530,30 +715,30 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
|
|
530
715
|
if exists is True and unique is False:
|
531
716
|
# Multiple elements found - so need to respecify with qualified name
|
532
717
|
msg = f"Multiple elements named {element_name} found"
|
533
|
-
|
718
|
+
logger.error(msg)
|
534
719
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": True, }
|
535
720
|
|
536
721
|
|
537
722
|
elif action == EXISTS_REQUIRED or if_missing == ERROR and not exists:
|
538
723
|
# a required identifier doesn't exist
|
539
724
|
msg = f"Required {element_type} `{element_name}` does not exist"
|
540
|
-
|
725
|
+
logger.error(msg)
|
541
726
|
identifier_output = {"status": ERROR, "reason": msg, "value": element_name, "valid": False, "exists": False, }
|
542
|
-
elif value is None
|
727
|
+
elif value is None and if_missing == INFO:
|
543
728
|
# an optional identifier is empty
|
544
729
|
msg = f"Optional attribute with label`{element_type}` missing"
|
545
|
-
|
730
|
+
logger.info(msg)
|
546
731
|
identifier_output = {"status": INFO, "reason": msg, "value": None, "valid": True, "exists": False, }
|
547
732
|
elif value and exists is False:
|
548
733
|
# optional identifier specified but doesn't exist
|
549
734
|
msg = f"Optional attribute with label`{element_type}` specified but doesn't exist"
|
550
|
-
|
735
|
+
logger.error(msg)
|
551
736
|
identifier_output = {"status": ERROR, "reason": msg, "value": value, "valid": False, "exists": False, }
|
552
737
|
|
553
738
|
else:
|
554
739
|
# all good.
|
555
740
|
msg = f"Element {element_type} `{element_name}` exists"
|
556
|
-
|
741
|
+
logger.info(msg)
|
557
742
|
identifier_output = {
|
558
743
|
"status": INFO, "reason": msg, "value": element_name, "valid": True, "exists": True,
|
559
744
|
"qualified_name": q_name, 'guid': guid
|
@@ -562,6 +747,7 @@ def proc_ids(egeria_client: EgeriaTech, element_type: str, element_labels: set,
|
|
562
747
|
return identifier_output
|
563
748
|
|
564
749
|
|
750
|
+
@logger.catch
|
565
751
|
def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, element_labels: set,
|
566
752
|
if_missing: str = INFO) -> dict:
|
567
753
|
"""
|
@@ -595,12 +781,12 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
595
781
|
id_list_output = {}
|
596
782
|
elements = ""
|
597
783
|
new_element_list = []
|
598
|
-
|
784
|
+
guid_list = []
|
599
785
|
elements_txt = extract_attribute(txt, element_labels)
|
600
786
|
|
601
787
|
if elements_txt is None:
|
602
788
|
msg = f"Attribute with labels `{{element_type}}` missing"
|
603
|
-
|
789
|
+
logger.debug(msg)
|
604
790
|
return {"status": if_missing, "reason": msg, "value": None, "valid": False, "exists": False, }
|
605
791
|
else:
|
606
792
|
# element_list = re.split(r'[;,\n]+', elements_txt)
|
@@ -610,13 +796,14 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
610
796
|
# Get the element using the generalized function
|
611
797
|
known_q_name, known_guid, el_valid, el_exists = get_element_by_name(egeria_client, element_type, element)
|
612
798
|
details = {"known_q_name": known_q_name, "known_guid": known_guid, "el_valid": el_valid}
|
613
|
-
elements
|
799
|
+
elements += element + ", " # list of the input names
|
614
800
|
|
615
801
|
if el_exists and el_valid:
|
616
802
|
new_element_list.append(known_q_name) # list of qualified names
|
803
|
+
guid_list.append(known_guid)
|
617
804
|
elif not el_exists:
|
618
805
|
msg = f"No {element_type} `{element}` found"
|
619
|
-
|
806
|
+
logger.debug(msg)
|
620
807
|
valid = False
|
621
808
|
valid = valid if el_valid is None else (valid and el_valid)
|
622
809
|
exists = exists and el_exists
|
@@ -624,19 +811,22 @@ def proc_name_list(egeria_client: EgeriaTech, element_type: str, txt: str, eleme
|
|
624
811
|
|
625
812
|
if elements:
|
626
813
|
msg = f"Found {element_type}: {elements}"
|
627
|
-
|
814
|
+
logger.debug(msg)
|
628
815
|
id_list_output = {
|
629
816
|
"status": INFO, "reason": msg, "value": element_details, "valid": valid, "exists": exists,
|
630
|
-
"name_list": new_element_list,
|
817
|
+
"name_list": new_element_list, "guid_list": guid_list,
|
631
818
|
}
|
632
819
|
else:
|
633
820
|
msg = f" Name list contains one or more invalid qualified names."
|
634
|
-
|
635
|
-
id_list_output = {
|
636
|
-
|
821
|
+
logger.debug(msg)
|
822
|
+
id_list_output = {
|
823
|
+
"status": if_missing, "reason": msg, "value": elements, "valid": valid, "exists": exists,
|
824
|
+
"dict_list": element_details, "guid_list": guid_list
|
825
|
+
}
|
637
826
|
return id_list_output
|
638
827
|
|
639
828
|
|
829
|
+
@logger.catch
|
640
830
|
def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories_exist: bool,
|
641
831
|
categories_list: List[str]) -> None:
|
642
832
|
"""
|
@@ -689,36 +879,19 @@ def update_term_categories(egeria_client: EgeriaTech, term_guid: str, categories
|
|
689
879
|
egeria_client.add_term_to_category(term_guid, cat)
|
690
880
|
current_categories.append(cat)
|
691
881
|
msg = f"Added term {term_guid} to category {cat}"
|
692
|
-
|
882
|
+
logger.info(msg)
|
693
883
|
|
694
884
|
for cat in current_categories:
|
695
885
|
if cat not in to_be_cat_guids:
|
696
886
|
egeria_client.remove_term_from_category(term_guid, cat)
|
697
887
|
msg = f"Removed term {term_guid} from category {cat}"
|
698
|
-
|
888
|
+
logger.info(msg)
|
699
889
|
else: # No categories specified - so remove any categories a term is in
|
700
890
|
for cat in current_categories:
|
701
891
|
egeria_client.remove_term_from_category(term_guid, cat)
|
702
892
|
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:
|
893
|
+
logger.info(msg)
|
711
894
|
|
712
|
-
pass
|
713
895
|
|
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
896
|
|
718
|
-
def sync_term_links(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
|
719
|
-
links_list: List[str]) -> None:
|
720
|
-
pass
|
721
897
|
|
722
|
-
def sync_parent_data_field(egeria_client: EgeriaTech, term_guid: str, links_exist: bool,
|
723
|
-
links_list: List[str]) -> None:
|
724
|
-
pass
|