pyegeria 5.4.3.2__py3-none-any.whl → 5.4.3.4__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.
Files changed (53) hide show
  1. commands/cat/debug_log.2025-09-01_07-02-58_818650.log.zip +0 -0
  2. commands/cat/debug_log.2025-09-02_07-44-39_567276.log.zip +0 -0
  3. commands/cat/debug_log.2025-09-03_07-45-21_986388.log.zip +0 -0
  4. commands/cat/debug_log.log +5379 -8107
  5. commands/cat/list_format_set.py +2 -2
  6. commands/tech/list_information_supply_chains.py +1 -1
  7. commands/tech/list_solution_blueprints.py +1 -1
  8. commands/tech/list_solution_components.py +1 -1
  9. commands/tech/list_solution_roles.py +1 -1
  10. md_processing/__init__.py +0 -4
  11. md_processing/data/commands.json +1258 -615
  12. md_processing/dr_egeria.py +6 -9
  13. md_processing/dr_egeria_inbox/data_spec_test.md +44 -418
  14. md_processing/dr_egeria_inbox/gov_def.md +239 -3
  15. md_processing/dr_egeria_inbox/product.md +13 -5
  16. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 14:03-product.md +209 -0
  17. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 14:24-product.md +263 -0
  18. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 16:03-data_spec_test.md +2374 -0
  19. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 16:05-data_spec_test.md +2374 -0
  20. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:28-data_spec_test.md +2321 -0
  21. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:37-data_spec_test.md +2304 -0
  22. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:56-data_spec_test.md +2324 -0
  23. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 09:00-data_spec_test.md +2324 -0
  24. md_processing/md_commands/data_designer_commands.py +170 -570
  25. md_processing/md_commands/product_manager_commands.py +1 -1
  26. md_processing/md_processing_utils/common_md_utils.py +55 -13
  27. md_processing/md_processing_utils/extraction_utils.py +14 -7
  28. md_processing/md_processing_utils/md_processing_constants.py +1 -1
  29. pyegeria/___external_references.py +3255 -0
  30. pyegeria/__init__.py +1 -1
  31. pyegeria/_client_new.py +9 -7
  32. pyegeria/_output_formats.py +124 -3
  33. pyegeria/collection_manager.py +17 -56
  34. pyegeria/config.py +10 -1
  35. pyegeria/data_designer.py +172 -124
  36. pyegeria/egeria_client.py +1 -1
  37. pyegeria/egeria_tech_client.py +1 -1
  38. pyegeria/glossary_manager.py +71 -85
  39. pyegeria/governance_officer.py +26 -29
  40. pyegeria/output_formatter.py +127 -1
  41. pyegeria/project_manager.py +33 -36
  42. pyegeria/{solution_architect_omvs.py → solution_architect.py} +443 -388
  43. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/METADATA +1 -1
  44. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/RECORD +47 -41
  45. md_processing/dr_egeria_outbox/friday/processed-2025-08-29 16:30-output_tests.md +0 -103
  46. md_processing/dr_egeria_outbox/friday/processed-2025-08-29 16:40-output_tests.md +0 -115
  47. md_processing/dr_egeria_outbox/friday/processed-2025-08-30 21:15-glossary_test1.md +0 -326
  48. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 13:27-glossary_test1.md +0 -369
  49. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 13:33-glossary_test1.md +0 -392
  50. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 20:57-glossary_test1.md +0 -400
  51. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/LICENSE +0 -0
  52. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/WHEEL +0 -0
  53. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/entry_points.txt +0 -0
