pyegeria 5.4.0.dev14__py3-none-any.whl → 5.4.0.2__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/__init__.py +1 -17
- commands/cat/dr_egeria_md.py +6 -4
- commands/cat/list_collections.py +46 -36
- md_processing/__init__.py +5 -2
- md_processing/data/commands-working.json +34850 -0
- md_processing/data/commands.json +1750 -530
- md_processing/md_commands/product_manager_commands.py +171 -220
- md_processing/md_processing_utils/common_md_proc_utils.py +9 -0
- md_processing/md_processing_utils/common_md_utils.py +15 -2
- md_processing/md_processing_utils/md_processing_constants.py +44 -6
- pyegeria/__init__.py +8 -4
- pyegeria/_client.py +2 -1
- pyegeria/_client_new.py +688 -0
- pyegeria/_exceptions_new.py +364 -0
- pyegeria/_globals.py +3 -1
- pyegeria/_output_formats.py +196 -0
- pyegeria/_validators.py +72 -199
- pyegeria/collection_manager_omvs.py +602 -324
- pyegeria/data_designer_omvs.py +251 -203
- pyegeria/load_config.py +206 -0
- pyegeria/logging_configuration.py +204 -0
- pyegeria/output_formatter.py +162 -31
- pyegeria/utils.py +99 -61
- {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/METADATA +4 -1
- {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/RECORD +28 -37
- commands/cat/debug_log +0 -2806
- commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
- commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +0 -1
- md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +0 -1
- md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +0 -31
- md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +0 -177
- md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +0 -719
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +0 -41
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +0 -33
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +0 -192
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +0 -527
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +0 -527
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +0 -474
- {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/LICENSE +0 -0
- {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/WHEEL +0 -0
- {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/entry_points.txt +0 -0
pyegeria/output_formatter.py
CHANGED
@@ -11,6 +11,60 @@ console = Console(width= 250)
|
|
11
11
|
# Constants
|
12
12
|
MD_SEPARATOR = "\n---\n\n"
|
13
13
|
|
14
|
+
|
15
|
+
def _extract_referenceable_properties(element: dict[str, Any]) -> dict[str, Any]:
|
16
|
+
# Get general header attributes
|
17
|
+
guid = element['elementHeader'].get("guid", None)
|
18
|
+
metadata_collection_id = element['elementHeader']['origin'].get("homeMetadataCollectionId", None)
|
19
|
+
metadata_collection_name = element['elementHeader']['origin'].get("homeMetadataCollectionName", None)
|
20
|
+
origin_category = element['elementHeader'].get("origin_category", None)
|
21
|
+
created_by = element['elementHeader']["versions"].get("createdBy", None)
|
22
|
+
create_time = element['elementHeader']["versions"].get("createTime", None)
|
23
|
+
updated_by = element['elementHeader']["versions"].get("updatedBy", None)
|
24
|
+
version = element['elementHeader']["versions"].get("version", None)
|
25
|
+
type_name = element['elementHeader']["type"].get("typeName", None)
|
26
|
+
classifications = element['elementHeader'].get("classifications", [])
|
27
|
+
|
28
|
+
# Get attributes from properties
|
29
|
+
properties = element['properties']
|
30
|
+
display_name = properties.get("name", "") or ""
|
31
|
+
description = properties.get("description", "") or ""
|
32
|
+
qualified_name = properties.get("qualifiedName", "") or ""
|
33
|
+
category = properties.get("category", "") or ""
|
34
|
+
version_identifier = properties.get("versionIdentifier", "") or ""
|
35
|
+
additional_properties = properties.get("additionalProperties", {}) or {}
|
36
|
+
extended_properties = properties.get("extendedProperties", {}) or {}
|
37
|
+
effective_from = element['elementHeader'].get("effectiveFrom", None)
|
38
|
+
effective_to = element['elementHeader'].get("effectiveTo", None)
|
39
|
+
|
40
|
+
return {
|
41
|
+
"GUID": guid,
|
42
|
+
"metadata_collection_id": metadata_collection_id,
|
43
|
+
"metadata_collection_name": metadata_collection_name,
|
44
|
+
"origin_category": origin_category,
|
45
|
+
"created_by": created_by,
|
46
|
+
"create_time": create_time,
|
47
|
+
"updated_by": updated_by,
|
48
|
+
"version": version,
|
49
|
+
"type_name": type_name,
|
50
|
+
"classifications": classifications,
|
51
|
+
|
52
|
+
"display_name": display_name,
|
53
|
+
"description": description,
|
54
|
+
"qualified_name": qualified_name,
|
55
|
+
"category": category,
|
56
|
+
"version_identifier": version_identifier,
|
57
|
+
"additional_properties": additional_properties,
|
58
|
+
"extended_properties": extended_properties,
|
59
|
+
"effective_from": effective_from,
|
60
|
+
"effective_to": effective_to,
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
14
68
|
def markdown_to_html(markdown_text: str) -> str:
|
15
69
|
"""
|
16
70
|
Convert markdown text to HTML, with special handling for mermaid code blocks.
|
@@ -120,7 +174,7 @@ def make_md_attribute(attribute_name: str, attribute_value: str, output_type: st
|
|
120
174
|
output = ""
|
121
175
|
if isinstance(attribute_value,str):
|
122
176
|
attribute_value = attribute_value.strip() if attribute_value else ""
|
123
|
-
elif isinstance(attribute_value,list):
|
177
|
+
elif isinstance(attribute_value,list) and len(attribute_value) > 0:
|
124
178
|
attribute_value = ",\n".join(attribute_value)
|
125
179
|
if attribute_name:
|
126
180
|
if attribute_name.upper() == "GUID":
|
@@ -170,7 +224,8 @@ def generate_entity_md(elements: List[Dict],
|
|
170
224
|
output_format: str,
|
171
225
|
entity_type: str,
|
172
226
|
extract_properties_func: Callable,
|
173
|
-
get_additional_props_func: Optional[Callable] = None
|
227
|
+
get_additional_props_func: Optional[Callable] = None,
|
228
|
+
columns_struct: [dict] = None) -> str:
|
174
229
|
"""
|
175
230
|
Generic method to generate markdown for entities.
|
176
231
|
|
@@ -181,11 +236,13 @@ def generate_entity_md(elements: List[Dict],
|
|
181
236
|
entity_type (str): Type of entity (Glossary, Term, Category, etc.)
|
182
237
|
extract_properties_func: Function to extract properties from an element
|
183
238
|
get_additional_props_func: Optional function to get additional properties
|
239
|
+
columns (list): List of column name structures
|
184
240
|
|
185
241
|
Returns:
|
186
242
|
str: Markdown representation
|
187
243
|
"""
|
188
244
|
elements_md = ""
|
245
|
+
columns = columns_struct['formats'].get('columns') if columns_struct else None
|
189
246
|
|
190
247
|
for element in elements:
|
191
248
|
if element is None:
|
@@ -197,7 +254,7 @@ def generate_entity_md(elements: List[Dict],
|
|
197
254
|
if get_additional_props_func:
|
198
255
|
additional_props = get_additional_props_func(element,props['GUID'], output_format)
|
199
256
|
|
200
|
-
display_name = props.get('
|
257
|
+
display_name = props.get('display_name', None)
|
201
258
|
if display_name is None:
|
202
259
|
display_name = props.get('title', None)
|
203
260
|
if display_name is None:
|
@@ -208,25 +265,45 @@ def generate_entity_md(elements: List[Dict],
|
|
208
265
|
elements_md += f"# {elements_action}\n\n"
|
209
266
|
elements_md += f"## {entity_type} Name \n\n{display_name}\n\n"
|
210
267
|
elif output_format == 'REPORT':
|
211
|
-
elements_md += f'<a id="{props
|
268
|
+
elements_md += f'<a id="{props.get("GUID","No GUID")}"></a>\n# {entity_type} Name: {display_name}\n\n'
|
212
269
|
else:
|
213
270
|
elements_md += f"## {entity_type} Name \n\n{display_name}\n\n"
|
214
271
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
272
|
+
# Add attributes based on column spec if available, otherwise, add all
|
273
|
+
if columns:
|
274
|
+
for column in columns:
|
275
|
+
key = column['key']
|
276
|
+
name = column['name']
|
277
|
+
value = ""
|
278
|
+
|
279
|
+
# Check if the key is in props or additional_props
|
280
|
+
if key in props:
|
281
|
+
value = props[key]
|
282
|
+
elif key in additional_props:
|
283
|
+
value = additional_props[key]
|
284
|
+
# Format the value if needed
|
285
|
+
if 'format' in column and column['format']:
|
286
|
+
value = format_for_markdown_table(value, props['GUID'])
|
287
|
+
# elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
|
288
|
+
elements_md += make_md_attribute(name, value, output_format)
|
219
289
|
|
220
|
-
|
290
|
+
else:
|
291
|
+
for key, value in props.items():
|
292
|
+
if output_format in ['FORM', 'MD', 'DICT'] and key == 'mermaid':
|
293
|
+
continue
|
294
|
+
if key not in [ 'properties', 'display_name']:
|
295
|
+
if key == "mermaid" and value == '':
|
296
|
+
continue
|
297
|
+
elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
|
298
|
+
# Add additional properties
|
299
|
+
for key, value in additional_props.items():
|
221
300
|
elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
|
222
301
|
|
223
|
-
# Add additional properties
|
224
|
-
for key, value in additional_props.items():
|
225
|
-
elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
|
226
|
-
|
227
302
|
# # Add GUID
|
228
303
|
# elements_md += make_md_attribute("GUID",props['GUID'], output_format)
|
229
304
|
|
305
|
+
if wk := columns_struct.get("annotations", {}).get("wikilinks", None):
|
306
|
+
elements_md += ", ".join(wk)
|
230
307
|
# Add separator if not the last element
|
231
308
|
if element != elements[-1]:
|
232
309
|
elements_md += MD_SEPARATOR
|
@@ -237,7 +314,7 @@ def generate_entity_md_table(elements: List[Dict],
|
|
237
314
|
search_string: str,
|
238
315
|
entity_type: str,
|
239
316
|
extract_properties_func: Callable,
|
240
|
-
|
317
|
+
columns_struct: dict,
|
241
318
|
get_additional_props_func: Optional[Callable] = None,
|
242
319
|
output_format: str = 'LIST') -> str:
|
243
320
|
"""
|
@@ -257,6 +334,7 @@ def generate_entity_md_table(elements: List[Dict],
|
|
257
334
|
"""
|
258
335
|
# Handle pluralization - if entity_type ends with 'y', use 'ies' instead of 's'
|
259
336
|
entity_type_plural = f"{entity_type[:-1]}ies" if entity_type.endswith('y') else f"{entity_type}s"
|
337
|
+
columns = columns_struct['formats'].get('columns', [])
|
260
338
|
|
261
339
|
elements_md = ""
|
262
340
|
if output_format == "LIST":
|
@@ -304,14 +382,16 @@ def generate_entity_md_table(elements: List[Dict],
|
|
304
382
|
row += f"{value} | "
|
305
383
|
|
306
384
|
elements_md += row + "\n"
|
307
|
-
|
385
|
+
if wk := columns_struct.get("annotations",{}).get("wikilinks", None):
|
386
|
+
elements_md += ", ".join(wk)
|
308
387
|
return elements_md
|
309
388
|
|
310
389
|
def generate_entity_dict(elements: List[Dict],
|
311
390
|
extract_properties_func: Callable,
|
312
391
|
get_additional_props_func: Optional[Callable] = None,
|
313
392
|
include_keys: Optional[List[str]] = None,
|
314
|
-
exclude_keys: Optional[List[str]] = None,
|
393
|
+
exclude_keys: Optional[List[str]] = None,
|
394
|
+
columns_struct: dict = None,
|
315
395
|
output_format: str = 'DICT') -> List[Dict]:
|
316
396
|
"""
|
317
397
|
Generic method to generate a dictionary representation of entities.
|
@@ -322,6 +402,7 @@ def generate_entity_dict(elements: List[Dict],
|
|
322
402
|
get_additional_props_func: Optional function to get additional properties
|
323
403
|
include_keys: Optional list of keys to include in the result (if None, include all)
|
324
404
|
exclude_keys: Optional list of keys to exclude from the result (if None, exclude none)
|
405
|
+
columns_struct: Optional dict of columns to include (if None, include all)
|
325
406
|
output_format (str): Output format (FORM, REPORT, DICT, etc.)
|
326
407
|
|
327
408
|
Returns:
|
@@ -329,11 +410,12 @@ def generate_entity_dict(elements: List[Dict],
|
|
329
410
|
"""
|
330
411
|
result = []
|
331
412
|
|
413
|
+
#####
|
414
|
+
# Add attributes based on column spec if available, otherwise, add all
|
332
415
|
for element in elements:
|
333
416
|
if element is None:
|
334
417
|
continue
|
335
418
|
props = extract_properties_func(element)
|
336
|
-
|
337
419
|
# Get additional properties if function is provided
|
338
420
|
additional_props = {}
|
339
421
|
if get_additional_props_func:
|
@@ -342,19 +424,64 @@ def generate_entity_dict(elements: List[Dict],
|
|
342
424
|
# Create entity dictionary
|
343
425
|
entity_dict = {}
|
344
426
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
427
|
+
columns = columns_struct['formats'].get('columns', None) if columns_struct else None
|
428
|
+
if columns:
|
429
|
+
for column in columns:
|
430
|
+
key = column['key']
|
431
|
+
name = column['name']
|
432
|
+
value = ""
|
433
|
+
|
434
|
+
# Check if the key is in props or additional_props
|
435
|
+
if key in props:
|
436
|
+
value = props[key]
|
437
|
+
elif key in additional_props:
|
438
|
+
value = additional_props[key]
|
439
|
+
# Format the value if needed
|
440
|
+
if column.get('format', None):
|
441
|
+
value = format_for_markdown_table(value, props['GUID'])
|
442
|
+
entity_dict[name] = value
|
351
443
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
444
|
+
else:
|
445
|
+
# Add properties based on include/exclude lists
|
446
|
+
for key, value in props.items():
|
447
|
+
if key not in ['properties', 'mermaid']: # Skip the raw properties object
|
448
|
+
if (include_keys is None or key in include_keys) and (
|
449
|
+
exclude_keys is None or key not in exclude_keys):
|
450
|
+
entity_dict[key] = value
|
451
|
+
|
452
|
+
# Add additional properties
|
453
|
+
for key, value in additional_props.items():
|
454
|
+
if (include_keys is None or key in include_keys) and (exclude_keys is None or key not in exclude_keys):
|
455
|
+
entity_dict[key] = value
|
356
456
|
|
357
457
|
result.append(entity_dict)
|
458
|
+
#####
|
459
|
+
# for element in elements:
|
460
|
+
# if element is None:
|
461
|
+
# continue
|
462
|
+
# props = extract_properties_func(element)
|
463
|
+
#
|
464
|
+
# # Get additional properties if function is provided
|
465
|
+
# additional_props = {}
|
466
|
+
# if get_additional_props_func:
|
467
|
+
# additional_props = get_additional_props_func(element,props['GUID'], output_format)
|
468
|
+
#
|
469
|
+
# # Create entity dictionary
|
470
|
+
# entity_dict = {}
|
471
|
+
#
|
472
|
+
# # Add properties based on include/exclude lists
|
473
|
+
# for key, value in props.items():
|
474
|
+
# if key not in [ 'properties', 'mermaid']: # Skip the raw properties object
|
475
|
+
# if (include_keys is None or key in include_keys) and (
|
476
|
+
# exclude_keys is None or key not in exclude_keys):
|
477
|
+
# entity_dict[key] = value
|
478
|
+
#
|
479
|
+
# # Add additional properties
|
480
|
+
# for key, value in additional_props.items():
|
481
|
+
# if (include_keys is None or key in include_keys) and (exclude_keys is None or key not in exclude_keys):
|
482
|
+
# entity_dict[key] = value
|
483
|
+
#
|
484
|
+
# result.append(entity_dict)
|
358
485
|
|
359
486
|
return result
|
360
487
|
|
@@ -430,7 +557,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
430
557
|
output_format: str,
|
431
558
|
extract_properties_func: Callable,
|
432
559
|
get_additional_props_func: Optional[Callable] = None,
|
433
|
-
|
560
|
+
columns_struct: dict = None) -> Union[str, list[dict]]:
|
434
561
|
"""
|
435
562
|
Generate output in the specified format for the given elements.
|
436
563
|
|
@@ -446,6 +573,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
446
573
|
Returns:
|
447
574
|
Formatted output as string or list of dictionaries
|
448
575
|
"""
|
576
|
+
columns = columns_struct['formats'].get('columns',None) if columns_struct else None
|
449
577
|
# Ensure elements is a list
|
450
578
|
if isinstance(elements, dict):
|
451
579
|
elements = [elements]
|
@@ -466,7 +594,8 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
466
594
|
entity_type=entity_type,
|
467
595
|
output_format="REPORT",
|
468
596
|
extract_properties_func=extract_properties_func,
|
469
|
-
get_additional_props_func=get_additional_props_func
|
597
|
+
get_additional_props_func=get_additional_props_func,
|
598
|
+
columns_struct=columns_struct
|
470
599
|
)
|
471
600
|
|
472
601
|
# Convert the markdown to HTML
|
@@ -478,6 +607,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
478
607
|
extract_properties_func=extract_properties_func,
|
479
608
|
get_additional_props_func=get_additional_props_func,
|
480
609
|
exclude_keys=['properties'],
|
610
|
+
columns_struct=columns_struct,
|
481
611
|
output_format=output_format
|
482
612
|
)
|
483
613
|
|
@@ -490,7 +620,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
490
620
|
search_string=search_string,
|
491
621
|
entity_type=entity_type,
|
492
622
|
extract_properties_func=extract_properties_func,
|
493
|
-
|
623
|
+
columns_struct=columns_struct,
|
494
624
|
get_additional_props_func=get_additional_props_func,
|
495
625
|
output_format=output_format
|
496
626
|
)
|
@@ -508,7 +638,8 @@ def generate_output(elements: Union[Dict, List[Dict]],
|
|
508
638
|
output_format=output_format,
|
509
639
|
entity_type=entity_type,
|
510
640
|
extract_properties_func=extract_properties_func,
|
511
|
-
get_additional_props_func=get_additional_props_func
|
641
|
+
get_additional_props_func=get_additional_props_func,
|
642
|
+
columns_struct = columns_struct
|
512
643
|
)
|
513
644
|
|
514
645
|
return elements_md
|
pyegeria/utils.py
CHANGED
@@ -8,72 +8,17 @@ General utility functions in support of the Egeria Python Client package.
|
|
8
8
|
|
9
9
|
import json
|
10
10
|
from datetime import datetime
|
11
|
-
|
11
|
+
from loguru import logger
|
12
12
|
from rich import print, print_json
|
13
13
|
from rich.console import Console
|
14
|
+
from pyegeria.load_config import get_app_config
|
14
15
|
|
15
|
-
|
16
|
+
app_settings = get_app_config()
|
16
17
|
|
17
|
-
|
18
|
-
# """ Wrap the text in a dataframe
|
19
|
-
# Parameters
|
20
|
-
# ----------
|
21
|
-
# df : pandas.DataFrame
|
22
|
-
# The DataFrame to wrap the text in.
|
23
|
-
# wrap_len : int, optional
|
24
|
-
# The maximum length of each cell's contents to wrap. Defaults to 30.
|
25
|
-
#
|
26
|
-
# Returns
|
27
|
-
# -------
|
28
|
-
# pandas.DataFrame
|
29
|
-
# A new DataFrame with the wrapped text.
|
30
|
-
#
|
31
|
-
# """
|
32
|
-
#
|
33
|
-
# # Helper function to wrap text in a particular cell
|
34
|
-
# def wrap_cell_contents(cell_contents: str, wrap: int = 30) -> str:
|
35
|
-
# """ Wrap the text in a cell
|
36
|
-
# Parameters
|
37
|
-
# ----------
|
38
|
-
# cell_contents : str or any
|
39
|
-
# The contents of a cell in a dataframe.
|
40
|
-
# wrap : int, optional
|
41
|
-
# The maximum width at which to wrap the cell contents. Default is 30.
|
42
|
-
#
|
43
|
-
# Returns
|
44
|
-
# -------
|
45
|
-
# str or any
|
46
|
-
# If the cell_contents is a string and its length is greater than wrap_len,
|
47
|
-
# the contents are wrapped at wrap_len width using textwrap.
|
48
|
-
# Otherwise, the original cell_contents are returned as is.
|
49
|
-
# """
|
50
|
-
# if isinstance(cell_contents, str) and len(cell_contents) > wrap:
|
51
|
-
# return textwrap.fill(cell_contents, width=wrap)
|
52
|
-
# else:
|
53
|
-
# return cell_contents
|
54
|
-
#
|
55
|
-
# # Apply the helper function to each element in the DataFrame
|
56
|
-
# return df.map(lambda x: wrap_cell_contents(x, wrap_len))
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# def print_nice_table(df, wrap_len: int = 20, tablefmt: str = "grid") -> None:
|
60
|
-
# """ Print a nice table from the data frame"""
|
61
|
-
# print(tabulate(wrap_text(df, wrap_len), headers="keys", tablefmt=tablefmt))
|
62
|
-
#
|
63
|
-
#
|
64
|
-
# def get_json_as_table(input_json, wrap_len: int = 30, tablefmt: str = "grid") -> str:
|
65
|
-
# """ return the input json as a table"""
|
66
|
-
# data = json.loads(json.dumps(input_json))
|
67
|
-
# df = pd.json_normalize(data)
|
68
|
-
# return tabulate(wrap_text(df, wrap_len), headers="keys", tablefmt=tablefmt)
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# def print_json_list_as_table(input_json, wrap_len: int = 30, tablefmt: str = "grid") -> None:
|
72
|
-
# """ print a json list as a table"""
|
73
|
-
# data = json.loads(json.dumps(input_json))
|
74
|
-
# df = pd.json_normalize(data)
|
75
|
-
# print(tabulate(wrap_text(df, wrap_len), headers="keys", tablefmt=tablefmt))
|
18
|
+
console = Console(width=200)
|
76
19
|
|
20
|
+
def init_log():
|
21
|
+
pass
|
77
22
|
|
78
23
|
def print_rest_request_body(body):
|
79
24
|
"""
|
@@ -213,5 +158,98 @@ def camel_to_title_case(input_string):
|
|
213
158
|
return result
|
214
159
|
|
215
160
|
|
161
|
+
def to_camel_case(input_string):
|
162
|
+
"""Convert an input string to camelCase, singularizing if plural.
|
163
|
+
|
164
|
+
This function takes an input string, converts it to singular form if it's plural,
|
165
|
+
and then transforms it to camelCase format (first word lowercase, subsequent words
|
166
|
+
capitalized with no spaces).
|
167
|
+
|
168
|
+
Parameters
|
169
|
+
----------
|
170
|
+
input_string : str
|
171
|
+
The string to convert to camelCase
|
172
|
+
|
173
|
+
Returns
|
174
|
+
-------
|
175
|
+
str:
|
176
|
+
The input string converted to camelCase, after singularization if needed
|
177
|
+
|
178
|
+
Examples
|
179
|
+
--------
|
180
|
+
>>> to_camel_case("data categories")
|
181
|
+
'dataCategory'
|
182
|
+
>>> to_camel_case("business terms")
|
183
|
+
'businessTerm'
|
184
|
+
>>> to_camel_case("glossary categories")
|
185
|
+
'glossaryCategory'
|
186
|
+
"""
|
187
|
+
if not input_string:
|
188
|
+
return ""
|
189
|
+
|
190
|
+
# Convert to lowercase for consistent processing
|
191
|
+
lowercase_input = input_string.lower()
|
192
|
+
|
193
|
+
# First, convert to singular if plural
|
194
|
+
singular = lowercase_input
|
195
|
+
|
196
|
+
# Handle common plural endings
|
197
|
+
if singular.endswith('ies'):
|
198
|
+
singular = singular[:-3] + 'y'
|
199
|
+
elif singular.endswith('es'):
|
200
|
+
# Special cases like 'classes' -> 'class'
|
201
|
+
if singular.endswith('sses') or singular.endswith('ches') or singular.endswith('shes') or singular.endswith('xes'):
|
202
|
+
singular = singular[:-2]
|
203
|
+
else:
|
204
|
+
singular = singular[:-1]
|
205
|
+
elif singular.endswith('s') and not singular.endswith('ss'):
|
206
|
+
singular = singular[:-1]
|
207
|
+
|
208
|
+
# Split the string into words and convert to camelCase
|
209
|
+
words = singular.split()
|
210
|
+
if not words:
|
211
|
+
return ""
|
212
|
+
|
213
|
+
# First word is lowercase, rest are capitalized
|
214
|
+
result = words[0]
|
215
|
+
for word in words[1:]:
|
216
|
+
result += word.capitalize()
|
217
|
+
|
218
|
+
return result
|
219
|
+
|
220
|
+
def to_pascal_case(input_string)->str:
|
221
|
+
"""
|
222
|
+
Convert input string to PascalCase, singularizing if plural.
|
223
|
+
Args:
|
224
|
+
input_string ():
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
transformed string
|
228
|
+
"""
|
229
|
+
result = to_camel_case(input_string)
|
230
|
+
output_string = result[0].upper() + result[1:]
|
231
|
+
return output_string
|
232
|
+
|
233
|
+
def flatten_dict_to_string(d: dict) -> str:
|
234
|
+
"""Flatten a dictionary into a string and replace quotes with backticks."""
|
235
|
+
try:
|
236
|
+
flat_string = ", ".join(
|
237
|
+
# Change replace(\"'\", '`') to replace("'", '`')
|
238
|
+
f"{key}=`{str(value).replace('\"', '`').replace("'", '`')}`"
|
239
|
+
for key, value in d.items()
|
240
|
+
)
|
241
|
+
return flat_string
|
242
|
+
except Exception as e:
|
243
|
+
# Corrected syntax for exception chaining
|
244
|
+
raise Exception("Error flattening dictionary") from e
|
245
|
+
# The decorator logic, which applies @logger.catch dynamically
|
246
|
+
|
247
|
+
|
248
|
+
def dynamic_catch(func):
|
249
|
+
if app_settings.get("enable_logger_catchh", False):
|
250
|
+
return logger.catch(func) # Apply the logger.catch decorator
|
251
|
+
else:
|
252
|
+
return func # Return the function unwrapped
|
253
|
+
|
216
254
|
if __name__ == "__main__":
|
217
255
|
print("Main-Utils")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: pyegeria
|
3
|
-
Version: 5.4.0.
|
3
|
+
Version: 5.4.0.2
|
4
4
|
Summary: A python client for Egeria
|
5
5
|
License: Apache 2.0
|
6
6
|
Keywords: egeria,metadata,governance
|
@@ -14,11 +14,14 @@ Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
15
15
|
Requires-Dist: click
|
16
16
|
Requires-Dist: httpx
|
17
|
+
Requires-Dist: inflect (>=7.5.0,<8.0.0)
|
17
18
|
Requires-Dist: jupyter
|
18
19
|
Requires-Dist: jupyter-notebook-parser (>=0.1.4,<0.2.0)
|
19
20
|
Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
20
21
|
Requires-Dist: mermaid-py
|
22
|
+
Requires-Dist: poetry-core (>=2.1.3,<3.0.0)
|
21
23
|
Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
24
|
+
Requires-Dist: pydantic (>=2.11.7,<3.0.0)
|
22
25
|
Requires-Dist: pytest (>=8.3.5,<9.0.0)
|
23
26
|
Requires-Dist: requests
|
24
27
|
Requires-Dist: rich
|