pyegeria 5.3.9.3__py3-none-any.whl → 5.3.9.5__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.
- pyegeria/_globals.py +2 -1
- pyegeria/collection_manager_omvs.py +324 -61
- pyegeria/data_designer_omvs.py +4944 -0
- pyegeria/glossary_browser_omvs.py +2 -2
- pyegeria/md_processing/__init__.py +51 -0
- pyegeria/md_processing/commands/__init__.py +3 -0
- pyegeria/md_processing/commands/blueprint_commands.py +307 -0
- pyegeria/md_processing/commands/category_commands.py +242 -0
- pyegeria/md_processing/commands/glossary_commands.py +225 -0
- pyegeria/md_processing/commands/project_commands.py +169 -0
- pyegeria/md_processing/commands/term_commands.py +524 -0
- pyegeria/md_processing/utils/__init__.py +3 -0
- pyegeria/md_processing/utils/common_utils.py +101 -0
- pyegeria/md_processing/utils/display_utils.py +53 -0
- pyegeria/md_processing/utils/extraction_utils.py +177 -0
- pyegeria/md_processing/utils/validation_utils.py +208 -0
- pyegeria/mermaid_utilities.py +3 -2
- {pyegeria-5.3.9.3.dist-info → pyegeria-5.3.9.5.dist-info}/METADATA +1 -1
- {pyegeria-5.3.9.3.dist-info → pyegeria-5.3.9.5.dist-info}/RECORD +22 -9
- {pyegeria-5.3.9.3.dist-info → pyegeria-5.3.9.5.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.9.3.dist-info → pyegeria-5.3.9.5.dist-info}/WHEEL +0 -0
- {pyegeria-5.3.9.3.dist-info → pyegeria-5.3.9.5.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,524 @@
|
|
1
|
+
"""
|
2
|
+
This file contains term-related command functions for processing Egeria Markdown
|
3
|
+
"""
|
4
|
+
import re
|
5
|
+
from typing import Optional, List
|
6
|
+
|
7
|
+
from rich.markdown import Markdown
|
8
|
+
from rich.console import Console
|
9
|
+
|
10
|
+
from pyegeria.egeria_tech_client import EgeriaTech
|
11
|
+
from pyegeria.md_processing.utils.common_utils import (
|
12
|
+
debug_level, print_msg, ALWAYS, ERROR, INFO, WARNING, pre_command, command_seperator, EXISTS_REQUIRED
|
13
|
+
)
|
14
|
+
from pyegeria.md_processing.utils.extraction_utils import (
|
15
|
+
extract_command_plus, extract_command, process_simple_attribute, process_name_list
|
16
|
+
)
|
17
|
+
from pyegeria.md_processing.utils.validation_utils import (
|
18
|
+
process_element_identifiers, update_a_command
|
19
|
+
)
|
20
|
+
from pyegeria.md_processing.utils.display_utils import (
|
21
|
+
GLOSSARY_NAME_LABELS, CATEGORY_NAME_LABELS, TERM_NAME_LABELS, OUTPUT_LABELS, ELEMENT_OUTPUT_FORMATS,
|
22
|
+
SEARCH_LABELS, GUID_LABELS, TERM_RELATIONSHPS
|
23
|
+
)
|
24
|
+
from pyegeria.dr_egeria_state import update_element_dictionary
|
25
|
+
|
26
|
+
def update_term_categories(egeria_client: EgeriaTech, term_guid: str, current_categories: List[str], new_categories: List[str]) -> None:
|
27
|
+
"""
|
28
|
+
Updates the categories of a term.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
egeria_client: The Egeria client to use for the update.
|
32
|
+
term_guid: The GUID of the term to update.
|
33
|
+
current_categories: The current categories of the term.
|
34
|
+
new_categories: The new categories of the term.
|
35
|
+
"""
|
36
|
+
if new_categories: # If categories are specified, add them
|
37
|
+
for cat in new_categories:
|
38
|
+
if cat not in current_categories:
|
39
|
+
egeria_client.add_term_to_category(term_guid, cat)
|
40
|
+
msg = f"Added term {term_guid} to category {cat}"
|
41
|
+
print_msg("DEBUG-INFO", msg, debug_level)
|
42
|
+
# Remove any categories that are not in the new list
|
43
|
+
for cat in current_categories:
|
44
|
+
if cat not in new_categories:
|
45
|
+
egeria_client.remove_term_from_category(term_guid, cat)
|
46
|
+
msg = f"Removed term {term_guid} from category {cat}"
|
47
|
+
print_msg("DEBUG-INFO", msg, debug_level)
|
48
|
+
else: # No categories specified - so remove any categories a term is in
|
49
|
+
for cat in current_categories:
|
50
|
+
egeria_client.remove_term_from_category(term_guid, cat)
|
51
|
+
msg = f"Removed term {term_guid} from category {cat}"
|
52
|
+
print_msg("DEBUG-INFO", msg, debug_level)
|
53
|
+
|
54
|
+
|
55
|
+
def process_term_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
56
|
+
"""
|
57
|
+
Processes a term create or update command by extracting key attributes such as
|
58
|
+
term name, summary, description, abbreviation, examples, usage, version, and status from the given cell.
|
59
|
+
|
60
|
+
:param txt: A string representing the input cell to be processed for
|
61
|
+
extracting glossary-related attributes.
|
62
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
63
|
+
:return: A string summarizing the outcome of the processing.
|
64
|
+
"""
|
65
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
66
|
+
|
67
|
+
valid = True
|
68
|
+
categories_list = None
|
69
|
+
cats_exist = False
|
70
|
+
set_debug_level(directive)
|
71
|
+
known_q_name = None
|
72
|
+
command = extract_command(txt)
|
73
|
+
object_type = command.split(' ')[1].strip()
|
74
|
+
object_action = command.split(' ')[0].strip()
|
75
|
+
|
76
|
+
term_name = process_simple_attribute(txt, ['Term Name', 'Display Name'], ERROR)
|
77
|
+
print(Markdown(f"{pre_command} `{command}` for term:`{term_name}` with directive: `{directive}`"))
|
78
|
+
summary = process_simple_attribute(txt, ['Summary'],INFO)
|
79
|
+
description = process_simple_attribute(txt, ['Description'], INFO)
|
80
|
+
abbreviation = process_simple_attribute(txt, ['Abbreviation'], INFO)
|
81
|
+
examples = process_simple_attribute(txt, ['Examples'], INFO)
|
82
|
+
usage = process_simple_attribute(txt, ['Usage'], INFO)
|
83
|
+
status = process_simple_attribute(txt, ['Status'])
|
84
|
+
status = status.upper() if status else 'DRAFT'
|
85
|
+
version = process_simple_attribute(txt, ['Version', "Version Identifier", "Published Version"], INFO)
|
86
|
+
q_name = process_simple_attribute(txt, ['Qualified Name'], INFO)
|
87
|
+
|
88
|
+
aliases = process_simple_attribute(txt, ['Aliases','Alias'], INFO)
|
89
|
+
if aliases:
|
90
|
+
alias_list = list(filter(None, re.split(r'[,\n]+', aliases.strip())))
|
91
|
+
else:
|
92
|
+
alias_list = None
|
93
|
+
|
94
|
+
|
95
|
+
# validate term name and get existing qualified_name and guid if they exist
|
96
|
+
if term_name is None:
|
97
|
+
valid = False
|
98
|
+
known_q_name, known_guid, term_exists = None, None, False
|
99
|
+
else:
|
100
|
+
element_labels = TERM_NAME_LABELS
|
101
|
+
element_labels.append('Display Name')
|
102
|
+
known_q_name, known_guid, valid, term_exists = process_element_identifiers(egeria_client, object_type,
|
103
|
+
element_labels, txt, object_action,
|
104
|
+
version)
|
105
|
+
|
106
|
+
# get the glossary qualified name this term is in
|
107
|
+
glossary_name = process_simple_attribute(txt, GLOSSARY_NAME_LABELS, ERROR)
|
108
|
+
if glossary_name is None:
|
109
|
+
valid = False
|
110
|
+
known_glossary_guid = None
|
111
|
+
known_glossary_q_name = None
|
112
|
+
glossary_valid = False
|
113
|
+
glossary_exists = False
|
114
|
+
else:
|
115
|
+
known_glossary_q_name, known_glossary_guid, glossary_valid, glossary_exists = process_element_identifiers(
|
116
|
+
egeria_client, "Glossary", GLOSSARY_NAME_LABELS, txt, EXISTS_REQUIRED, None)
|
117
|
+
|
118
|
+
# process categories, if present
|
119
|
+
categories = process_simple_attribute(txt, ['Glossary Categories', 'Glossary Category', 'Category', 'Categories'])
|
120
|
+
if categories: # Find information about categoriess that classify this term
|
121
|
+
msg = "Checking for categories that classify this term"
|
122
|
+
print_msg("DEBUG-INFO", msg, debug_level)
|
123
|
+
categories_list, cat_q_name_list, cats_valid, cats_exist = process_name_list(egeria_client, 'Glossary Categories',
|
124
|
+
txt, CATEGORY_NAME_LABELS)
|
125
|
+
if cats_exist and cats_valid:
|
126
|
+
msg = f"Found valid glossary categories to classify the term:\n\t{term_name}"
|
127
|
+
print_msg("INFO", msg, debug_level)
|
128
|
+
else:
|
129
|
+
msg = "No valid glossary categories found."
|
130
|
+
print_msg("INFO", msg, debug_level)
|
131
|
+
else:
|
132
|
+
cats_exist = cats_valid = False
|
133
|
+
cat_q_name_list = None
|
134
|
+
|
135
|
+
if object_action == "Update": # check to see if provided information exists and is consistent with existing info
|
136
|
+
term_guid = process_simple_attribute(txt, GUID_LABELS)
|
137
|
+
update_description = process_simple_attribute(txt, ['Update Description'])
|
138
|
+
term_display = (f"\n* Command: {command}\n\t* Glossary: {known_glossary_q_name}\n\t"
|
139
|
+
f"* Term Name: {term_name}\n\t* Qualified Name: {q_name}\n\t* Aliases: {aliases}\n\t"
|
140
|
+
f"* Categories: {categories}\n\t"
|
141
|
+
f"* Summary: {summary}\n\t* Description: {description}\n\t"
|
142
|
+
f"* Abbreviation: {abbreviation}\n\t* Examples: {examples}\n\t* Usage: {usage}\n\t"
|
143
|
+
f"* Version: {version}\n\t* Status: {status}\n\t* GUID: {term_guid}"
|
144
|
+
f"\n\t* Update Description: {update_description}\n")
|
145
|
+
if not term_exists:
|
146
|
+
msg = f"Update request invalid, Term {term_name} does not exist\n"
|
147
|
+
print_msg(ERROR, msg, debug_level)
|
148
|
+
valid = False
|
149
|
+
|
150
|
+
elif object_action == 'Create': # if the command is create, check that it doesn't already exist
|
151
|
+
term_display = (f"\n* Command: {command}\n\t* Glossary: {known_glossary_q_name}\n\t"
|
152
|
+
f"* Term Name: {term_name}\n\t* Categories: {categories}\n\t* Summary: {summary}\n\t"
|
153
|
+
f"* Qualified Name: {q_name}\n\t* Aliases: {aliases}\n\t* Description: {description}\n\t"
|
154
|
+
f"* Abbreviation: {abbreviation}\n\t* Examples: {examples}\n\t* Usage: {usage}\n\t"
|
155
|
+
f"* Version: {version}\n\t* Status: {status}\n")
|
156
|
+
if term_exists:
|
157
|
+
msg = f"Term `{term_name}` cannot be created since it already exists\n"
|
158
|
+
print_msg(ERROR, msg, debug_level)
|
159
|
+
else:
|
160
|
+
msg = f"It is valid to create Term `{term_name}`"
|
161
|
+
print_msg(ALWAYS, msg, debug_level)
|
162
|
+
|
163
|
+
if directive == "display":
|
164
|
+
print(Markdown(term_display))
|
165
|
+
return None
|
166
|
+
elif directive == "validate":
|
167
|
+
if valid:
|
168
|
+
print(Markdown(term_display))
|
169
|
+
else:
|
170
|
+
msg = f"Validation failed for Term `{term_name}`\n"
|
171
|
+
print_msg(ERROR, msg, debug_level)
|
172
|
+
print(Markdown(term_display))
|
173
|
+
return valid
|
174
|
+
elif directive == "process":
|
175
|
+
if valid:
|
176
|
+
print(Markdown(term_display))
|
177
|
+
else:
|
178
|
+
if term_exists and object_action == "Create":
|
179
|
+
msg = f"Create failed because term `{term_name}` exists - changing `Create` to `Update` in processed output \n"
|
180
|
+
print_msg(ERROR, msg, debug_level)
|
181
|
+
print(Markdown(term_display))
|
182
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
183
|
+
else:
|
184
|
+
return None
|
185
|
+
|
186
|
+
try:
|
187
|
+
if object_action == "Update":
|
188
|
+
if not term_exists:
|
189
|
+
print(f"\n{ERROR}Term `{term_name}` does not exist! Updating result document with Create "
|
190
|
+
f"command\n")
|
191
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
192
|
+
|
193
|
+
body = {
|
194
|
+
"class": "ReferenceableRequestBody", "elementProperties": {
|
195
|
+
"class": "GlossaryTermProperties", "qualifiedName": known_q_name, "summary": summary,
|
196
|
+
"description": description, "abbreviation": abbreviation, "examples": examples,
|
197
|
+
"usage": usage, "status": status
|
198
|
+
}
|
199
|
+
}
|
200
|
+
egeria_client.update_term(known_guid, body)
|
201
|
+
print_msg(ALWAYS, f"Updated Term `{term_name}` with GUID {known_guid}", debug_level)
|
202
|
+
update_element_dictionary(known_q_name, {
|
203
|
+
'guid': known_guid, 'display_name': term_name
|
204
|
+
})
|
205
|
+
|
206
|
+
# Update categories if specified
|
207
|
+
if categories:
|
208
|
+
# Get the current categories
|
209
|
+
term_details = egeria_client.get_term_by_guid(known_guid)
|
210
|
+
current_categories = []
|
211
|
+
if 'categories' in term_details:
|
212
|
+
for cat in term_details['categories']:
|
213
|
+
current_categories.append(cat.get('guid', None))
|
214
|
+
# Update the categories
|
215
|
+
update_term_categories(egeria_client, known_guid, current_categories, cat_q_name_list)
|
216
|
+
|
217
|
+
# Update aliases if specified
|
218
|
+
if alias_list:
|
219
|
+
# Get the current aliases
|
220
|
+
term_details = egeria_client.get_term_by_guid(known_guid)
|
221
|
+
current_aliases = term_details.get('aliases', [])
|
222
|
+
# Add new aliases
|
223
|
+
for alias in alias_list:
|
224
|
+
if alias not in current_aliases:
|
225
|
+
egeria_client.add_term_alias(known_guid, alias)
|
226
|
+
# Remove aliases that are not in the new list
|
227
|
+
for alias in current_aliases:
|
228
|
+
if alias not in alias_list:
|
229
|
+
egeria_client.remove_term_alias(known_guid, alias)
|
230
|
+
|
231
|
+
return egeria_client.get_term_by_guid(known_guid, output_format='MD')
|
232
|
+
|
233
|
+
elif object_action == "Create":
|
234
|
+
if term_exists:
|
235
|
+
print(f"\nTerm `{term_name}` already exists and result document updated\n")
|
236
|
+
return update_a_command(txt, command, object_type, known_q_name, known_guid)
|
237
|
+
else:
|
238
|
+
term_guid = egeria_client.create_term(term_name, summary, description, glossary_name=glossary_name,
|
239
|
+
status=status, abbreviation=abbreviation, examples=examples,
|
240
|
+
usage=usage, aliases=alias_list)
|
241
|
+
if term_guid:
|
242
|
+
print_msg(ALWAYS, f"Created Term `{term_name}` with GUID {term_guid}", debug_level)
|
243
|
+
# Add categories if specified
|
244
|
+
if categories and cats_exist and cats_valid:
|
245
|
+
update_term_categories(egeria_client, term_guid, [], cat_q_name_list)
|
246
|
+
return egeria_client.get_term_by_guid(term_guid, output_format='MD')
|
247
|
+
else:
|
248
|
+
print_msg(ERROR, f"Failed to create Term `{term_name}`", debug_level)
|
249
|
+
return None
|
250
|
+
|
251
|
+
except Exception as e:
|
252
|
+
print(f"{ERROR}Error performing {command}: {e}")
|
253
|
+
Console().print_exception(show_locals=True)
|
254
|
+
return None
|
255
|
+
else:
|
256
|
+
return None
|
257
|
+
|
258
|
+
|
259
|
+
def process_create_term_term_relationship_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
260
|
+
"""
|
261
|
+
Processes a term-term relationship create command by extracting key attributes such as
|
262
|
+
term names and relationship type from the given text.
|
263
|
+
|
264
|
+
:param txt: A string representing the input cell to be processed for
|
265
|
+
extracting term relationship attributes.
|
266
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
267
|
+
:return: A string summarizing the outcome of the processing.
|
268
|
+
"""
|
269
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
270
|
+
|
271
|
+
command = extract_command(txt)
|
272
|
+
set_debug_level(directive)
|
273
|
+
print(Markdown(f"{pre_command} `{command}` with directive: `{directive}`"))
|
274
|
+
|
275
|
+
# Get the terms involved in the relationship
|
276
|
+
from_term_name = process_simple_attribute(txt, ['From Term', 'From Term Name'], ERROR)
|
277
|
+
to_term_name = process_simple_attribute(txt, ['To Term', 'To Term Name'], ERROR)
|
278
|
+
relationship_type = process_simple_attribute(txt, ['Relationship Type'], ERROR)
|
279
|
+
|
280
|
+
if from_term_name is None or to_term_name is None or relationship_type is None:
|
281
|
+
print_msg(ERROR, "Missing required attributes for term-term relationship", debug_level)
|
282
|
+
return None
|
283
|
+
|
284
|
+
# Validate the relationship type
|
285
|
+
if relationship_type not in TERM_RELATIONSHPS:
|
286
|
+
print_msg(ERROR, f"Invalid relationship type: {relationship_type}", debug_level)
|
287
|
+
print_msg(INFO, f"Valid relationship types: {', '.join(TERM_RELATIONSHPS)}", debug_level)
|
288
|
+
return None
|
289
|
+
|
290
|
+
# Get the term GUIDs
|
291
|
+
from_term_q_name, from_term_guid, from_term_valid, from_term_exists = process_element_identifiers(
|
292
|
+
egeria_client, "Term", TERM_NAME_LABELS, txt, EXISTS_REQUIRED, None)
|
293
|
+
to_term_q_name, to_term_guid, to_term_valid, to_term_exists = process_element_identifiers(
|
294
|
+
egeria_client, "Term", TERM_NAME_LABELS, txt, EXISTS_REQUIRED, None)
|
295
|
+
|
296
|
+
if not from_term_exists or not to_term_exists:
|
297
|
+
print_msg(ERROR, "One or both terms do not exist", debug_level)
|
298
|
+
return None
|
299
|
+
|
300
|
+
relationship_display = (f"\n* Command: {command}\n\t* From Term: {from_term_name}\n\t"
|
301
|
+
f"* To Term: {to_term_name}\n\t* Relationship Type: {relationship_type}\n")
|
302
|
+
|
303
|
+
if directive == "display":
|
304
|
+
print(Markdown(relationship_display))
|
305
|
+
return None
|
306
|
+
elif directive == "validate":
|
307
|
+
print(Markdown(relationship_display))
|
308
|
+
return True
|
309
|
+
elif directive == "process":
|
310
|
+
print(Markdown(relationship_display))
|
311
|
+
try:
|
312
|
+
# Check if the relationship already exists
|
313
|
+
term_relationships = egeria_client.get_term_relationships(from_term_guid)
|
314
|
+
for rel in term_relationships:
|
315
|
+
if rel.get('end2', {}).get('guid', '') == to_term_guid and rel.get('type', {}).get('name', '') == relationship_type:
|
316
|
+
print_msg(WARNING, f"Relationship already exists between {from_term_name} and {to_term_name}", debug_level)
|
317
|
+
return None
|
318
|
+
|
319
|
+
# Create the relationship
|
320
|
+
result = egeria_client.create_term_relationship(from_term_guid, to_term_guid, relationship_type)
|
321
|
+
if result:
|
322
|
+
print_msg(ALWAYS, f"Created relationship between {from_term_name} and {to_term_name}", debug_level)
|
323
|
+
return egeria_client.get_term_by_guid(from_term_guid, output_format='MD')
|
324
|
+
else:
|
325
|
+
print_msg(ERROR, f"Failed to create relationship between {from_term_name} and {to_term_name}", debug_level)
|
326
|
+
return None
|
327
|
+
except Exception as e:
|
328
|
+
print_msg(ERROR, f"Error creating term relationship: {e}", debug_level)
|
329
|
+
Console().print_exception(show_locals=True)
|
330
|
+
return None
|
331
|
+
|
332
|
+
|
333
|
+
def process_term_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
334
|
+
"""
|
335
|
+
Processes a term list command by extracting key attributes such as
|
336
|
+
glossary name, output format, and search string from the given text.
|
337
|
+
|
338
|
+
:param txt: A string representing the input cell to be processed for
|
339
|
+
extracting term-related attributes.
|
340
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
341
|
+
:return: A string summarizing the outcome of the processing.
|
342
|
+
"""
|
343
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
344
|
+
|
345
|
+
command = extract_command(txt)
|
346
|
+
set_debug_level(directive)
|
347
|
+
print(Markdown(f"{pre_command} `{command}` with directive: `{directive}`"))
|
348
|
+
|
349
|
+
glossary_name = process_simple_attribute(txt, GLOSSARY_NAME_LABELS)
|
350
|
+
category_name = process_simple_attribute(txt, CATEGORY_NAME_LABELS)
|
351
|
+
output_format = process_simple_attribute(txt, OUTPUT_LABELS)
|
352
|
+
output_format = output_format.upper() if output_format else "MD"
|
353
|
+
if output_format not in ELEMENT_OUTPUT_FORMATS:
|
354
|
+
print_msg(WARNING, f"Output format {output_format} not recognized, using MD", debug_level)
|
355
|
+
output_format = "MD"
|
356
|
+
|
357
|
+
search_string = process_simple_attribute(txt, SEARCH_LABELS)
|
358
|
+
|
359
|
+
known_glossary_guid = None
|
360
|
+
known_category_guid = None
|
361
|
+
|
362
|
+
if glossary_name:
|
363
|
+
known_glossary_q_name, known_glossary_guid, glossary_valid, glossary_exists = process_element_identifiers(
|
364
|
+
egeria_client, "Glossary", GLOSSARY_NAME_LABELS, txt, EXISTS_REQUIRED, None)
|
365
|
+
if not glossary_exists:
|
366
|
+
print_msg(ERROR, f"Glossary {glossary_name} not found", debug_level)
|
367
|
+
return None
|
368
|
+
|
369
|
+
if category_name:
|
370
|
+
known_category_q_name, known_category_guid, category_valid, category_exists = process_element_identifiers(
|
371
|
+
egeria_client, "Category", CATEGORY_NAME_LABELS, txt, EXISTS_REQUIRED, None)
|
372
|
+
if not category_exists:
|
373
|
+
print_msg(ERROR, f"Category {category_name} not found", debug_level)
|
374
|
+
return None
|
375
|
+
|
376
|
+
if directive == "display":
|
377
|
+
print(Markdown(f"\n* Command: {command}\n\t* Glossary Name: {glossary_name}\n\t* Category Name: {category_name}\n\t* Output Format: {output_format}\n\t* Search String: {search_string}"))
|
378
|
+
return None
|
379
|
+
elif directive == "validate":
|
380
|
+
print(Markdown(f"\n* Command: {command}\n\t* Glossary Name: {glossary_name}\n\t* Category Name: {category_name}\n\t* Output Format: {output_format}\n\t* Search String: {search_string}"))
|
381
|
+
return True
|
382
|
+
elif directive == "process":
|
383
|
+
print(Markdown(f"\n* Command: {command}\n\t* Glossary Name: {glossary_name}\n\t* Category Name: {category_name}\n\t* Output Format: {output_format}\n\t* Search String: {search_string}"))
|
384
|
+
if category_name and category_exists:
|
385
|
+
return egeria_client.list_terms_for_category(known_category_guid, output_format=output_format, search_string=search_string)
|
386
|
+
elif glossary_name and glossary_exists:
|
387
|
+
return egeria_client.list_terms_for_glossary(known_glossary_guid, output_format=output_format, search_string=search_string)
|
388
|
+
else:
|
389
|
+
return egeria_client.list_terms(output_format=output_format, search_string=search_string)
|
390
|
+
|
391
|
+
|
392
|
+
def process_term_details_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
393
|
+
"""
|
394
|
+
Processes a term details command by extracting key attributes such as
|
395
|
+
term name and output format from the given text.
|
396
|
+
|
397
|
+
:param txt: A string representing the input cell to be processed for
|
398
|
+
extracting term-related attributes.
|
399
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
400
|
+
:return: A string summarizing the outcome of the processing.
|
401
|
+
"""
|
402
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
403
|
+
|
404
|
+
command = extract_command(txt)
|
405
|
+
set_debug_level(directive)
|
406
|
+
print(Markdown(f"{pre_command} `{command}` with directive: `{directive}`"))
|
407
|
+
|
408
|
+
term_name = process_simple_attribute(txt, TERM_NAME_LABELS, ERROR)
|
409
|
+
output_format = process_simple_attribute(txt, OUTPUT_LABELS)
|
410
|
+
output_format = output_format.upper() if output_format else "MD"
|
411
|
+
if output_format not in ELEMENT_OUTPUT_FORMATS:
|
412
|
+
print_msg(WARNING, f"Output format {output_format} not recognized, using MD", debug_level)
|
413
|
+
output_format = "MD"
|
414
|
+
|
415
|
+
if term_name is None:
|
416
|
+
print_msg(ERROR, "No term name found", debug_level)
|
417
|
+
return None
|
418
|
+
|
419
|
+
known_q_name, known_guid, valid, term_exists = process_element_identifiers(egeria_client, "Term",
|
420
|
+
TERM_NAME_LABELS, txt,
|
421
|
+
EXISTS_REQUIRED, None)
|
422
|
+
if not term_exists:
|
423
|
+
print_msg(ERROR, f"Term {term_name} not found", debug_level)
|
424
|
+
return None
|
425
|
+
|
426
|
+
if directive == "display":
|
427
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
428
|
+
return None
|
429
|
+
elif directive == "validate":
|
430
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
431
|
+
return True
|
432
|
+
elif directive == "process":
|
433
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
434
|
+
return egeria_client.get_term_by_guid(known_guid, output_format=output_format)
|
435
|
+
|
436
|
+
|
437
|
+
def process_term_history_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
438
|
+
"""
|
439
|
+
Processes a term history command by extracting key attributes such as
|
440
|
+
term name and output format from the given text.
|
441
|
+
|
442
|
+
:param txt: A string representing the input cell to be processed for
|
443
|
+
extracting term-related attributes.
|
444
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
445
|
+
:return: A string summarizing the outcome of the processing.
|
446
|
+
"""
|
447
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
448
|
+
|
449
|
+
command = extract_command(txt)
|
450
|
+
set_debug_level(directive)
|
451
|
+
print(Markdown(f"{pre_command} `{command}` with directive: `{directive}`"))
|
452
|
+
|
453
|
+
term_name = process_simple_attribute(txt, TERM_NAME_LABELS, ERROR)
|
454
|
+
output_format = process_simple_attribute(txt, OUTPUT_LABELS)
|
455
|
+
output_format = output_format.upper() if output_format else "MD"
|
456
|
+
if output_format not in ELEMENT_OUTPUT_FORMATS:
|
457
|
+
print_msg(WARNING, f"Output format {output_format} not recognized, using MD", debug_level)
|
458
|
+
output_format = "MD"
|
459
|
+
|
460
|
+
if term_name is None:
|
461
|
+
print_msg(ERROR, "No term name found", debug_level)
|
462
|
+
return None
|
463
|
+
|
464
|
+
known_q_name, known_guid, valid, term_exists = process_element_identifiers(egeria_client, "Term",
|
465
|
+
TERM_NAME_LABELS, txt,
|
466
|
+
EXISTS_REQUIRED, None)
|
467
|
+
if not term_exists:
|
468
|
+
print_msg(ERROR, f"Term {term_name} not found", debug_level)
|
469
|
+
return None
|
470
|
+
|
471
|
+
if directive == "display":
|
472
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
473
|
+
return None
|
474
|
+
elif directive == "validate":
|
475
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
476
|
+
return True
|
477
|
+
elif directive == "process":
|
478
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
479
|
+
return egeria_client.get_term_history(known_guid, output_format=output_format)
|
480
|
+
|
481
|
+
|
482
|
+
def process_term_revision_history_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
483
|
+
"""
|
484
|
+
Processes a term revision history command by extracting key attributes such as
|
485
|
+
term name and output format from the given text.
|
486
|
+
|
487
|
+
:param txt: A string representing the input cell to be processed for
|
488
|
+
extracting term-related attributes.
|
489
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
490
|
+
:return: A string summarizing the outcome of the processing.
|
491
|
+
"""
|
492
|
+
from pyegeria.md_processing.utils.common_utils import set_debug_level
|
493
|
+
|
494
|
+
command = extract_command(txt)
|
495
|
+
set_debug_level(directive)
|
496
|
+
print(Markdown(f"{pre_command} `{command}` with directive: `{directive}`"))
|
497
|
+
|
498
|
+
term_name = process_simple_attribute(txt, TERM_NAME_LABELS, ERROR)
|
499
|
+
output_format = process_simple_attribute(txt, OUTPUT_LABELS)
|
500
|
+
output_format = output_format.upper() if output_format else "MD"
|
501
|
+
if output_format not in ELEMENT_OUTPUT_FORMATS:
|
502
|
+
print_msg(WARNING, f"Output format {output_format} not recognized, using MD", debug_level)
|
503
|
+
output_format = "MD"
|
504
|
+
|
505
|
+
if term_name is None:
|
506
|
+
print_msg(ERROR, "No term name found", debug_level)
|
507
|
+
return None
|
508
|
+
|
509
|
+
known_q_name, known_guid, valid, term_exists = process_element_identifiers(egeria_client, "Term",
|
510
|
+
TERM_NAME_LABELS, txt,
|
511
|
+
EXISTS_REQUIRED, None)
|
512
|
+
if not term_exists:
|
513
|
+
print_msg(ERROR, f"Term {term_name} not found", debug_level)
|
514
|
+
return None
|
515
|
+
|
516
|
+
if directive == "display":
|
517
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
518
|
+
return None
|
519
|
+
elif directive == "validate":
|
520
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
521
|
+
return True
|
522
|
+
elif directive == "process":
|
523
|
+
print(Markdown(f"\n* Command: {command}\n\t* Term Name: {term_name}\n\t* Output Format: {output_format}"))
|
524
|
+
return egeria_client.get_term_revision_history(known_guid, output_format=output_format)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
"""
|
2
|
+
This file contains general utility functions for processing Egeria Markdown
|
3
|
+
"""
|
4
|
+
import os
|
5
|
+
import re
|
6
|
+
from datetime import datetime
|
7
|
+
from typing import List, Optional, Any
|
8
|
+
|
9
|
+
from rich import print
|
10
|
+
from rich.console import Console
|
11
|
+
from rich.markdown import Markdown
|
12
|
+
|
13
|
+
from pyegeria._globals import DEBUG_LEVEL
|
14
|
+
|
15
|
+
# Constants
|
16
|
+
EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "170"))
|
17
|
+
console = Console(width=EGERIA_WIDTH)
|
18
|
+
|
19
|
+
message_types = {
|
20
|
+
"INFO": "INFO-", "WARNING": "WARNING->", "ERROR": "ERROR->", "DEBUG-INFO": "DEBUG-INFO->",
|
21
|
+
"DEBUG-WARNING": "DEBUG-WARNING->", "DEBUG-ERROR": "DEBUG-ERROR->", "ALWAYS": "\n\n==> "
|
22
|
+
}
|
23
|
+
ALWAYS = "ALWAYS"
|
24
|
+
ERROR = "ERROR"
|
25
|
+
INFO = "INFO"
|
26
|
+
WARNING = "WARNING"
|
27
|
+
pre_command = "\n---\n==> Processing command:"
|
28
|
+
command_seperator = Markdown("\n---\n")
|
29
|
+
EXISTS_REQUIRED = "Exists Required"
|
30
|
+
|
31
|
+
debug_level = DEBUG_LEVEL
|
32
|
+
|
33
|
+
def render_markdown(markdown_text: str) -> None:
|
34
|
+
"""Renders the given markdown text in the console."""
|
35
|
+
console.print(Markdown(markdown_text))
|
36
|
+
|
37
|
+
|
38
|
+
def is_valid_iso_date(date_text) -> bool:
|
39
|
+
"""Checks if the given string is a valid ISO date."""
|
40
|
+
try:
|
41
|
+
datetime.strptime(date_text, '%Y-%m-%d')
|
42
|
+
return True
|
43
|
+
except ValueError:
|
44
|
+
return False
|
45
|
+
|
46
|
+
|
47
|
+
def set_debug_level(directive: str) -> None:
|
48
|
+
"""Sets the debug level for the script."""
|
49
|
+
global debug_level
|
50
|
+
if directive == "display":
|
51
|
+
debug_level = "display-only"
|
52
|
+
|
53
|
+
|
54
|
+
def get_current_datetime_string():
|
55
|
+
"""Returns the current date and time as a human-readable string."""
|
56
|
+
now = datetime.now().strftime('%Y-%m-%d %H:%M')
|
57
|
+
return now
|
58
|
+
|
59
|
+
|
60
|
+
def print_msg(msg_level: str, msg: str, verbosity: str):
|
61
|
+
"""
|
62
|
+
Prints a message based on its type and verbosity level.
|
63
|
+
|
64
|
+
This function handles the output of messages depending on the specified
|
65
|
+
verbosity level and message type. It uses predefined message types and
|
66
|
+
formats the output accordingly.
|
67
|
+
|
68
|
+
Args:
|
69
|
+
msg_type: The type of the message, such as 'WARNING', 'ERROR', 'INFO', or
|
70
|
+
'ALWAYS'.
|
71
|
+
msg: The content of the message to display.
|
72
|
+
verbosity: The verbosity level, which determines how the message is
|
73
|
+
displayed ('verbose', 'quiet', or 'debug').
|
74
|
+
"""
|
75
|
+
if msg_level == "ALWAYS":
|
76
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
77
|
+
elif verbosity == "verbose" and msg_level in ["INFO", "WARNING", "ERROR"]:
|
78
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
79
|
+
elif verbosity == "quiet" and msg_level in ["WARNING", "ERROR"]:
|
80
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
81
|
+
elif verbosity == "debug" and msg_level in ["INFO", "WARNING", "ERROR", "DEBUG-INFO", "DEBUG-WARNING", "DEBUG-ERROR"]:
|
82
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
83
|
+
elif verbosity == "display-only" and msg_level in ["ALWAYS", "ERROR"]:
|
84
|
+
print(f"{message_types.get(msg_level, '')}{msg}")
|
85
|
+
|
86
|
+
|
87
|
+
def process_provenance_command(file_path: str, txt: [str]) -> str:
|
88
|
+
"""
|
89
|
+
Processes a provenance command by extracting the file path and current datetime.
|
90
|
+
|
91
|
+
Args:
|
92
|
+
file_path: The path to the file being processed.
|
93
|
+
txt: The text containing the provenance command.
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
A string containing the provenance information.
|
97
|
+
"""
|
98
|
+
now = get_current_datetime_string()
|
99
|
+
file_name = os.path.basename(file_path)
|
100
|
+
provenance = f"\n\n\n# Provenance:\n \n* Derived from processing file {file_name} on {now}\n"
|
101
|
+
return provenance
|