@@ -953,7 +953,7 @@ def process_attach_subscriber_command(egeria_client: EgeriaTech, txt: str,
953
953
  logger.debug(json.dumps(parsed_output, indent=4))
954
954
 
955
955
  attributes = parsed_output['attributes']
956
- subscriber_guid = attributes.get('Subscriber', {}).get('guid', None)
956
+ subscriber_guid = attributes.get('Subscriber Id', {}).get('guid', None)
957
957
  subscription_guid = attributes.get('Subscription', {}).get('guid', None)
958
958
 
959
959
  valid = parsed_output['valid']
@@ -216,23 +216,17 @@ def find_key_with_value(value: str) -> str | None:
216
216
 
217
217
  def set_find_body(object_type: str, attributes: dict)->dict:
218
218
  prop_name = object_type.replace(" ", "")
219
-
220
- start = attributes.get('Start From', {}).get('value', 0)
221
- start_from = int(start) if start else 0
222
- page = attributes.get('Page Size', {}).get('value', 0)
223
- page_size = int(page) if page else 0
224
- depth = attributes.get('Graph Query Depth', {}).get('value', 0)
225
- depth = int(depth) if depth else 0
226
-
219
+ s = attributes.get('Search String', {}).get('value', None)
220
+ search_string = None if s =='*' else s
227
221
 
228
222
 
229
223
  body = {
230
224
  "class": "SearchStringRequestBody",
231
- "searchString": attributes.get('Search String', {}).get('value', None),
225
+ "searchString": search_string,
232
226
  "startsWith": attributes.get('Start With', {}).get('value', True),
233
227
  "endWith": attributes.get('End With', {}).get('value', False),
234
228
  "ignoreCase": attributes.get('Ignore Case', {}).get('value', False),
235
- "limitResultsByStatus": attributes.get('Limit Results By Status', {}).get('value', False),
229
+ "limitResultsByStatus": attributes.get('Limit Results By Status', {}).get('value', []),
236
230
  "startFrom": int(attributes.get('Start From', {}).get('value', 0)),
237
231
  "pageSize": int(attributes.get('Page Size', {}).get('value', 0)),
238
232
  # "metadataElementSubtypeNames": attributes.get('Metadata Element Subtype Name', {}).get('value', None),
@@ -240,13 +234,20 @@ def set_find_body(object_type: str, attributes: dict)->dict:
240
234
  "effectiveTime": attributes.get('Effective Time', {}).get('value', None),
241
235
  "governanceZoneFilter" : attributes.get('Governance Zone Filter', {}).get('value', None),
242
236
  "graphQueryDepth": int(attributes.get('Graph Query Depth', {}).get('value', 0)),
243
- "initialStatus": attributes.get('Status', {}).get('value', "ACTIVE"),
244
- "initialClassifications": {}}
237
+ }
245
238
 
246
239
  return body
247
240
 
248
241
 
249
242
  def set_create_body(object_type: str, attributes: dict)->dict:
243
+ """
244
+ Build the OUTER request body for a create action (NewElementRequestBody).
245
+
246
+ Notes on two-layer convention:
247
+ - Outer layer (this function): action wrapper with metadata like externalSource*, effectiveTime, anchor/parent hints, and an empty "properties" field.
248
+ - Inner layer: an element-type-specific Properties structure built by set_element_prop_body, set_product_body, set_data_field_body, etc.
249
+ Callers should build the inner body separately with the appropriate helper and then assign it to body["properties"].
250
+ """
250
251
  prop_name = object_type.replace(" ", "")
