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.
@@ -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,3 @@
1
+ """
2
+ This package contains utility functions for processing Egeria Markdown
3
+ """
@@ -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