251
252
  body = {
252
253
  "class": "NewElementRequestBody",
@@ -273,6 +274,13 @@ def set_create_body(object_type: str, attributes: dict)->dict:
273
274
 
274
275
 
275
276
  def set_update_body(object_type: str, attributes: dict)->dict:
277
+ """
278
+ Build the OUTER request body for an update action (UpdateElementRequestBody).
279
+
280
+ Two-layer convention:
281
+ - Outer layer (this function) provides action metadata and an empty "properties" slot.
282
+ - Inner layer must be constructed via element-specific helpers (e.g., set_element_prop_body) and assigned to the returned dict's "properties" key by the caller before invoking the client.
283
+ """
276
284
  return {
277
285
  "class" : "UpdateElementRequestBody",
278
286
  "externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
@@ -299,6 +307,16 @@ def set_rel_prop_body(object_type: str, attributes: dict)->dict:
299
307
  }
300
308
 
301
309
  def set_element_prop_body(object_type: str, qualified_name: str, attributes: dict)->dict:
310
+ """
311
+ Build the INNER element-specific Properties body to be placed under the outer body's "properties" key.
312
+
313
+ This returns the typed properties structure (e.g., "ReferenceableProperties" subtypes) appropriate for the object_type.
314
+ Usage example:
315
+ - outer = set_create_body(object_type, attributes)
316
+ - props = set_element_prop_body(object_type, qualified_name, attributes)
317
+ - outer["properties"] = props
318
+ - client.create_xxx(outer)
319
+ """
302
320
  prop_name = object_type.replace(" ", "")
303
321
  display_name = attributes.get('Display Name', {}).get('value', None)
304
322
 
@@ -330,7 +348,21 @@ def set_product_body(object_type: str, qualified_name: str, attributes: dict)->d
330
348
  prop_bod["nextVersion"] = attributes.get('Next Version Date', {}).get('value', [])
331
349
  return prop_bod
332
350
 
333
-
351
+ def set_data_field_body(object_type: str, qualified_name: str, attributes: dict)->dict:
352
+ prop_bod = set_element_prop_body(object_type, qualified_name, attributes)
353
+ prop_bod["namespace"] = attributes.get('Namespace', {}).get('value', None)
354
+ prop_bod["aliases"] = attributes.get('Aliases', {}).get('value', [])
355
+ prop_bod["namePatterns"] = attributes.get('Name Patterns', {}).get('value', [])
356
+ prop_bod["defaultValue"] = attributes.get('Default Value', {}).get('value', None)
357
+ prop_bod["isNullable"] = attributes.get('Is Nullable', {}).get('value', None)
358
+ prop_bod["dataType"] = attributes.get('Data Type', {}).get('value', None)
359
+ prop_bod["units"] = attributes.get('Units', {}).get('value', None)
360
+ prop_bod["minimumLength"] = attributes.get('Minimum Length', {}).get('value', None)
361
+ prop_bod["length"] = attributes.get('Length', {}).get('value', None)
362
+ prop_bod["precision"] = attributes.get('Precision', {}).get('value', None)
363
+ prop_bod["orderedValues"] = attributes.get('Ordered Values', {}).get('value', [])
364
+ prop_bod["sortOrder"] = attributes.get('Sort Order', {}).get('value', None)
365
+ return prop_bod
334
366
 
335
367
  def set_update_status_body(object_type: str, attributes: dict)->dict:
336
368
  return {
@@ -401,6 +433,11 @@ def update_gov_body_for_type(object_type: str, body: dict, attributes: dict) ->
401
433
 
402
434
 
403
435
  def set_rel_request_body(object_type: str, attributes: dict)->dict:
436
+ """
437
+ Build the OUTER request body for creating a relationship (NewRelationshipRequestBody).
438
+ The inner relationship properties must be assigned to the returned dict under the "properties" key,
439
+ commonly via set_rel_prop_body or set_rel_request_body_for_type.
440
+ """
404
441
  return {
405
442
  "class" : "NewRelationshipRequestBody",
406
443
  "externalSourceGUID": attributes.get('External Source GUID', {}).get('guid', None),
@@ -423,6 +460,11 @@ def set_peer_gov_def_request_body(object_type: str, attributes: dict)->dict:
423
460
  return rel_body
424
461
 
425
462
  def set_rel_request_body_for_type(object_type: str, attributes: dict)->dict:
463
+ """
464
+ Convenience helper that builds both layers (outer + inner) for a relationship of a known type.
465
+ It creates the outer NewRelationshipRequestBody via set_rel_request_body and fills rel_body["properties"]
466
+ with a typed properties structure under the "class" of f"{object_type}Properties".
467
+ """
426
468
  rel_body = set_rel_request_body(object_type, attributes)
427
469
  # class_prop = camel_to_title_case(object_type) + "Properties"
428
470
  class_prop = f"{object_type}Properties"
@@ -421,7 +421,7 @@ def get_element_by_name(egeria_client, element_type: str, element_name: str) ->
421
421
  return q_name, guid, unique, exists
422
422
 
423
423
  # Haven't seen this element before
424
- property_names = ['qualifiedName', 'name', 'displayName', 'title']
424
+ property_names = ['qualifiedName', 'displayName', 'title']
425
425
  open_metadata_type_name = None
426
426
  details = egeria_client.get_elements_by_property_value(element_name, property_names, open_metadata_type_name)
427
427
  if isinstance(details, str):
@@ -430,12 +430,19 @@ def get_element_by_name(egeria_client, element_type: str, element_name: str) ->
430
430
  exists = False
431
431
  return None, None, unique, exists
432
432
  if len(details) > 1:
433
- msg = (f"More than one element with name {element_name} found, please specify a "
434
- f"**Qualified Name**")
435
- print_msg("DEBUG-ERROR", msg, debug_level)
436
- unique = False
437
- exists = None
438
- return element_name, None, unique, exists
433
+ if q_name is None:
434
+ q_name = egeria_client.__create_qualified_name__(element_type, element_name)
435
+ guid = egeria_client.__get_guid__(qualified_name=q_name)
436
+ update_element_dictionary(q_name, {'guid': guid})
437
+ exists = True if guid != "No elements found" else False
438
+ return q_name, guid, unique, exists
439
+ else:
440
+ msg = (f"More than one element with name {element_name} found, please specify a "
441
+ f"**Qualified Name**")
442
+ print_msg("DEBUG-ERROR", msg, debug_level)
443
+ unique = False
444
+ exists = None
445
+ return element_name, None, unique, exists
439
446
 
440
447
  el_qname = details[0]["properties"].get('qualifiedName', None)
441
448
  el_guid = details[0]['elementHeader']['guid']
@@ -150,7 +150,7 @@ command_list = ["Provenance", "Create Glossary", "Update Glossary", "Create Term
150
150
  "Update Data Structure", "Create Data Dictionary", "Update Data Dictionary", "Create Data Dict",
151
151
  "Update Data Dict",
152
152
  "View Data Structures", "View Data Structure", "View Data Fields", "View Data Field",
153
- "View Dataa Classes", "View Data Class", "Create Data Class", "Update Data Class",
153
+ "View Data Classes", "View Data Class", "Create Data Class", "Update Data Class",
154
154
  "Create Digital Product", "Create Data Product", "Update Digital Product", "Update Data Product",
155
155
  "Create Agreement", "Update Agreement",
156
156
  "Link Digital Products", "Link Product-Product", "Detach Digital Products", "Detach Product-Product",