pyegeria 5.4.0.1__py3-none-any.whl → 5.4.0.3__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 (43) hide show
  1. commands/cat/__init__.py +1 -1
  2. commands/cat/dr_egeria_md.py +6 -4
  3. commands/cat/list_collections.py +47 -36
  4. md_processing/__init__.py +5 -2
  5. md_processing/data/commands-working.json +34850 -0
  6. md_processing/data/commands.json +1750 -530
  7. md_processing/md_commands/product_manager_commands.py +171 -220
  8. md_processing/md_processing_utils/common_md_proc_utils.py +9 -0
  9. md_processing/md_processing_utils/common_md_utils.py +15 -2
  10. md_processing/md_processing_utils/md_processing_constants.py +44 -6
  11. pyegeria/__init__.py +8 -4
  12. pyegeria/_client.py +2 -1
  13. pyegeria/_client_new.py +688 -0
  14. pyegeria/_exceptions_new.py +362 -0
  15. pyegeria/_globals.py +3 -1
  16. pyegeria/_output_formats.py +196 -0
  17. pyegeria/_validators.py +72 -199
  18. pyegeria/collection_manager_omvs.py +602 -324
  19. pyegeria/data_designer_omvs.py +251 -203
  20. pyegeria/load_config.py +217 -0
  21. pyegeria/logging_configuration.py +204 -0
  22. pyegeria/output_formatter.py +162 -31
  23. pyegeria/utils.py +99 -61
  24. {pyegeria-5.4.0.1.dist-info → pyegeria-5.4.0.3.dist-info}/METADATA +3 -1
  25. {pyegeria-5.4.0.1.dist-info → pyegeria-5.4.0.3.dist-info}/RECORD +28 -37
  26. commands/cat/debug_log +0 -2806
  27. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  28. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  29. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +0 -1
  30. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +0 -1
  31. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +0 -31
  32. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +0 -177
  33. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  34. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +0 -719
  35. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +0 -41
  36. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +0 -33
  37. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +0 -192
  38. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +0 -527
  39. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +0 -527
  40. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +0 -474
  41. {pyegeria-5.4.0.1.dist-info → pyegeria-5.4.0.3.dist-info}/LICENSE +0 -0
  42. {pyegeria-5.4.0.1.dist-info → pyegeria-5.4.0.3.dist-info}/WHEEL +0 -0
  43. {pyegeria-5.4.0.1.dist-info → pyegeria-5.4.0.3.dist-info}/entry_points.txt +0 -0
@@ -7,11 +7,18 @@ Copyright Contributors to the ODPi Egeria project.
7
7
  """
8
8
 
9
9
  import asyncio
10
+ from typing import Dict, Union, List, Optional
11
+
12
+ from loguru import logger
13
+
14
+ from pyegeria import select_output_format_set
10
15
  from pyegeria._client import Client
11
- from pyegeria._globals import NO_ELEMENTS_FOUND
16
+ from pyegeria._globals import NO_ELEMENTS_FOUND, NO_GUID_RETURNED, NO_MEMBERS_FOUND
12
17
  from pyegeria._validators import validate_guid, validate_search_string
13
- from pyegeria.output_formatter import (extract_mermaid_only, extract_basic_dict, generate_output, markdown_to_html)
14
- from pyegeria.utils import body_slimmer
18
+ from pyegeria.output_formatter import (generate_output,
19
+ _extract_referenceable_properties)
20
+ from pyegeria.utils import body_slimmer, dynamic_catch
21
+
15
22
 
16
23
 
17
24
  def query_seperator(current_string):
@@ -32,10 +39,9 @@ def query_string(params):
32
39
  result = f"{result}{query_seperator(result)}{params[i][0]}={params[i][1]}"
33
40
  return result
34
41
 
42
+ from pyegeria._client_new import Client2
35
43
 
36
-
37
-
38
- class CollectionManager(Client):
44
+ class CollectionManager(Client2):
39
45
  """
40
46
  Maintain and explore the contents of nested collections. These collections can be used to represent digital
41
47
  products, or collections of resources for a particular project or team. They can be used to organize assets and
@@ -57,21 +63,28 @@ class CollectionManager(Client):
57
63
 
58
64
  """
59
65
 
66
+
60
67
  def __init__(self, view_server: str, platform_url: str, user_id: str, user_pwd: str = None, token: str = None, ):
61
68
  self.view_server = view_server
62
69
  self.platform_url = platform_url
63
70
  self.user_id = user_id
64
71
  self.user_pwd = user_pwd
65
72
 
73
+
74
+ Client2.__init__(self, view_server, platform_url, user_id, user_pwd, token)
75
+ result = self.get_platform_origin()
76
+ logger.info(f"CollectionManager initialized, platform origin is: {result}")
66
77
  self.collection_command_root: str = (
67
78
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections")
68
- Client.__init__(self, view_server, platform_url, user_id, user_pwd, token)
79
+ #
80
+ # Retrieving Collections - https://egeria-project.org/concepts/collection
81
+ #
69
82
 
70
- #
71
- # Retrieving Collections - https://egeria-project.org/concepts/collection
72
- #
83
+
84
+ @dynamic_catch
73
85
  async def _async_get_attached_collections(self, parent_guid: str, start_from: int = 0, page_size: int = 0,
74
- body: dict = None, output_format: str = "JSON") -> list:
86
+ body: dict = None, output_format: str = "JSON",
87
+ output_format_set: str | dict = None) -> list | str:
75
88
  """Returns the list of collections that are linked off of the supplied element using the ResourceList
76
89
  relationship. Async version.
77
90
 
@@ -88,6 +101,8 @@ class CollectionManager(Client):
88
101
  If supplied, adds addition request details - for instance, to filter the results on collectionType
89
102
  output_format: str, default = "JSON"
90
103
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
104
+ output_format_set: str | dict = None), optional, default = None
105
+ The desired output columns/fields to include.
91
106
 
92
107
  Returns
93
108
  -------
@@ -130,14 +145,18 @@ class CollectionManager(Client):
130
145
  response = await self._async_make_request("POST", url, body_slimmer(body))
131
146
  elements = response.json().get("elements", NO_ELEMENTS_FOUND)
132
147
  if type(elements) is str:
148
+ logger.info(NO_ELEMENTS_FOUND)
133
149
  return NO_ELEMENTS_FOUND
134
150
 
135
151
  if output_format != 'JSON': # return a simplified markdown representation
136
- return self.generate_collection_output(elements, None, None, output_format)
152
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
153
+ return self.generate_collection_output(elements, None, None, output_format,
154
+ output_format_set=output_format_set)
137
155
  return elements
138
156
 
157
+
139
158
  def get_attached_collections(self, parent_guid: str, start_from: int = 0, page_size: int = 0, body: dict = None,
140
- output_format: str = "JSON") -> list:
159
+ output_format: str = "JSON", output_format_set: str | dict = None) -> list:
141
160
  """Returns the list of collections that are linked off of the supplied element using the ResourceList
142
161
  relationship. Async version.
143
162
 
@@ -154,6 +173,8 @@ class CollectionManager(Client):
154
173
  If supplied, adds addition request details - for instance, to filter the results on collectionType
155
174
  output_format: str, default = "JSON"
156
175
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
176
+ output_format_set: str | dict = None), optional, default = None
177
+ The desired output columns/fields to include.
157
178
 
158
179
 
159
180
  Returns
@@ -189,12 +210,16 @@ class CollectionManager(Client):
189
210
 
190
211
  """
191
212
  return asyncio.get_event_loop().run_until_complete(
192
- self._async_get_attached_collections(parent_guid, start_from, page_size, body, output_format))
213
+ self._async_get_attached_collections(parent_guid, start_from, page_size,
214
+ body, output_format, output_format_set))
193
215
 
216
+
217
+ # @dynamic_catch
194
218
  async def _async_find_collections_w_body(self, body: dict, classification_name: str = None,
195
219
  starts_with: bool = True, ends_with: bool = False,
196
220
  ignore_case: bool = False, start_from: int = 0, page_size: int = 0,
197
- output_format: str = 'JSON', output_profile: str = "CORE") -> list | str:
221
+ output_format: str = 'JSON',
222
+ output_format_set: str | dict = None) -> list | str:
198
223
  """ Returns the list of collections matching the search string filtered by the optional classification.
199
224
  The search string is located in the request body and is interpreted as a plain string. The full
200
225
  body allows complete control including status, asOfTime and effectiveTime.
@@ -220,8 +245,8 @@ class CollectionManager(Client):
220
245
  the class instance.
221
246
  output_format: str, default = "JSON"
222
247
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
223
- output_profile: str, optional, default = "CORE"
224
- The desired output profile - BASIC, CORE, FULL
248
+ output_format_set: str | dict , optional, default = None
249
+ - The desired output columns/field options.
225
250
  Returns
226
251
  -------
227
252
  List | str
@@ -259,7 +284,7 @@ class CollectionManager(Client):
259
284
  ends_with_s = str(ends_with).lower()
260
285
  ignore_case_s = str(ignore_case).lower()
261
286
 
262
- if classification_name == "*":
287
+ if classification_name in ["*", "Collections", "Collection"]:
263
288
  classification_name = None
264
289
 
265
290
  body_s = body_slimmer(body)
@@ -273,16 +298,20 @@ class CollectionManager(Client):
273
298
  response = await self._async_make_request("POST", url, body_s)
274
299
  elements = response.json().get("elements", NO_ELEMENTS_FOUND)
275
300
  if type(elements) is str:
301
+ logger.info(NO_ELEMENTS_FOUND)
276
302
  return NO_ELEMENTS_FOUND
277
303
 
278
304
  if output_format != 'JSON': # return a simplified markdown representation
279
- return self.generate_collection_output(elements, None, None, output_format)
305
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
306
+ return self.generate_collection_output(elements, None, classification_name,
307
+ output_format, output_format_set)
280
308
  return elements
281
309
 
310
+
282
311
  def find_collections_w_body(self, body: dict, classification_name: str = None, starts_with: bool = True,
283
312
  ends_with: bool = False, ignore_case: bool = False, start_from: int = 0,
284
313
  page_size: int = 0, output_format: str = 'JSON',
285
- output_profile: str = "CORE") -> list | str:
314
+ output_format_set: str | dict = None) -> list | str:
286
315
  """ Returns the list of collections matching the search string filtered by the optional classification.
287
316
  The search string is located in the request body and is interpreted as a plain string. The full
288
317
  body allows complete control including status, asOfTime and effectiveTime.
@@ -308,8 +337,8 @@ class CollectionManager(Client):
308
337
  the class instance.
309
338
  output_format: str, default = "JSON"
310
339
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
311
- output_profile: str, optional, default = "CORE"
312
- The desired output profile - BASIC, CORE, FULL
340
+ output_format_set: str | dict , optional, default = None
341
+ The desired output columns.
313
342
  Returns
314
343
  -------
315
344
  List | str
@@ -343,12 +372,14 @@ class CollectionManager(Client):
343
372
  """
344
373
  return asyncio.get_event_loop().run_until_complete(
345
374
  self._async_find_collections_w_body(body, classification_name, starts_with, ends_with, ignore_case,
346
- start_from, page_size, output_format, output_profile))
375
+ start_from, page_size, output_format, output_format_set))
347
376
 
377
+
378
+ @dynamic_catch
348
379
  async def _async_find_collections(self, search_string: str = '*', classification_name: str = None,
349
380
  starts_with: bool = True, ends_with: bool = False, ignore_case: bool = False,
350
381
  start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
351
- output_profile: str = "CORE") -> list | str:
382
+ output_format_set: str | dict = None) -> list | str:
352
383
  """ Returns the list of collections matching the search string filtered by the optional classification.
353
384
  The search string is located in the request body and is interpreted as a plain string. The full
354
385
  body allows complete control including status, asOfTime and effectiveTime.
@@ -375,8 +406,8 @@ class CollectionManager(Client):
375
406
  the class instance.
376
407
  output_format: str, default = "JSON"
377
408
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
378
- output_profile: str, optional, default = "CORE"
379
- The desired output profile - BASIC, CORE, FULL
409
+ output_format_set: str | dict , optional, default = None
410
+ - The desired output columns/fields to include.
380
411
  Returns
381
412
  -------
382
413
  List | str
@@ -400,12 +431,14 @@ class CollectionManager(Client):
400
431
  }
401
432
 
402
433
  resp = await self._async_find_collections_w_body(body, classification_name, starts_with, ends_with, ignore_case,
403
- start_from, page_size, output_format, output_profile)
434
+ start_from, page_size, output_format, output_format_set)
404
435
  return resp
405
436
 
437
+ @dynamic_catch
406
438
  def find_collections(self, search_string: str = '*', classification_name: str = None, starts_with: bool = True,
407
439
  ends_with: bool = False, ignore_case: bool = False,
408
- start_from: int = 0, page_size: int = 0, output_format: str = 'JSON', output_profile: str = "CORE") -> list | str:
440
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
441
+ output_format_set: str | dict = None) -> list | str:
409
442
  """ Returns the list of collections matching the search string filtered by the optional classification.
410
443
  The search string is located in the request body and is interpreted as a plain string. The full
411
444
  body allows complete control including status, asOfTime and effectiveTime.
@@ -431,8 +464,8 @@ class CollectionManager(Client):
431
464
  the class instance.
432
465
  output_format: str, default = "JSON"
433
466
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
434
- output_profile: str, optional, default = "CORE"
435
- The desired output profile - BASIC, CORE, FULL
467
+ output_format_set: str | dict , optional, default = None
468
+ - The desired output columns/fields to include.
436
469
  Returns
437
470
  -------
438
471
  List | str
@@ -452,11 +485,14 @@ class CollectionManager(Client):
452
485
  """
453
486
  return asyncio.get_event_loop().run_until_complete(
454
487
  self._async_find_collections(search_string, classification_name, starts_with, ends_with, ignore_case,
455
- start_from, page_size, output_format, output_profile))
488
+ start_from, page_size, output_format, output_format_set))
489
+
456
490
 
491
+ @dynamic_catch
457
492
  async def _async_get_collections_by_name(self, name: str, classification_name: str = None, body: dict = None,
458
493
  start_from: int = 0, page_size: int = 0,
459
- output_format: str = 'JSON') -> list | str:
494
+ output_format: str = 'JSON',
495
+ output_format_set: str | dict = None) -> list | str:
460
496
  """ Returns the list of collections with a particular name.
461
497
 
462
498
  Parameters
@@ -474,6 +510,9 @@ class CollectionManager(Client):
474
510
  the class instance.
475
511
  output_format: str, default = "JSON"
476
512
  - one of "DICT", "MERMAID" or "JSON"
513
+ output_format_set: dict , optional, default = None
514
+ The desired output columns/fields to include.
515
+
477
516
  Returns
478
517
  -------
479
518
  List | str
@@ -505,14 +544,19 @@ class CollectionManager(Client):
505
544
  response = await self._async_make_request("POST", url, body_slimmer(body))
506
545
  elements = response.json().get("elements", NO_ELEMENTS_FOUND)
507
546
  if type(elements) is str:
547
+ logger.info(NO_ELEMENTS_FOUND)
508
548
  return NO_ELEMENTS_FOUND
509
549
 
510
550
  if output_format != 'JSON': # return a simplified markdown representation
511
- return self.generate_collection_output(elements, filter, classification_name, output_format)
551
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
552
+ return self.generate_collection_output(elements, filter, classification_name,
553
+ output_format, output_format_set)
512
554
  return elements
513
555
 
556
+
514
557
  def get_collections_by_name(self, name: str, classification_name: str = None, body: dict = None,
515
- start_from: int = 0, page_size: int = None, output_format: str = 'JSON') -> list | str:
558
+ start_from: int = 0, page_size: int = None, output_format: str = 'JSON',
559
+ output_format_set: str | dict = None) -> list | str:
516
560
  """Returns the list of collections matching the search string. Async version.
517
561
  The search string is located in the request body and is interpreted as a plain string.
518
562
  The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
@@ -532,6 +576,8 @@ class CollectionManager(Client):
532
576
  the class instance.
533
577
  output_format: str, default = "JSON"
534
578
  - one of "DICT", "MERMAID" or "JSON"
579
+ output_format_set: str | dict , optional, default = None
580
+ The desired output columns/fields to include.
535
581
 
536
582
  Returns
537
583
  -------
@@ -554,11 +600,15 @@ class CollectionManager(Client):
554
600
 
555
601
  """
556
602
  return asyncio.get_event_loop().run_until_complete(
557
- self._async_get_collections_by_name(name, classification_name, body, start_from, page_size, output_format))
603
+ self._async_get_collections_by_name(name, classification_name, body, start_from, page_size,
604
+ output_format, output_format_set))
605
+
558
606
 
607
+ @dynamic_catch
559
608
  async def _async_get_collections_by_type(self, collection_type: str, classification_name: str = None,
560
609
  body: dict = None, start_from: int = 0, page_size: int = 0,
561
- output_format: str = 'JSON') -> list | str:
610
+ output_format: str = 'JSON',
611
+ output_format_set: str | dict = None) -> list | str:
562
612
  """Returns the list of collections with a particular collectionType. This is an optional text field in the
563
613
  collection element.
564
614
 
@@ -578,6 +628,8 @@ class CollectionManager(Client):
578
628
  the class instance.
579
629
  output_format: str, default = "JSON"
580
630
  - one of "DICT", "MERMAID" or "JSON"
631
+ output_format_set: str | dict , optional, default = None
632
+ The desired output columns/fields to include.
581
633
 
582
634
  Returns
583
635
  -------
@@ -630,14 +682,19 @@ class CollectionManager(Client):
630
682
  response = await self._async_make_request("POST", url, body_s)
631
683
  elements = response.json().get("elements", NO_ELEMENTS_FOUND)
632
684
  if type(elements) is str:
685
+ logger.info(NO_ELEMENTS_FOUND)
633
686
  return NO_ELEMENTS_FOUND
634
687
 
635
688
  if output_format != 'JSON': # return a simplified markdown representation
636
- return self.generate_collection_output(elements, filter, collection_type, output_format)
689
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
690
+ return self.generate_collection_output(elements, filter, collection_type,
691
+ output_format, output_format_set)
637
692
  return elements
638
693
 
694
+
639
695
  def get_collections_by_type(self, collection_type: str, classification_name: str = None, body: dict = None,
640
- start_from: int = 0, page_size: int = 0, output_format: str = 'JSON') -> list | str:
696
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
697
+ output_format_set: str | dict = None) -> list | str:
641
698
  """Returns the list of collections with a particular collectionType. This is an optional text field in the
642
699
  collection element.
643
700
 
@@ -657,12 +714,14 @@ class CollectionManager(Client):
657
714
  the class instance.
658
715
  output_format: str, default = "JSON"
659
716
  - one of "DICT", "MERMAID" or "JSON"
717
+ output_format_set: str | dict , optional, default = None
718
+ The desired output columns/fields to include.
660
719
 
661
720
  Returns
662
721
  -------
663
722
  List | str
664
723
 
665
- A list of collections the specified collection type. Returns a string if none found.
724
+ A list of collections of the specified collection type. Returns a string if none found.
666
725
 
667
726
  Raises
668
727
  ------
@@ -694,10 +753,13 @@ class CollectionManager(Client):
694
753
 
695
754
  return asyncio.get_event_loop().run_until_complete(
696
755
  self._async_get_collections_by_type(collection_type, classification_name, body, start_from, page_size,
697
- output_format))
756
+ output_format, output_format_set))
757
+
698
758
 
759
+ @dynamic_catch
699
760
  async def _async_get_collection_by_guid(self, collection_guid: str, collection_type: str = None, body: dict = None,
700
- output_format: str = 'JSON') -> dict | str:
761
+ output_format: str = 'JSON',
762
+ output_format_set: str | dict = None) -> dict | str:
701
763
  """Return the properties of a specific collection. Async version.
702
764
 
703
765
  Parameters
@@ -710,6 +772,8 @@ class CollectionManager(Client):
710
772
  full request body.
711
773
  output_format: str, default = "JSON"
712
774
  - one of "DICT", "MERMAID" or "JSON"
775
+ output_format_set: str | dict , optional, default = None
776
+ The desired output columns/fields to include.
713
777
 
714
778
  Returns
715
779
  -------
@@ -749,14 +813,18 @@ class CollectionManager(Client):
749
813
  response = await self._async_make_request("GET", url)
750
814
  elements = response.json().get("element", NO_ELEMENTS_FOUND)
751
815
  if type(elements) is str:
816
+ logger.info(NO_ELEMENTS_FOUND)
752
817
  return NO_ELEMENTS_FOUND
753
818
 
754
819
  if output_format != 'JSON': # return a simplified markdown representation
755
- return self.generate_collection_output(elements, None, collection_type, output_format)
820
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
821
+ return self.generate_collection_output(elements, None, collection_type,
822
+ output_format, output_format_set)
756
823
  return elements
757
824
 
825
+
758
826
  def get_collection_by_guid(self, collection_guid: str, collection_type: str = None, body: dict = None,
759
- output_format: str = 'JSON') -> dict | str:
827
+ output_format: str = 'JSON', output_format_set: str | dict = None) -> dict | str:
760
828
  """ Return the properties of a specific collection. Async version.
761
829
 
762
830
  Parameters
@@ -769,6 +837,9 @@ class CollectionManager(Client):
769
837
  full request body.
770
838
  output_format: str, default = "JSON"
771
839
  - one of "DICT", "MERMAID" or "JSON"
840
+ output_format_set: dict , optional, default = None
841
+ The desired output columns/fields to include.
842
+
772
843
 
773
844
  Returns
774
845
  -------
@@ -798,11 +869,15 @@ class CollectionManager(Client):
798
869
  }
799
870
  """
800
871
  return asyncio.get_event_loop().run_until_complete(
801
- self._async_get_collection_by_guid(collection_guid, collection_type, body, output_format))
872
+ self._async_get_collection_by_guid(collection_guid, collection_type, body,
873
+ output_format, output_format_set))
874
+
802
875
 
876
+ @dynamic_catch
803
877
  async def _async_get_collection_members(self, collection_guid: str = None, collection_name: str = None,
804
878
  collection_qname: str = None, body: dict = None, start_from: int = 0,
805
- page_size: int = 0, output_format: str = "JSON") -> list | str:
879
+ page_size: int = 0, output_format: str = "JSON",
880
+ output_format_set: str | dict = None) -> list | str:
806
881
  """Return a list of elements that are a member of a collection. Async version.
807
882
 
808
883
  Parameters
@@ -825,6 +900,8 @@ class CollectionManager(Client):
825
900
  the class instance.
826
901
  output_format: str, default = "JSON"
827
902
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
903
+ output_format_set: str | dict , optional, default = None
904
+ The desired output columns/fields to include.
828
905
 
829
906
  Returns
830
907
  -------
@@ -857,7 +934,8 @@ class CollectionManager(Client):
857
934
  """
858
935
 
859
936
  if collection_guid is None:
860
- collection_guid = self.__get_guid__(collection_guid, collection_name, "name", collection_qname, None, )
937
+ collection_guid = self.__get_guid__(collection_guid, collection_name, "name",
938
+ collection_qname, None, )
861
939
 
862
940
  url = (f"{self.collection_command_root}/{collection_guid}/"
863
941
  f"members?startFrom={start_from}&pageSize={page_size}")
@@ -867,17 +945,22 @@ class CollectionManager(Client):
867
945
  else:
868
946
  response = await self._async_make_request("POST", url)
869
947
 
870
- elements = response.json().get("elements", NO_ELEMENTS_FOUND)
948
+ elements = response.json().get("elements", NO_MEMBERS_FOUND)
871
949
  if type(elements) is str:
872
- return NO_ELEMENTS_FOUND
950
+ logger.trace(f"No elements found for collection {collection_guid}")
951
+ return NO_MEMBERS_FOUND
873
952
 
874
953
  if output_format != 'JSON': # return a simplified markdown representation
875
- return self.generate_collection_output(elements, None, None, output_format)
954
+ logger.debug(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
955
+ return self.generate_collection_output(elements, None, None,
956
+ output_format, output_format_set)
876
957
  return elements
877
958
 
959
+
878
960
  def get_collection_members(self, collection_guid: str = None, collection_name: str = None,
879
- collection_qname: str = None, body: dict = None, start_from: int = 0, page_size: int = 0,
880
- output_format: str = "JSON") -> list | str:
961
+ collection_qname: str = None, body: dict = None, start_from: int = 0,
962
+ page_size: int = 0,
963
+ output_format: str = "JSON", output_format_set: str | dict = None) -> list | str:
881
964
  """Return a list of elements that are a member of a collection.
882
965
  Parameters
883
966
  ----------
@@ -899,6 +982,8 @@ class CollectionManager(Client):
899
982
  the class instance.
900
983
  output_format: str, default = "JSON"
901
984
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
985
+ output_format_set: str | dict , optional, default = None
986
+ The desired output columns/fields to include.
902
987
 
903
988
  Returns
904
989
  -------
@@ -928,63 +1013,68 @@ class CollectionManager(Client):
928
1013
  "sequencingProperty": ""
929
1014
  }
930
1015
 
931
- """
1016
+ """
932
1017
  loop = asyncio.get_event_loop()
933
1018
  resp = loop.run_until_complete(
934
1019
  self._async_get_collection_members(collection_guid, collection_name, collection_qname, body, start_from,
935
- page_size, output_format))
1020
+ page_size, output_format, output_format_set))
936
1021
 
937
1022
  return resp
938
1023
 
1024
+
1025
+ @dynamic_catch
939
1026
  async def _async_get_collection_graph(self, collection_guid: str, body: dict = None, start_from: int = 0,
940
- page_size: int = 0, output_format: str = "JSON") -> list | str:
1027
+ page_size: int = 0, output_format: str = "JSON",
1028
+ output_format_set: str | dict = None) -> list | str:
941
1029
  """ Return a graph of elements that are the nested members of a collection along
942
- with elements immediately connected to the starting collection. The result
943
- includes a mermaid graph of the returned elements. Async version.
1030
+ with elements immediately connected to the starting collection. The result
1031
+ includes a mermaid graph of the returned elements. Async version.
944
1032
 
945
- Parameters
946
- ----------
947
- collection_guid: str,
948
- identity of the collection to return members for. If none, collection_name or
949
- collection_qname are used.
950
- body: dict, optional, default = None
951
- Providing the body allows full control of the request and replaces filter parameters.
952
- start_from: int, [default=0], optional
953
- When multiple pages of results are available, the page number to start from.
954
- page_size: int, [default=None]
955
- The number of items to return in a single page. If not specified, the default will be taken from
956
- the class instance.
957
- output_format: str, default = "JSON"
958
- - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
1033
+ Parameters
1034
+ ----------
1035
+ collection_guid: str,
1036
+ identity of the collection to return members for. If none, collection_name or
1037
+ collection_qname are used.
1038
+ body: dict, optional, default = None
1039
+ Providing the body allows full control of the request and replaces filter parameters.
1040
+ start_from: int, [default=0], optional
1041
+ When multiple pages of results are available, the page number to start from.
1042
+ page_size: int, [default=None]
1043
+ The number of items to return in a single page. If not specified, the default will be taken from
1044
+ the class instance.
1045
+ output_format: str, default = "JSON"
1046
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
1047
+ output_format_set: dict , optional, default = None
1048
+ The desired output columns/fields to include.
959
1049
 
960
- Returns
961
- -------
962
- List | str
1050
+ Returns
1051
+ -------
1052
+ List | str
963
1053
 
964
- A graph anchored in the collection.
1054
+ A graph anchored in the collection.
965
1055
 
966
- Raises
967
- ------
1056
+ Raises
1057
+ ------
968
1058
 
969
- InvalidParameterException
970
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
971
- PropertyServerException
972
- Raised by the server when an issue arises in processing a valid request
973
- NotAuthorizedException
974
- The principle specified by the user_id does not have authorization for the requested action
1059
+ InvalidParameterException
1060
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1061
+ PropertyServerException
1062
+ Raised by the server when an issue arises in processing a valid request
1063
+ NotAuthorizedException
1064
+ The principle specified by the user_id does not have authorization for the requested action
975
1065
 
976
- Notes:
977
- -----
978
- Body sample:
979
- {
980
- "class": "ResultsRequestBody",
981
- "effectiveTime": "{{$isoTimestamp}}",
982
- "limitResultsByStatus": ["ACTIVE"],
983
- "asOfTime": "{{$isoTimestamp}}",
984
- "sequencingOrder": "CREATION_DATE_RECENT",
985
- "sequencingProperty": ""
986
- }
987
- """
1066
+ Notes:
1067
+ -----
1068
+ Body sample:
1069
+ {
1070
+ "class": "ResultsRequestBody",
1071
+ "effectiveTime": "{{$isoTimestamp}}",
1072
+ "limitResultsByStatus": ["ACTIVE"],
1073
+ "asOfTime": "{{$isoTimestamp}}",
1074
+ "sequencingOrder": "CREATION_DATE_RECENT",
1075
+ "sequencingProperty": ""
1076
+ }
1077
+ """
988
1078
 
989
1079
  url = (f"{self.collection_command_root}/{collection_guid}/"
990
1080
  f"graph?startFrom={start_from}&pageSize={page_size}")
@@ -996,14 +1086,19 @@ class CollectionManager(Client):
996
1086
 
997
1087
  elements = response.json().get("graph", NO_ELEMENTS_FOUND)
998
1088
  if type(elements) is str:
1089
+ logger.info(NO_ELEMENTS_FOUND)
999
1090
  return NO_ELEMENTS_FOUND
1000
1091
 
1001
1092
  if output_format != 'JSON': # return a simplified markdown representation
1002
- return self.generate_collection_output(elements, None, None, output_format)
1093
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
1094
+ return self.generate_collection_output(elements, None, None,
1095
+ output_format, output_format_set)
1003
1096
  return elements
1004
1097
 
1098
+
1005
1099
  def get_collection_graph(self, collection_guid: str = None, body: dict = None, start_from: int = 0,
1006
- page_size: int = 0, output_format: str = "JSON") -> list | str:
1100
+ page_size: int = 0, output_format: str = "JSON",
1101
+ output_format_set: str | dict = None) -> list | str:
1007
1102
  """ Return a graph of elements that are the nested members of a collection along
1008
1103
  with elements immediately connected to the starting collection. The result
1009
1104
  includes a mermaid graph of the returned elements.
@@ -1022,6 +1117,8 @@ class CollectionManager(Client):
1022
1117
  the class instance.
1023
1118
  output_format: str, default = "JSON"
1024
1119
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
1120
+ output_format_set: str | dict , optional, default = None
1121
+ The desired output columns/fields to include.
1025
1122
 
1026
1123
  Returns
1027
1124
  -------
@@ -1052,10 +1149,14 @@ class CollectionManager(Client):
1052
1149
  }
1053
1150
  """
1054
1151
  return asyncio.get_event_loop().run_until_complete(
1055
- self._async_get_collection_graph(collection_guid, body, start_from, page_size, output_format))
1152
+ self._async_get_collection_graph(collection_guid, body, start_from, page_size,
1153
+ output_format, output_format_set))
1154
+
1056
1155
 
1156
+ @dynamic_catch
1057
1157
  async def _async_get_collection_graph_w_body(self, collection_guid: str, body: dict = None, start_from: int = 0,
1058
- page_size: int = None, output_format: str = "JSON") -> list | str:
1158
+ page_size: int = None, output_format: str = "JSON",
1159
+ output_format_set: str | dict = None) -> list | str:
1059
1160
  """ Return a graph of elements that are the nested members of a collection along
1060
1161
  with elements immediately connected to the starting collection. The result
1061
1162
  includes a mermaid graph of the returned elements. Async version.
@@ -1073,6 +1174,7 @@ class CollectionManager(Client):
1073
1174
  the class instance.
1074
1175
  output_format: str, default = "JSON"
1075
1176
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
1177
+ output_format_set: dict , optional, default = None
1076
1178
 
1077
1179
  Returns
1078
1180
  -------
@@ -1111,15 +1213,19 @@ class CollectionManager(Client):
1111
1213
  response = await self._async_make_request("GET", url, body_slimmer(body))
1112
1214
  elements = response.json().get("elements", NO_ELEMENTS_FOUND)
1113
1215
  if type(elements) is str:
1216
+ logger.info(NO_ELEMENTS_FOUND)
1114
1217
  return NO_ELEMENTS_FOUND
1115
1218
 
1116
1219
  if output_format != 'JSON': # return a simplified markdown representation
1117
- return self.generate_collection_output(elements, None, None, output_format)
1220
+ logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
1221
+ return self.generate_collection_output(elements, None, None,
1222
+ output_format, output_format_set)
1118
1223
  return elements
1119
1224
 
1120
- def get_collection_graph_w_body(self, collection_guid: str, body: dict = None, start_from: int = 0,
1121
- page_size: int = None, output_format: str = "JSON") -> list | str:
1122
1225
 
1226
+ def get_collection_graph_w_body(self, collection_guid: str, body: dict = None, start_from: int = 0,
1227
+ page_size: int = None, output_format: str = "JSON",
1228
+ output_format_set: str | dict = None) -> list | str:
1123
1229
  """ Return a graph of elements that are the nested members of a collection along
1124
1230
  with elements immediately connected to the starting collection. The result
1125
1231
  includes a mermaid graph of the returned elements.
@@ -1137,6 +1243,8 @@ class CollectionManager(Client):
1137
1243
  the class instance.
1138
1244
  output_format: str, default = "JSON"
1139
1245
  - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
1246
+ output_format_set: str | dict , optional, default = None
1247
+ The desired output columns/fields to include.
1140
1248
 
1141
1249
  Returns
1142
1250
  -------
@@ -1167,33 +1275,39 @@ class CollectionManager(Client):
1167
1275
  """
1168
1276
 
1169
1277
  return asyncio.get_event_loop().run_until_complete(
1170
- self._async_get_collection_graph_w_body(collection_guid, body, start_from, page_size, output_format))
1171
-
1172
- #
1173
- # Create collection methods
1174
- #
1175
-
1176
- ###
1177
- # =====================================================================================================================
1178
- # Create Collections: https://egeria-project.org/concepts/collection
1179
- # These requests use the following parameters:
1180
- #
1181
- # anchorGUID - the unique identifier of the element that should be the anchor for the new element. Set to null if
1182
- # no anchor,
1183
- # or if this collection is to be its own anchor.
1184
- #
1185
- # isOwnAnchor -this element should be classified as its own anchor or not. The default is false.
1186
- #
1187
- # parentGUID - the optional unique identifier for an element that should be connected to the newly created element.
1188
- # If this property is specified, parentRelationshipTypeName must also be specified
1189
- #
1190
- # parentRelationshipTypeName - the name of the relationship, if any, that should be established between the new
1191
- # element and the parent element.
1192
- # Examples could be "ResourceList" or "DigitalServiceProduct".
1193
- #
1194
- # parentAtEnd1 -identifies which end any parent entity sits on the relationship.
1195
- #
1196
-
1278
+ self._async_get_collection_graph_w_body(collection_guid, body, start_from,
1279
+ page_size, output_format, output_format_set))
1280
+
1281
+ #
1282
+ # Create collection methods
1283
+ #
1284
+
1285
+ ###
1286
+ # =====================================================================================================================
1287
+ # Create Collections: https://egeria-project.org/concepts/collection
1288
+ # These requests use the following parameters:
1289
+ #
1290
+ # anchorGUID - the unique identifier of the element that should be the anchor for the new element. Set to
1291
+ # null if
1292
+ # no anchor,
1293
+ # or if this collection is to be its own anchor.
1294
+ #
1295
+ # isOwnAnchor -this element should be classified as its own anchor or not. The default is false.
1296
+ #
1297
+ # parentGUID - the optional unique identifier for an element that should be connected to the newly
1298
+ # created element.
1299
+ # If this property is specified, parentRelationshipTypeName must also be specified
1300
+ #
1301
+ # parentRelationshipTypeName - the name of the relationship, if any, that should be established between
1302
+ # the new
1303
+ # element and the parent element.
1304
+ # Examples could be "ResourceList" or "DigitalServiceProduct".
1305
+ #
1306
+ # parentAtEnd1 -identifies which end any parent entity sits on the relationship.
1307
+ #
1308
+
1309
+
1310
+ @dynamic_catch
1197
1311
  async def _async_create_collection_w_body(self, body: dict, classification_name: str = None) -> str:
1198
1312
  """ Create a new generic collection.
1199
1313
  Collections: https://egeria-project.org/concepts/collection
@@ -1259,7 +1373,9 @@ class CollectionManager(Client):
1259
1373
  url = f"{self.collection_command_root}{possible_query_params}"
1260
1374
 
1261
1375
  resp = await self._async_make_request("POST", url, body)
1262
- return resp.json().get("guid", "No GUID returned")
1376
+ logger.info(f"Create collection with GUID: {resp.json().get['guid']}")
1377
+ return resp.json().get("guid", NO_GUID_RETURNED)
1378
+
1263
1379
 
1264
1380
  def create_collection_w_body(self, body: dict, classification_name: str = None, ) -> str:
1265
1381
  """ Create a new generic collection.
@@ -1323,6 +1439,8 @@ class CollectionManager(Client):
1323
1439
  return asyncio.get_event_loop().run_until_complete(
1324
1440
  self._async_create_collection_w_body(body, classification_name))
1325
1441
 
1442
+
1443
+ @dynamic_catch
1326
1444
  async def _async_create_collection(self, display_name: str, description: str, is_own_anchor: bool = True,
1327
1445
  classification_name: str = None, anchor_guid: str = None,
1328
1446
  parent_guid: str = None, parent_relationship_type_name: str = None,
@@ -1403,7 +1521,8 @@ class CollectionManager(Client):
1403
1521
  }
1404
1522
 
1405
1523
  resp = await self._async_make_request("POST", url, body_slimmer(body))
1406
- return resp.json().get("guid", "No GUID returned")
1524
+ return resp.json().get("guid", NO_GUID_RETURNED)
1525
+
1407
1526
 
1408
1527
  def create_collection(self, display_name: str, description: str, is_own_anchor: bool = True,
1409
1528
  classification_name: str = None, anchor_guid: str = None, parent_guid: str = None,
@@ -1460,11 +1579,16 @@ class CollectionManager(Client):
1460
1579
 
1461
1580
  """
1462
1581
  return asyncio.get_event_loop().run_until_complete(
1463
- self._async_create_collection(display_name, description, is_own_anchor, classification_name, anchor_guid,
1464
- parent_guid, parent_relationship_type_name, parent_at_end1, collection_type,
1582
+ self._async_create_collection(display_name, description, is_own_anchor, classification_name,
1583
+ anchor_guid,
1584
+ parent_guid, parent_relationship_type_name, parent_at_end1,
1585
+ collection_type,
1465
1586
  anchor_scope_guid, additional_properties, extended_properties))
1466
1587
 
1467
- async def _async_create_generic_collection(self, display_name: str, description: str, qualified_name: str = None,
1588
+
1589
+ @dynamic_catch
1590
+ async def _async_create_generic_collection(self, display_name: str, description: str,
1591
+ qualified_name: str = None,
1468
1592
  is_own_anchor: bool = True, url_item=None,
1469
1593
  classification_name: str = None, anchor_guid: str = None,
1470
1594
  parent_guid: str = None, parent_relationship_type_name: str = None,
@@ -1550,8 +1674,12 @@ class CollectionManager(Client):
1550
1674
  }
1551
1675
 
1552
1676
  resp = await self._async_make_request("POST", url, body_slimmer(body))
1553
- return resp.json().get("guid", "No GUID returned")
1677
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
1678
+ logger.info(f"Create collection with GUID: {guid}")
1679
+ return guid
1554
1680
 
1681
+
1682
+ @dynamic_catch
1555
1683
  async def _async_create_root_collection(self, display_name: str, description: str, qualified_name: str = None,
1556
1684
  is_own_anchor: bool = True, anchor_guid: str = None,
1557
1685
  parent_guid: str = None, parent_relationship_type_name: str = None,
@@ -1560,7 +1688,8 @@ class CollectionManager(Client):
1560
1688
 
1561
1689
  additional_properties: dict = None,
1562
1690
  extended_properties: dict = None) -> str:
1563
- """ Create a new collection with the RootCollection classification. Used to identify the top of a collection
1691
+ """ Create a new collection with the RootCollection classification. Used to identify the top of a
1692
+ collection
1564
1693
  hierarchy.
1565
1694
  Create Collections: https://egeria-project.org/concepts/collection
1566
1695
  Async version.
@@ -1624,6 +1753,7 @@ class CollectionManager(Client):
1624
1753
 
1625
1754
  return resp
1626
1755
 
1756
+
1627
1757
  def create_root_collection(self, display_name: str, description: str, qualified_name: str = None,
1628
1758
  is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
1629
1759
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
@@ -1681,13 +1811,17 @@ class CollectionManager(Client):
1681
1811
  """
1682
1812
  loop = asyncio.get_event_loop()
1683
1813
  resp = loop.run_until_complete(
1684
- self._async_create_root_collection(display_name, description, qualified_name, is_own_anchor, anchor_guid,
1814
+ self._async_create_root_collection(display_name, description, qualified_name, is_own_anchor,
1815
+ anchor_guid,
1685
1816
  parent_guid, parent_relationship_type_name, parent_at_end1,
1686
1817
  collection_type, anchor_scope_guid, additional_properties,
1687
1818
  extended_properties))
1688
1819
  return resp
1689
1820
 
1690
- async def _async_create_data_spec_collection(self, display_name: str, description: str, qualified_name: str = None,
1821
+
1822
+ @dynamic_catch
1823
+ async def _async_create_data_spec_collection(self, display_name: str, description: str,
1824
+ qualified_name: str = None,
1691
1825
  is_own_anchor: bool = True, anchor_guid: str = None,
1692
1826
  parent_guid: str = None, parent_relationship_type_name: str = None,
1693
1827
  parent_at_end1: bool = True, collection_type: str = None,
@@ -1745,7 +1879,8 @@ class CollectionManager(Client):
1745
1879
  """
1746
1880
 
1747
1881
  resp = await self._async_create_generic_collection(display_name, description, qualified_name,
1748
- is_own_anchor=is_own_anchor, url_item="data-spec-collection",
1882
+ is_own_anchor=is_own_anchor,
1883
+ url_item="data-spec-collection",
1749
1884
  classification_name="DataSpec", anchor_guid=anchor_guid,
1750
1885
  parent_guid=parent_guid,
1751
1886
  parent_relationship_type_name=parent_relationship_type_name,
@@ -1757,6 +1892,7 @@ class CollectionManager(Client):
1757
1892
 
1758
1893
  return resp
1759
1894
 
1895
+
1760
1896
  def create_data_spec_collection(self, display_name: str, description: str, qualified_name: str = None,
1761
1897
  is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
1762
1898
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
@@ -1820,6 +1956,8 @@ class CollectionManager(Client):
1820
1956
  additional_properties, extended_properties))
1821
1957
  return resp
1822
1958
 
1959
+
1960
+ @dynamic_catch
1823
1961
  async def _async_create_data_dictionary_collection(self, display_name: str, description: str,
1824
1962
  qualified_name: str = None, is_own_anchor: bool = True,
1825
1963
  anchor_guid: str = None, parent_guid: str = None,
@@ -1893,12 +2031,15 @@ class CollectionManager(Client):
1893
2031
 
1894
2032
  return resp
1895
2033
 
2034
+
1896
2035
  def create_data_dictionary_collection(self, display_name: str, description: str, qualified_name: str = None,
1897
- is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
2036
+ is_own_anchor: bool = True, anchor_guid: str = None,
2037
+ parent_guid: str = None,
1898
2038
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
1899
2039
  collection_type: str = None, anchor_scope_guid: str = None,
1900
2040
 
1901
- additional_properties: dict = None, extended_properties: dict = None) -> str:
2041
+ additional_properties: dict = None,
2042
+ extended_properties: dict = None) -> str:
1902
2043
  """ Create a new collection with the DataSpec classification. Used to identify a collection of data
1903
2044
  structures and
1904
2045
  data fields used to define data requirements for a project or initiative.
@@ -1956,6 +2097,8 @@ class CollectionManager(Client):
1956
2097
  additional_properties, extended_properties))
1957
2098
  return resp
1958
2099
 
2100
+
2101
+ @dynamic_catch
1959
2102
  async def _async_create_folder_collection(self, display_name: str, description: str, qualified_name: str = None,
1960
2103
  is_own_anchor: bool = True, anchor_guid: str = None,
1961
2104
  parent_guid: str = None, parent_relationship_type_name: str = None,
@@ -1964,7 +2107,8 @@ class CollectionManager(Client):
1964
2107
 
1965
2108
  additional_properties: dict = None,
1966
2109
  extended_properties: dict = None) -> str:
1967
- """ Create a new collection with the Folder classification. This is used to identify the organizing collections
2110
+ """ Create a new collection with the Folder classification. This is used to identify the organizing
2111
+ collections
1968
2112
  in a collection hierarchy.
1969
2113
  Async version.
1970
2114
 
@@ -2027,13 +2171,15 @@ class CollectionManager(Client):
2027
2171
 
2028
2172
  return resp
2029
2173
 
2174
+
2030
2175
  def create_folder_collection(self, display_name: str, description: str, qualified_name: str = None,
2031
2176
  is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
2032
2177
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
2033
2178
  collection_type: str = None, anchor_scope_guid: str = None,
2034
2179
 
2035
2180
  additional_properties: dict = None, extended_properties: dict = None) -> str:
2036
- """ Create a new collection with the Folder classification. This is used to identify the organizing collections
2181
+ """ Create a new collection with the Folder classification. This is used to identify the organizing
2182
+ collections
2037
2183
  in a collection hierarchy.
2038
2184
 
2039
2185
  Parameters
@@ -2083,18 +2229,22 @@ class CollectionManager(Client):
2083
2229
  """
2084
2230
  loop = asyncio.get_event_loop()
2085
2231
  resp = loop.run_until_complete(
2086
- self._async_create_folder_collection(display_name, description, qualified_name, is_own_anchor, anchor_guid,
2232
+ self._async_create_folder_collection(display_name, description, qualified_name, is_own_anchor,
2233
+ anchor_guid,
2087
2234
  parent_guid, parent_relationship_type_name, parent_at_end1,
2088
2235
  collection_type, anchor_scope_guid, additional_properties,
2089
2236
  extended_properties))
2090
2237
  return resp
2091
2238
 
2239
+
2240
+ @dynamic_catch
2092
2241
  async def _async_create_context_event_collection(self, display_name: str, description: str,
2093
2242
  qualified_name: str = None, is_own_anchor: bool = True,
2094
2243
  anchor_guid: str = None, parent_guid: str = None,
2095
2244
  parent_relationship_type_name: str = None,
2096
2245
  parent_at_end1: bool = True, collection_type: str = None,
2097
- anchor_scope_guid: str = None, additional_properties: dict = None,
2246
+ anchor_scope_guid: str = None,
2247
+ additional_properties: dict = None,
2098
2248
  extended_properties: dict = None) -> str:
2099
2249
  """ Create a new collection with the ContextEventCollection classification. This is used to group context
2100
2250
  events together.
@@ -2161,12 +2311,15 @@ class CollectionManager(Client):
2161
2311
 
2162
2312
  return resp
2163
2313
 
2314
+
2164
2315
  def create_context_event_collection(self, display_name: str, description: str, qualified_name: str = None,
2165
- is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
2316
+ is_own_anchor: bool = True, anchor_guid: str = None,
2317
+ parent_guid: str = None,
2166
2318
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
2167
2319
  collection_type: str = None, anchor_scope_guid: str = None,
2168
2320
 
2169
- additional_properties: dict = None, extended_properties: dict = None) -> str:
2321
+ additional_properties: dict = None,
2322
+ extended_properties: dict = None) -> str:
2170
2323
  """ Create a new collection with the ContextEventCollection classification. This is used to group context
2171
2324
  events together.
2172
2325
  For example, the collection may be a series of events that affect a set of resources.
@@ -2224,13 +2377,18 @@ class CollectionManager(Client):
2224
2377
  additional_properties, extended_properties))
2225
2378
  return resp
2226
2379
 
2227
- async def _async_create_name_space_collection(self, display_name: str, description: str, qualified_name: str = None,
2380
+
2381
+ @dynamic_catch
2382
+ async def _async_create_name_space_collection(self, display_name: str, description: str,
2383
+ qualified_name: str = None,
2228
2384
  is_own_anchor: bool = True, anchor_guid: str = None,
2229
- parent_guid: str = None, parent_relationship_type_name: str = None,
2385
+ parent_guid: str = None,
2386
+ parent_relationship_type_name: str = None,
2230
2387
  parent_at_end1: bool = True, collection_type: str = None,
2231
2388
  anchor_scope_guid: str = None, additional_properties: dict = None,
2232
2389
  extended_properties: dict = None) -> str:
2233
- """ Create a new collection with the Namespace classification. This is used to group elements that belong to
2390
+ """ Create a new collection with the Namespace classification. This is used to group elements that
2391
+ belong to
2234
2392
  the same namespace.
2235
2393
  For example, the collection may be a series of processes that are recording OpenLineage under a single
2236
2394
  namespace.
@@ -2283,7 +2441,8 @@ class CollectionManager(Client):
2283
2441
  """
2284
2442
 
2285
2443
  resp = await self._async_create_generic_collection(display_name, description, qualified_name,
2286
- is_own_anchor=is_own_anchor, url_item="namespace-collection",
2444
+ is_own_anchor=is_own_anchor,
2445
+ url_item="namespace-collection",
2287
2446
  classification_name="NamespaceCollection",
2288
2447
  anchor_guid=anchor_guid, parent_guid=parent_guid,
2289
2448
  parent_relationship_type_name=parent_relationship_type_name,
@@ -2295,13 +2454,14 @@ class CollectionManager(Client):
2295
2454
 
2296
2455
  return resp
2297
2456
 
2457
+
2298
2458
  def create_name_space_collection(self, display_name: str, description: str, qualified_name: str = None,
2299
2459
  is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
2300
2460
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
2301
2461
  collection_type: str = None, anchor_scope_guid: str = None,
2302
-
2303
2462
  additional_properties: dict = None, extended_properties: dict = None) -> str:
2304
- """ Create a new collection with the Namespace classification. This is used to group elements that belong to
2463
+ """ Create a new collection with the Namespace classification. This is used to group elements that
2464
+ belong to
2305
2465
  the same namespace.
2306
2466
  For example, the collection may be a series of processes that are recording OpenLineage under a single
2307
2467
  namespace.
@@ -2358,7 +2518,10 @@ class CollectionManager(Client):
2358
2518
  parent_at_end1, collection_type, anchor_scope_guid))
2359
2519
  return resp
2360
2520
 
2361
- async def _async_create_event_set_collection(self, display_name: str, description: str, qualified_name: str = None,
2521
+
2522
+ @dynamic_catch
2523
+ async def _async_create_event_set_collection(self, display_name: str, description: str,
2524
+ qualified_name: str = None,
2362
2525
  is_own_anchor: bool = True, anchor_guid: str = None,
2363
2526
  parent_guid: str = None, parent_relationship_type_name: str = None,
2364
2527
  parent_at_end1: bool = True, collection_type: str = None,
@@ -2418,7 +2581,8 @@ class CollectionManager(Client):
2418
2581
  """
2419
2582
 
2420
2583
  resp = await self._async_create_generic_collection(display_name, description, qualified_name,
2421
- is_own_anchor=is_own_anchor, url_item="event-set-collection",
2584
+ is_own_anchor=is_own_anchor,
2585
+ url_item="event-set-collection",
2422
2586
  classification_name="EventSetCollection",
2423
2587
  anchor_guid=anchor_guid, parent_guid=parent_guid,
2424
2588
  parent_relationship_type_name=parent_relationship_type_name,
@@ -2430,6 +2594,7 @@ class CollectionManager(Client):
2430
2594
 
2431
2595
  return resp
2432
2596
 
2597
+
2433
2598
  def create_event_set_collection(self, display_name: str, description: str, qualified_name: str = None,
2434
2599
  is_own_anchor: bool = True, anchor_guid: str = None, parent_guid: str = None,
2435
2600
  parent_relationship_type_name: str = None, parent_at_end1: bool = True,
@@ -2493,11 +2658,15 @@ class CollectionManager(Client):
2493
2658
  additional_properties, extended_properties))
2494
2659
  return resp
2495
2660
 
2661
+
2662
+ @dynamic_catch
2496
2663
  async def _async_create_naming_standard_ruleset_collection(self, display_name: str, description: str,
2497
- qualified_name: str = None, is_own_anchor: bool = True,
2664
+ qualified_name: str = None,
2665
+ is_own_anchor: bool = True,
2498
2666
  anchor_guid: str = None, parent_guid: str = None,
2499
2667
  parent_relationship_type_name: str = None,
2500
- parent_at_end1: bool = True, collection_type: str = None,
2668
+ parent_at_end1: bool = True,
2669
+ collection_type: str = None,
2501
2670
  anchor_scope_guid: str = None,
2502
2671
  additional_properties: dict = None,
2503
2672
  extended_properties: dict = None) -> str:
@@ -2566,9 +2735,12 @@ class CollectionManager(Client):
2566
2735
 
2567
2736
  return resp
2568
2737
 
2569
- def create_naming_standard_ruleset_collection(self, display_name: str, description: str, qualified_name: str = None,
2738
+
2739
+ def create_naming_standard_ruleset_collection(self, display_name: str, description: str,
2740
+ qualified_name: str = None,
2570
2741
  is_own_anchor: bool = True, anchor_guid: str = None,
2571
- parent_guid: str = None, parent_relationship_type_name: str = None,
2742
+ parent_guid: str = None,
2743
+ parent_relationship_type_name: str = None,
2572
2744
  parent_at_end1: bool = True, collection_type: str = None,
2573
2745
  anchor_scope_guid: str = None, additional_properties: dict = None,
2574
2746
  extended_properties: dict = None) -> str:
@@ -2629,9 +2801,12 @@ class CollectionManager(Client):
2629
2801
  collection_type, anchor_scope_guid))
2630
2802
  return resp
2631
2803
 
2632
- #
2633
- #
2634
- #
2804
+ #
2805
+ #
2806
+ #
2807
+
2808
+
2809
+ @dynamic_catch
2635
2810
  async def _async_create_collection_from_template(self, body: dict) -> str:
2636
2811
  """Create a new metadata element to represent a collection using an existing metadata element as a template.
2637
2812
  The template defines additional classifications and relationships that are added to the new collection.
@@ -2690,7 +2865,10 @@ class CollectionManager(Client):
2690
2865
  url = f"{self.collection_command_root}/from-template"
2691
2866
 
2692
2867
  resp = await self._async_make_request("POST", url, body)
2693
- return resp.json().get("guid", "No GUID Returned")
2868
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
2869
+ logger.info(f"Create collection with GUID: {guid}")
2870
+ return guid
2871
+
2694
2872
 
2695
2873
  def create_collection_from_template(self, body: dict) -> str:
2696
2874
  """Create a new metadata element to represent a collection using an existing metadata element as a template.
@@ -2747,10 +2925,14 @@ class CollectionManager(Client):
2747
2925
  resp = loop.run_until_complete(self._async_create_collection_from_template(body))
2748
2926
  return resp
2749
2927
 
2750
- #
2751
- # Manage collections
2752
- #
2753
- async def _async_update_collection(self, collection_guid: str, qualified_name: str = None, display_name: str = None,
2928
+ #
2929
+ # Manage collections
2930
+ #
2931
+
2932
+
2933
+ @dynamic_catch
2934
+ async def _async_update_collection(self, collection_guid: str, qualified_name: str = None,
2935
+ display_name: str = None,
2754
2936
  description: str = None, collection_type: str = None,
2755
2937
 
2756
2938
  additional_properties: dict = None, extended_properties: dict = None,
@@ -2804,6 +2986,8 @@ class CollectionManager(Client):
2804
2986
  }
2805
2987
  body_s = body_slimmer(body)
2806
2988
  await self._async_make_request("POST", url, body_s)
2989
+ logger.info(f"Successfully updated {collection_guid}")
2990
+
2807
2991
 
2808
2992
  def update_collection(self, collection_guid, qualified_name: str = None, display_name: str = None,
2809
2993
  description: str = None, collection_type: str = None, additional_properties: dict = None,
@@ -2845,10 +3029,13 @@ class CollectionManager(Client):
2845
3029
  """
2846
3030
  loop = asyncio.get_event_loop()
2847
3031
  loop.run_until_complete(
2848
- self._async_update_collection(collection_guid, qualified_name, display_name, description, collection_type,
3032
+ self._async_update_collection(collection_guid, qualified_name, display_name, description,
3033
+ collection_type,
2849
3034
 
2850
3035
  additional_properties, extended_properties, replace_all_props))
2851
3036
 
3037
+
3038
+ @dynamic_catch
2852
3039
  async def _async_update_collection_w_body(self, collection_guid: str, body: dict,
2853
3040
  replace_all_props: bool = False) -> None:
2854
3041
  """Update the properties of a collection. Async version.
@@ -2900,6 +3087,8 @@ class CollectionManager(Client):
2900
3087
 
2901
3088
  body_s = body_slimmer(body)
2902
3089
  await self._async_make_request("POST", url, body_s)
3090
+ logger.info(f"Updated properties of collection {collection_guid}")
3091
+
2903
3092
 
2904
3093
  def update_collection_w_body(self, collection_guid: str, body: dict, replace_all_props: bool = False) -> None:
2905
3094
  """Update the properties of a collection.
@@ -2949,9 +3138,12 @@ class CollectionManager(Client):
2949
3138
  loop = asyncio.get_event_loop()
2950
3139
  loop.run_until_complete(self._async_update_collection_w_body(collection_guid, body, replace_all_props))
2951
3140
 
2952
- #
2953
- # Digital Products
2954
- #
3141
+ #
3142
+ # Digital Products
3143
+ #
3144
+
3145
+
3146
+ @dynamic_catch
2955
3147
  async def _async_create_digital_product(self, body: dict) -> str:
2956
3148
  """ Create a new collection that represents a digital product. To set a lifecycle status
2957
3149
  use a NewDigitalProductRequestBody which has a default status of DRAFT. Using a
@@ -3063,7 +3255,10 @@ class CollectionManager(Client):
3063
3255
  url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
3064
3256
 
3065
3257
  resp = await self._async_make_request("POST", url, body_slimmer(body))
3066
- return resp.json().get("guid", "No GUID returned")
3258
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
3259
+ logger.info(f"Create collection with GUID: {guid}")
3260
+ return guid
3261
+
3067
3262
 
3068
3263
  def create_digital_product(self, body: dict) -> str:
3069
3264
  """ Create a new collection that represents a digital product. To set a lifecycle status
@@ -3175,7 +3370,10 @@ class CollectionManager(Client):
3175
3370
  resp = loop.run_until_complete(self._async_create_digital_product(body))
3176
3371
  return resp
3177
3372
 
3178
- async def _async_update_digital_product(self, collection_guid: str, body: dict, replace_all_props: bool = False, ):
3373
+
3374
+ @dynamic_catch
3375
+ async def _async_update_digital_product(self, collection_guid: str, body: dict,
3376
+ replace_all_props: bool = False, ):
3179
3377
  """Update the properties of the DigitalProduct classification attached to a collection. Async version.
3180
3378
 
3181
3379
  Parameters
@@ -3229,6 +3427,8 @@ class CollectionManager(Client):
3229
3427
  f"{collection_guid}/update?replaceAllProperties={replace_all_props_s}")
3230
3428
 
3231
3429
  await self._async_make_request("POST", url, body)
3430
+ logger.info(f'Updated properties of DigitalProduct: {collection_guid}')
3431
+
3232
3432
 
3233
3433
  def update_digital_product(self, collection_guid: str, body: dict, replace_all_props: bool = False, ):
3234
3434
  """Update the properties of the DigitalProduct classification attached to a collection.
@@ -3280,6 +3480,8 @@ class CollectionManager(Client):
3280
3480
  loop = asyncio.get_event_loop()
3281
3481
  loop.run_until_complete(self._async_update_digital_product(collection_guid, body, replace_all_props))
3282
3482
 
3483
+
3484
+ @dynamic_catch
3283
3485
  async def _async_update_digital_product_status(self, digital_prod_guid: str, body: dict):
3284
3486
  """Update the status of a DigitalProduct collection. Async version.
3285
3487
 
@@ -3318,11 +3520,14 @@ class CollectionManager(Client):
3318
3520
  """
3319
3521
 
3320
3522
  url = (
3321
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3523
+ f"{self.platform_url}/servers/"
3524
+ f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3322
3525
  f"-products/"
3323
3526
  f"{digital_prod_guid}/update=status")
3324
3527
 
3325
3528
  await self._async_make_request("POST", url, body)
3529
+ logger.info(f'Updated status of DigitalProduct: {digital_prod_guid}')
3530
+
3326
3531
 
3327
3532
  def update_digital_product_status(self, digital_prod_guid: str, body: dict):
3328
3533
  """Update the status of a DigitalProduct collection. Async version.
@@ -3364,6 +3569,8 @@ class CollectionManager(Client):
3364
3569
  loop = asyncio.get_event_loop()
3365
3570
  loop.run_until_complete(self._async_update_digital_product_status(digital_prod_guid, body))
3366
3571
 
3572
+
3573
+ @dynamic_catch
3367
3574
  async def _async_link_digital_product_dependency(self, upstream_digital_prod_guid: str,
3368
3575
  downstream_digital_prod_guid: str, body: dict = None):
3369
3576
  """ Link two dependent digital products. The linked elements are of type DigitalProduct.
@@ -3412,13 +3619,16 @@ class CollectionManager(Client):
3412
3619
  """
3413
3620
 
3414
3621
  url = (
3415
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3622
+ f"{self.platform_url}/servers/"
3623
+ f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3416
3624
  f"-products/"
3417
3625
  f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/attach")
3418
3626
  if body:
3419
3627
  await self._async_make_request("POST", url, body)
3420
3628
  else:
3421
3629
  await self._async_make_request("POST", url)
3630
+ logger.info(f"Linked {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
3631
+
3422
3632
 
3423
3633
  def link_digital_product_dependency(self, upstream_digital_prod_guid: str, downstream_digital_prod_guid: str,
3424
3634
  body: dict = None):
@@ -3468,8 +3678,11 @@ class CollectionManager(Client):
3468
3678
  """
3469
3679
  loop = asyncio.get_event_loop()
3470
3680
  loop.run_until_complete(
3471
- self._async_link_digital_product_dependency(upstream_digital_prod_guid, downstream_digital_prod_guid, body))
3681
+ self._async_link_digital_product_dependency(upstream_digital_prod_guid, downstream_digital_prod_guid,
3682
+ body))
3683
+
3472
3684
 
3685
+ @dynamic_catch
3473
3686
  async def _async_detach_digital_product_dependency(self, upstream_digital_prod_guid: str,
3474
3687
  downstream_digital_prod_guid: str, body: dict = None):
3475
3688
  """ Unlink two dependent digital products. The linked elements are of type DigitalProduct.
@@ -3511,14 +3724,18 @@ class CollectionManager(Client):
3511
3724
  """
3512
3725
 
3513
3726
  url = (
3514
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3727
+ f"{self.platform_url}/servers/"
3728
+ f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3515
3729
  f"-products/"
3516
3730
  f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/detach")
3517
3731
  if body:
3518
3732
  await self._async_make_request("POST", url, body)
3519
3733
  else:
3520
3734
  await self._async_make_request("POST", url)
3735
+ logger.info(f"Detached digital product dependency {upstream_digital_prod_guid}, {downstream_digital_prod_guid}")
3521
3736
 
3737
+
3738
+ @dynamic_catch
3522
3739
  async def _async_link_product_manager(self, digital_prod_guid: str, digital_prod_manager_guid: str,
3523
3740
  body: dict = None) -> None:
3524
3741
  """ Attach a product manager to a digital product. Request body is optional.
@@ -3560,13 +3777,16 @@ class CollectionManager(Client):
3560
3777
  """
3561
3778
 
3562
3779
  url = (
3563
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3780
+ f"{self.platform_url}/servers/"
3781
+ f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3564
3782
  f"-products/"
3565
3783
  f"{digital_prod_guid}/product-managers/{digital_prod_manager_guid}/attach")
3566
3784
  if body:
3567
3785
  await self._async_make_request("POST", url, body)
3568
3786
  else:
3569
3787
  await self._async_make_request("POST", url)
3788
+ logger.info(f"Attached digital product manager {digital_prod_manager_guid} to {digital_prod_guid}")
3789
+
3570
3790
 
3571
3791
  def link_product_manager(self, digital_prod_guid: str, digital_prod_manager_guid: str, body: dict = None):
3572
3792
  """ Link a product manager to a digital product.
@@ -3607,8 +3827,11 @@ class CollectionManager(Client):
3607
3827
  }
3608
3828
  """
3609
3829
  loop = asyncio.get_event_loop()
3610
- loop.run_until_complete(self._async_link_product_manager(digital_prod_guid, digital_prod_manager_guid, body))
3830
+ loop.run_until_complete(
3831
+ self._async_link_product_manager(digital_prod_guid, digital_prod_manager_guid, body))
3832
+
3611
3833
 
3834
+ @dynamic_catch
3612
3835
  async def _async_detach_product_manager(self, digital_prod_guid: str, digital_prod_manager_guid: str,
3613
3836
  body: dict = None):
3614
3837
  """ Detach a product manager from a digital product. Request body is optional.
@@ -3650,13 +3873,16 @@ class CollectionManager(Client):
3650
3873
  """
3651
3874
 
3652
3875
  url = (
3653
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3876
+ f"{self.platform_url}/servers/"
3877
+ f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
3654
3878
  f"-products/"
3655
3879
  f"{digital_prod_guid}/product-managers/{digital_prod_manager_guid}/detach")
3656
3880
  if body:
3657
3881
  await self._async_make_request("POST", url, body)
3658
3882
  else:
3659
3883
  await self._async_make_request("POST", url)
3884
+ logger.info(f'Detached product manager {digital_prod_manager_guid} from {digital_prod_guid}')
3885
+
3660
3886
 
3661
3887
  def detach_product_manager(self, digital_prod_guid: str, digital_prod_manager_guid: str, body: dict = None):
3662
3888
  """ Detach a product manager from a digital product. Request body is optional.
@@ -3696,11 +3922,15 @@ class CollectionManager(Client):
3696
3922
  }
3697
3923
  """
3698
3924
  loop = asyncio.get_event_loop()
3699
- loop.run_until_complete(self._async_detach_product_manager(digital_prod_guid, digital_prod_manager_guid, body))
3925
+ loop.run_until_complete(
3926
+ self._async_detach_product_manager(digital_prod_guid, digital_prod_manager_guid, body))
3927
+
3928
+ #
3929
+ # Agreements
3930
+ #
3700
3931
 
3701
- #
3702
- # Agreements
3703
- #
3932
+
3933
+ @dynamic_catch
3704
3934
  async def _async_create_agreement(self, body: dict) -> str:
3705
3935
  """Create a new collection that represents am agreement. Async version.
3706
3936
 
@@ -3790,7 +4020,10 @@ class CollectionManager(Client):
3790
4020
  url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
3791
4021
 
3792
4022
  resp = await self._async_make_request("POST", url, body_slimmer(body))
3793
- return resp.json().get("guid", "No GUID returned")
4023
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
4024
+ logger.info(f"Create collection with GUID: {guid}")
4025
+ return guid
4026
+
3794
4027
 
3795
4028
  def create_agreement(self, body: dict) -> str:
3796
4029
  """Create a new collection that represents am agreement. Async version.
@@ -3881,6 +4114,8 @@ class CollectionManager(Client):
3881
4114
  resp = loop.run_until_complete(self._async_create_agreement(body))
3882
4115
  return resp
3883
4116
 
4117
+
4118
+ @dynamic_catch
3884
4119
  async def _async_create_data_sharing_agreement(self, body: dict) -> str:
3885
4120
  """ Create a new collection with the DataSharingAgreement classification. The collection is typically
3886
4121
  an agreement which may use the NewElementRequestBody, or the NewAgreementRequestBody if the
@@ -3938,11 +4173,15 @@ class CollectionManager(Client):
3938
4173
  }
3939
4174
  """
3940
4175
 
3941
- url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/data"
3942
- f"-sharing-agreement")
4176
+ url = (
4177
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/data"
4178
+ f"-sharing-agreement")
3943
4179
 
3944
4180
  resp = await self._async_make_request("POST", url, body_slimmer(body))
3945
- return resp.json().get("guid", "No GUID returned")
4181
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
4182
+ logger.info(f"Create collection with GUID: {guid}")
4183
+ return guid
4184
+
3946
4185
 
3947
4186
  def create_data_sharing_agreement(self, body: dict) -> str:
3948
4187
  """ Create a new collection with the DataSharingAgreement classification. The collection is typically
@@ -4004,6 +4243,8 @@ class CollectionManager(Client):
4004
4243
  resp = loop.run_until_complete(self._async_create_data_sharing_agreement(body))
4005
4244
  return resp
4006
4245
 
4246
+
4247
+ @dynamic_catch
4007
4248
  async def _async_update_agreement(self, agreement_guid: str, body: dict, replace_all_props: bool = False, ):
4008
4249
  """Update the properties of the agreement collection. Async version.
4009
4250
 
@@ -4061,6 +4302,8 @@ class CollectionManager(Client):
4061
4302
  f"{agreement_guid}/update?replaceAllProperties={replace_all_props_s}")
4062
4303
 
4063
4304
  await self._async_make_request("POST", url, body)
4305
+ logger.info(f"Updated properties for agreement {agreement_guid}")
4306
+
4064
4307
 
4065
4308
  def update_agreement(self, agreement_guid: str, body: dict, replace_all_props: bool = False, ):
4066
4309
  """Update the properties of the DigitalProduct classification attached to a collection.
@@ -4116,6 +4359,8 @@ class CollectionManager(Client):
4116
4359
  loop = asyncio.get_event_loop()
4117
4360
  loop.run_until_complete(self._async_update_digital_product(agreement_guid, body, replace_all_props))
4118
4361
 
4362
+
4363
+ @dynamic_catch
4119
4364
  async def _async_update_agreement_status(self, agreement_guid: str, body: dict):
4120
4365
  """Update the status of an agreement collection. Async version.
4121
4366
 
@@ -4159,6 +4404,8 @@ class CollectionManager(Client):
4159
4404
  f"{agreement_guid}/update-status")
4160
4405
 
4161
4406
  await self._async_make_request("POST", url, body)
4407
+ logger.info(f"Updated status for agreement {agreement_guid}")
4408
+
4162
4409
 
4163
4410
  def update_agreement_status(self, agreement_guid: str, body: dict):
4164
4411
  """Update the status of an agreement collection. Async version.
@@ -4200,8 +4447,11 @@ class CollectionManager(Client):
4200
4447
  loop = asyncio.get_event_loop()
4201
4448
  loop.run_until_complete(self._async_update_agreement_status(agreement_guid, body))
4202
4449
 
4450
+
4451
+ @dynamic_catch
4203
4452
  async def _async_link_agreement_actor(self, agreement_guid: str, actor_guid: str, body: dict = None):
4204
- """ Attach an actor to an agreement. The actor element may be an actor profile (person, team or IT profile);
4453
+ """ Attach an actor to an agreement. The actor element may be an actor profile (person, team or IT
4454
+ profile);
4205
4455
  actor role (person role, team role or IT profile role); or user identity. Request body is optional.
4206
4456
  Async version.
4207
4457
 
@@ -4254,9 +4504,12 @@ class CollectionManager(Client):
4254
4504
  await self._async_make_request("POST", url, body)
4255
4505
  else:
4256
4506
  await self._async_make_request("POST", url)
4507
+ logger.info(f"Attached actor {actor_guid} to agreement {agreement_guid}")
4508
+
4257
4509
 
4258
4510
  def link_agreement_actor(self, agreement_guid: str, actor_guid: str, body: dict = None):
4259
- """ Attach an actor to an agreement. The actor element may be an actor profile (person, team or IT profile);
4511
+ """ Attach an actor to an agreement. The actor element may be an actor profile (person, team or IT
4512
+ profile);
4260
4513
  actor role (person role, team role or IT profile role); or user identity. Request body is optional.
4261
4514
 
4262
4515
 
@@ -4303,6 +4556,8 @@ class CollectionManager(Client):
4303
4556
  loop = asyncio.get_event_loop()
4304
4557
  loop.run_until_complete(self._async_link_agreement_actor(agreement_guid, actor_guid, body))
4305
4558
 
4559
+
4560
+ @dynamic_catch
4306
4561
  async def _async_detach_agreement_actor(self, agreement_guid: str, actor_guid: str, body: dict = None):
4307
4562
  """ Unlink an actor from an agreement. Request body is optional. Async version.
4308
4563
 
@@ -4349,6 +4604,8 @@ class CollectionManager(Client):
4349
4604
  await self._async_make_request("POST", url, body)
4350
4605
  else:
4351
4606
  await self._async_make_request("POST", url)
4607
+ logger.info(f"Detached agreement actor {actor_guid} from {agreement_guid}")
4608
+
4352
4609
 
4353
4610
  def detach_agreement_actor(self, agreement_guid: str, actor_guid: str, body: dict = None):
4354
4611
  """ Unlink an actor from an agreement. Request body is optional.
@@ -4390,6 +4647,8 @@ class CollectionManager(Client):
4390
4647
  loop = asyncio.get_event_loop()
4391
4648
  loop.run_until_complete(self._async_detach_agreement_actor(agreement_guid, actor_guid, body))
4392
4649
 
4650
+
4651
+ @dynamic_catch
4393
4652
  async def _async_link_agreement_item(self, agreement_guid: str, agreement_item_guid: str,
4394
4653
  body: dict = None) -> None:
4395
4654
  """ Attach an agreement to an element referenced in its definition. The agreement item element is of type
@@ -4458,6 +4717,8 @@ class CollectionManager(Client):
4458
4717
  await self._async_make_request("POST", url, body)
4459
4718
  else:
4460
4719
  await self._async_make_request("POST", url)
4720
+ logger.info(f"Attached agreement item {agreement_item_guid} to {agreement_guid}")
4721
+
4461
4722
 
4462
4723
  def link_agreement_item(self, agreement_guid: str, agreement_item_guid: str, body: dict = None) -> None:
4463
4724
  """ Attach an agreement to an element referenced in its definition. The agreement item element is of type
@@ -4521,6 +4782,8 @@ class CollectionManager(Client):
4521
4782
  loop = asyncio.get_event_loop()
4522
4783
  loop.run_until_complete(self._async_link_agreement_item(agreement_guid, agreement_item_guid, body))
4523
4784
 
4785
+
4786
+ @dynamic_catch
4524
4787
  async def _async_detach_agreement_item(self, agreement_guid: str, agreement_item_guid: str,
4525
4788
  body: dict = None) -> None:
4526
4789
  """Detach an agreement item from an agreement. Request body is optional. Async version.
@@ -4569,6 +4832,8 @@ class CollectionManager(Client):
4569
4832
  await self._async_make_request("POST", url, body)
4570
4833
  else:
4571
4834
  await self._async_make_request("POST", url)
4835
+ logger.info(f"Detached agreement item {agreement_item_guid} from {agreement_guid}")
4836
+
4572
4837
 
4573
4838
  def detach_agreement_item(self, agreement_guid: str, agreement_item_guid: str, body: dict = None) -> None:
4574
4839
  """Detach an agreement item from an agreement. Request body is optional. Async version.
@@ -4610,8 +4875,11 @@ class CollectionManager(Client):
4610
4875
  loop = asyncio.get_event_loop()
4611
4876
  loop.run_until_complete(self._async_detach_agreement_item(agreement_guid, agreement_item_guid, body))
4612
4877
 
4878
+
4879
+ @dynamic_catch
4613
4880
  async def _async_link_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
4614
- """ Attach an agreement to an external reference element that describes the location of the contract documents.
4881
+ """ Attach an agreement to an external reference element that describes the location of the contract
4882
+ documents.
4615
4883
  Request body is optional. Async version.
4616
4884
 
4617
4885
  Parameters
@@ -4666,9 +4934,12 @@ class CollectionManager(Client):
4666
4934
  await self._async_make_request("POST", url, body)
4667
4935
  else:
4668
4936
  await self._async_make_request("POST", url)
4937
+ logger.info(f"Attached agreemenbt {agreement_guid} to contract {external_ref_guid}")
4938
+
4669
4939
 
4670
4940
  def link_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
4671
- """ Attach an agreement to an external reference element that describes the location of the contract documents.
4941
+ """ Attach an agreement to an external reference element that describes the location of the contract
4942
+ documents.
4672
4943
  Request body is optional.
4673
4944
 
4674
4945
  Parameters
@@ -4718,6 +4989,8 @@ class CollectionManager(Client):
4718
4989
  loop = asyncio.get_event_loop()
4719
4990
  loop.run_until_complete(self._async_link_contract(agreement_guid, external_ref_guid, body))
4720
4991
 
4992
+
4993
+ @dynamic_catch
4721
4994
  async def _async_detach_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
4722
4995
  """Detach an external reference to a contract, from an agreement. Request body is optional. Async version.
4723
4996
 
@@ -4765,6 +5038,8 @@ class CollectionManager(Client):
4765
5038
  await self._async_make_request("POST", url, body)
4766
5039
  else:
4767
5040
  await self._async_make_request("POST", url)
5041
+ logger.info(f"Detached contract: {external_ref_guid} from {agreement_guid}")
5042
+
4768
5043
 
4769
5044
  def detach_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
4770
5045
  """Detach an external reference to a contract, from an agreement. Request body is optional.
@@ -4806,10 +5081,12 @@ class CollectionManager(Client):
4806
5081
  loop = asyncio.get_event_loop()
4807
5082
  loop.run_until_complete(self._async_detach_contract(agreement_guid, external_ref_guid, body))
4808
5083
 
4809
- #
4810
- # Digital Subscriptions
4811
- #
5084
+ #
5085
+ # Digital Subscriptions
5086
+ #
4812
5087
 
5088
+
5089
+ @dynamic_catch
4813
5090
  async def _async_create_digital_subscription(self, body: dict) -> str:
4814
5091
  """Create a new collection that represents a type of agreement called a digital_subscription. Async version.
4815
5092
 
@@ -4912,7 +5189,10 @@ class CollectionManager(Client):
4912
5189
  url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
4913
5190
 
4914
5191
  resp = await self._async_make_request("POST", url, body_slimmer(body))
4915
- return resp.json().get("guid", "No GUID returned")
5192
+ guid = resp.json().get('guid', NO_GUID_RETURNED)
5193
+ logger.info(f"Create collection with GUID: {guid}")
5194
+ return guid
5195
+
4916
5196
 
4917
5197
  def create_digital_subscription(self, body: dict) -> str:
4918
5198
  """Create a new collection that represents a type of agreement called a digital_subscription.
@@ -4985,6 +5265,8 @@ class CollectionManager(Client):
4985
5265
  resp = loop.run_until_complete(self._async_create_digital_subscription(body))
4986
5266
  return resp
4987
5267
 
5268
+
5269
+ @dynamic_catch
4988
5270
  async def _async_update_digital_subscription(self, digital_subscription_guid: str, body: dict,
4989
5271
  replace_all_props: bool = False, ):
4990
5272
  """Update the properties of the digital_subscription collection. Async version.
@@ -5047,6 +5329,8 @@ class CollectionManager(Client):
5047
5329
  f"{digital_subscription_guid}/update?replaceAllProperties={replace_all_props_s}")
5048
5330
 
5049
5331
  await self._async_make_request("POST", url, body)
5332
+ logger.info(f"Updated digital subscription {digital_subscription_guid}")
5333
+
5050
5334
 
5051
5335
  def update_digital_subscription(self, digital_subscription_guid: str, body: dict,
5052
5336
  replace_all_props: bool = False, ):
@@ -5104,6 +5388,8 @@ class CollectionManager(Client):
5104
5388
  loop.run_until_complete(
5105
5389
  self._async_update_digital_subscription(digital_subscription_guid, body, replace_all_props))
5106
5390
 
5391
+
5392
+ @dynamic_catch
5107
5393
  async def _async_update_digital_subscription_status(self, digital_subscription_guid: str, body: dict):
5108
5394
  """Update the status of an digital_subscription collection. Async version.
5109
5395
 
@@ -5147,8 +5433,10 @@ class CollectionManager(Client):
5147
5433
  f"{digital_subscription_guid}/update-status")
5148
5434
 
5149
5435
  await self._async_make_request("POST", url, body)
5436
+ logger.info(f"Updated status for DigitalProduct {digital_subscription_guid}")
5437
+
5150
5438
 
5151
- def update_digital_digital_subscription_status(self, digital_subscription_guid: str, body: dict):
5439
+ def update_digital_subscription_status(self, digital_subscription_guid: str, body: dict):
5152
5440
  """Update the status of an digital_subscription collection. Async version.
5153
5441
 
5154
5442
  Parameters
@@ -5188,6 +5476,8 @@ class CollectionManager(Client):
5188
5476
  loop = asyncio.get_event_loop()
5189
5477
  loop.run_until_complete(self._async_update_digital_subscription_status(digital_subscription_guid, body))
5190
5478
 
5479
+
5480
+ @dynamic_catch
5191
5481
  async def _async_link_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict = None):
5192
5482
  """ Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
5193
5483
  products, team or business capabilities to be the subscriber. The subscription is an element of type
@@ -5243,6 +5533,8 @@ class CollectionManager(Client):
5243
5533
  await self._async_make_request("POST", url, body)
5244
5534
  else:
5245
5535
  await self._async_make_request("POST", url)
5536
+ logger.info(f"Linking subscriber {subscriber_guid} to subscription {subscription_guid}")
5537
+
5246
5538
 
5247
5539
  def link_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict = None):
5248
5540
  """ Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
@@ -5293,6 +5585,8 @@ class CollectionManager(Client):
5293
5585
  loop = asyncio.get_event_loop()
5294
5586
  loop.run_until_complete(self._async_link_subscriber(subscriber_guid, subscription_guid, body))
5295
5587
 
5588
+
5589
+ @dynamic_catch
5296
5590
  async def _async_detach_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict = None):
5297
5591
  """ Detach a subscriber from a subscription Request body is optional. Async version.
5298
5592
 
@@ -5339,6 +5633,8 @@ class CollectionManager(Client):
5339
5633
  await self._async_make_request("POST", url, body)
5340
5634
  else:
5341
5635
  await self._async_make_request("POST", url)
5636
+ logger.info(f"Detached subscriber {subscriber_guid} from subscription {subscription_guid}")
5637
+
5342
5638
 
5343
5639
  def detach_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict = None):
5344
5640
  """ Detach a subscriber from a subscription. Request body is optional.
@@ -5380,11 +5676,14 @@ class CollectionManager(Client):
5380
5676
  loop = asyncio.get_event_loop()
5381
5677
  loop.run_until_complete(self._async_detach_subscriber(subscriber_guid, subscription_guid, body))
5382
5678
 
5383
- #
5384
- #
5385
- #
5679
+ #
5680
+ #
5681
+ #
5682
+
5386
5683
 
5387
- async def _async_attach_collection(self, parent_guid: str, collection_guid: str, body: dict = None, make_anchor: bool = False):
5684
+ @dynamic_catch
5685
+ async def _async_attach_collection(self, parent_guid: str, collection_guid: str, body: dict = None,
5686
+ make_anchor: bool = False):
5388
5687
  """ Connect an existing collection to an element using the ResourceList relationship (0019).
5389
5688
  Async version.
5390
5689
 
@@ -5437,14 +5736,19 @@ class CollectionManager(Client):
5437
5736
 
5438
5737
  """
5439
5738
 
5440
- url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
5441
- f"{parent_guid}/collections/{collection_guid}/attach?makeAchor={make_anchor}")
5739
+ url = (
5740
+ f"{self.platform_url}/servers/"
5741
+ f"{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
5742
+ f"{parent_guid}/collections/{collection_guid}/attach?makeAchor={make_anchor}")
5442
5743
  if body:
5443
5744
  await self._async_make_request("POST", url, body)
5444
5745
  else:
5445
5746
  await self._async_make_request("POST", url)
5747
+ logger.info(f"Attached {collection_guid} to {parent_guid}")
5748
+
5446
5749
 
5447
- def attach_collection(self, parent_guid: str, collection_guid: str, body: dict = None, make_anchor: bool = False):
5750
+ def attach_collection(self, parent_guid: str, collection_guid: str, body: dict = None,
5751
+ make_anchor: bool = False):
5448
5752
  """ Connect an existing collection to an element using the ResourceList relationship (0019).
5449
5753
 
5450
5754
  Parameters
@@ -5497,8 +5801,11 @@ class CollectionManager(Client):
5497
5801
  loop = asyncio.get_event_loop()
5498
5802
  loop.run_until_complete(self._async_attach_collection(parent_guid, collection_guid, body, make_anchor))
5499
5803
 
5804
+
5805
+ @dynamic_catch
5500
5806
  async def _async_detach_collection(self, parent_guid: str, collection_guid: str, body: dict = None):
5501
- """ Detach an existing collection from an element. If the collection is anchored to the element, it is delete.
5807
+ """ Detach an existing collection from an element. If the collection is anchored to the element,
5808
+ it is delete.
5502
5809
  Async version.
5503
5810
 
5504
5811
  Parameters
@@ -5537,15 +5844,20 @@ class CollectionManager(Client):
5537
5844
  }
5538
5845
  """
5539
5846
 
5540
- url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
5541
- f"{parent_guid}/collections/{collection_guid}/detach")
5847
+ url = (
5848
+ f"{self.platform_url}/servers/"
5849
+ f"{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
5850
+ f"{parent_guid}/collections/{collection_guid}/detach")
5542
5851
  if body:
5543
5852
  await self._async_make_request("POST", url, body)
5544
5853
  else:
5545
5854
  await self._async_make_request("POST", url)
5855
+ logger.info(f"Detached collection {collection_guid} from {parent_guid}")
5856
+
5546
5857
 
5547
5858
  def detach_collection(self, parent_guid: str, collection_guid: str, body: dict = None):
5548
- """ Detach an existing collection from an element. If the collection is anchored to the element, it is delete.
5859
+ """ Detach an existing collection from an element. If the collection is anchored to the element,
5860
+ it is delete.
5549
5861
 
5550
5862
  Parameters
5551
5863
  ----------
@@ -5584,7 +5896,10 @@ class CollectionManager(Client):
5584
5896
  loop = asyncio.get_event_loop()
5585
5897
  loop.run_until_complete(self._async_detach_collection(parent_guid, collection_guid, body))
5586
5898
 
5587
- async def _async_delete_collection(self, collection_guid: str, body: dict = None, cascade: bool = False) -> None:
5899
+
5900
+ @dynamic_catch
5901
+ async def _async_delete_collection(self, collection_guid: str, body: dict = None,
5902
+ cascade: bool = False) -> None:
5588
5903
  """Delete a collection. It is detected from all parent elements. If members are anchored to the collection
5589
5904
  then they are also deleted. Async version
5590
5905
 
@@ -5633,6 +5948,8 @@ class CollectionManager(Client):
5633
5948
  body = {"class": "NullRequestBody"}
5634
5949
 
5635
5950
  await self._async_make_request("POST", url, body)
5951
+ logger.info(f"Deleted collection {collection_guid} with cascade {cascade}")
5952
+
5636
5953
 
5637
5954
  def delete_collection(self, collection_guid: str, body: dict = None, cascade: bool = False) -> None:
5638
5955
  """Delete a collection. It is detected from all parent elements. If members are anchored to the collection
@@ -5679,6 +5996,8 @@ class CollectionManager(Client):
5679
5996
  loop = asyncio.get_event_loop()
5680
5997
  loop.run_until_complete(self._async_delete_collection(collection_guid, body, cascade))
5681
5998
 
5999
+
6000
+ @dynamic_catch
5682
6001
  async def _async_add_to_collection(self, collection_guid: str, element_guid: str, body: dict = None, ) -> None:
5683
6002
  """Add an element to a collection. The request body is optional. Async version.
5684
6003
 
@@ -5740,6 +6059,8 @@ class CollectionManager(Client):
5740
6059
  f"{element_guid}/attach")
5741
6060
  body_s = body_slimmer(body)
5742
6061
  await self._async_make_request("POST", url, body_s)
6062
+ logger.info(f"Added {element_guid} to {collection_guid}")
6063
+
5743
6064
 
5744
6065
  def add_to_collection(self, collection_guid: str, element_guid: str, body: dict = None, ) -> None:
5745
6066
  """Add an element to a collection. The request body is optional.
@@ -5800,6 +6121,8 @@ class CollectionManager(Client):
5800
6121
  loop = asyncio.get_event_loop()
5801
6122
  loop.run_until_complete(self._async_add_to_collection(collection_guid, element_guid, body))
5802
6123
 
6124
+
6125
+ @dynamic_catch
5803
6126
  async def _async_update_collection_membership(self, collection_guid: str, element_guid: str, body: dict = None,
5804
6127
  replace_all_props: bool = False, ) -> None:
5805
6128
  """Update an element's membership to a collection. Async version.
@@ -5864,6 +6187,8 @@ class CollectionManager(Client):
5864
6187
  f"{element_guid}/update?replaceAllProperties={replace_all_props_s}")
5865
6188
  body_s = body_slimmer(body)
5866
6189
  await self._async_make_request("POST", url, body_s)
6190
+ logger.info(f"Updated membership for collection {collection_guid}")
6191
+
5867
6192
 
5868
6193
  def update_collection_membership(self, collection_guid: str, element_guid: str, body: dict = None,
5869
6194
  replace_all_props: bool = False, ) -> None:
@@ -5927,7 +6252,10 @@ class CollectionManager(Client):
5927
6252
  loop.run_until_complete(
5928
6253
  self._async_update_collection_membership(collection_guid, element_guid, body, replace_all_props))
5929
6254
 
5930
- async def _async_remove_from_collection(self, collection_guid: str, element_guid: str, body: dict = None) -> None:
6255
+
6256
+ @dynamic_catch
6257
+ async def _async_remove_from_collection(self, collection_guid: str, element_guid: str,
6258
+ body: dict = None) -> None:
5931
6259
  """Remove an element from a collection. Async version.
5932
6260
 
5933
6261
  Parameters
@@ -5971,6 +6299,8 @@ class CollectionManager(Client):
5971
6299
  if body is None:
5972
6300
  body = {"class": "NullRequestBody"}
5973
6301
  await self._async_make_request("POST", url, body)
6302
+ logger.info(f"Removed member {element_guid} from collection {collection_guid}")
6303
+
5974
6304
 
5975
6305
  def remove_from_collection(self, collection_guid: str, element_guid: str, body: dict = None) -> None:
5976
6306
  """Remove an element from a collection. Async version.
@@ -6013,10 +6343,12 @@ class CollectionManager(Client):
6013
6343
  loop = asyncio.get_event_loop()
6014
6344
  loop.run_until_complete(self._async_remove_from_collection(collection_guid, element_guid, body))
6015
6345
 
6016
- #
6017
- #
6018
- #
6346
+ #
6347
+ #
6348
+ #
6349
+
6019
6350
 
6351
+ @dynamic_catch
6020
6352
  async def _async_get_member_list(self, collection_guid: str = None, collection_name: str = None,
6021
6353
  collection_qname: str = None, ) -> list | str:
6022
6354
  """Get the member list for the collection - async version.
@@ -6050,6 +6382,7 @@ class CollectionManager(Client):
6050
6382
  member_list = []
6051
6383
  members = await self._async_get_collection_members(collection_guid, collection_name, collection_qname)
6052
6384
  if (type(members) is str) or (len(members) == 0):
6385
+ logger.trace(f"No members found for collection {collection_guid}")
6053
6386
  return "No members found"
6054
6387
  # finally, construct a list of member information
6055
6388
  for member_rel in members:
@@ -6063,12 +6396,13 @@ class CollectionManager(Client):
6063
6396
  "type": member["elementHeader"]["type"]['typeName'],
6064
6397
  }
6065
6398
  member_list.append(member_instance)
6066
-
6399
+ logger.debug(f"Member list for collection {collection_guid}: {member_list}")
6067
6400
  return member_list if len(member_list) > 0 else "No members found"
6068
6401
 
6402
+
6069
6403
  def get_member_list(self, collection_guid: str = None, collection_name: str = None,
6070
6404
  collection_qname: str = None, ) -> list | bool:
6071
- """Get the member list for the collection - async version.
6405
+ """Get the member list for a collection - async version.
6072
6406
  Parameters
6073
6407
  ----------
6074
6408
  collection_guid: str,
@@ -6092,9 +6426,11 @@ class CollectionManager(Client):
6092
6426
 
6093
6427
  """
6094
6428
  loop = asyncio.get_event_loop()
6095
- resp = loop.run_until_complete(self._async_get_member_list(collection_guid, collection_name, collection_qname))
6429
+ resp = loop.run_until_complete(
6430
+ self._async_get_member_list(collection_guid, collection_name, collection_qname))
6096
6431
  return resp
6097
6432
 
6433
+
6098
6434
  def _extract_collection_properties(self, element: dict) -> dict:
6099
6435
  """
6100
6436
  Extract common properties from a collection element.
@@ -6105,129 +6441,71 @@ class CollectionManager(Client):
6105
6441
  Returns:
6106
6442
  dict: Dictionary of extracted properties
6107
6443
  """
6108
- guid = element['elementHeader'].get("guid", None)
6109
- properties = element['properties']
6110
- display_name = properties.get("name", "") or ""
6111
- description = properties.get("description", "") or ""
6112
- qualified_name = properties.get("qualifiedName", "") or ""
6113
- collection_type = properties.get("collectionType", "") or ""
6114
- additional_properties = properties.get("additionalProperties", {}) or {}
6115
- extended_properties = properties.get("extendedProperties", {}) or {}
6444
+
6445
+ props = _extract_referenceable_properties(element)
6116
6446
  classification_names = ""
6117
- classifications = element['elementHeader'].get("classifications", [])
6118
- for classification in classifications:
6447
+ # classifications = element['elementHeader'].get("classifications", [])
6448
+ for classification in props['classifications']:
6119
6449
  classification_names += f"{classification['classificationName']}, "
6120
- classification_names = classification_names[:-2]
6121
- mermaid = element.get('mermaidGraph', "") or ""
6450
+ props["classifications"] = classification_names[:-2] # why?
6451
+
6452
+ props['mermaid'] = element.get('mermaidGraph', "") or ""
6122
6453
 
6123
6454
  member_names = ""
6124
- members = self.get_member_list(collection_guid=guid)
6455
+ members = self.get_member_list(collection_guid=props["GUID"])
6125
6456
  if isinstance(members, list):
6126
6457
  for member in members:
6127
6458
  member_names += f"{member['qualifiedName']}, "
6128
- member_names = member_names[:-2]
6129
-
6130
- return {
6131
- 'GUID': guid, 'display_name': display_name, 'qualified_name': qualified_name, 'description': description,
6132
- 'classifications': classification_names, 'collection_type': collection_type, 'members': member_names,
6133
- 'properties': properties, 'additional_properties': additional_properties,
6134
- 'extended_properties': extended_properties, 'mermaid': mermaid
6135
- }
6136
-
6137
- def generate_basic_structured_output(self, elements, filter, output_format: str = 'DICT',
6138
- collection_type: str = None) -> str | list:
6139
- """
6140
- Generate output in the specified format for the given elements.
6141
-
6142
- Args:
6143
- elements: Dictionary or list of dictionaries containing element data
6144
- filter: The search string used to find the elements
6145
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
6146
-
6147
- Returns:
6148
- Formatted output as string or list of dictionaries
6149
- """
6150
- # Handle MERMAID and DICT formats using existing methods
6151
- if output_format == "MERMAID":
6152
- return extract_mermaid_only(elements)
6153
- elif output_format == "DICT":
6154
- return extract_basic_dict(elements)
6155
- elif output_format == "HTML":
6156
- if collection_type is None:
6157
- entity_type = "Collection"
6158
- else:
6159
- entity_type = collection_type
6160
-
6161
- return generate_output(
6162
- elements=elements,
6163
- search_string=filter,
6164
- entity_type=entity_type,
6165
- output_format="HTML",
6166
- extract_properties_func=self._extract_collection_properties
6167
- )
6168
-
6169
- # For other formats (MD, FORM, REPORT, LIST), use generate_output
6170
- elif output_format in ["MD", "FORM", "REPORT", "LIST"]:
6171
- # Define columns for LIST format
6172
- columns = [{'name': 'Collection Name', 'key': 'display_name'},
6173
- {'name': 'Qualified Name', 'key': 'qualified_name'},
6174
- {'name': 'Collection Type', 'key': 'collection_type'},
6175
- {'name': 'Classifications', 'key': 'classifications'},
6176
- {'name': 'Description', 'key': 'description', 'format': True}]
6177
- if collection_type is None:
6178
- entity_type = "Collection"
6179
- else:
6180
- entity_type = collection_type
6181
-
6182
- return generate_output(elements=elements, search_string=filter, entity_type=entity_type,
6183
- output_format=output_format,
6184
- extract_properties_func=self._extract_collection_properties,
6185
- columns=columns if output_format == 'LIST' else None)
6186
-
6187
- def generate_collection_output(self, elements, filter, classification_name, output_format) -> str | list:
6188
- """
6189
- Generate output for collections in the specified format.
6190
-
6191
- Args:
6192
- elements: Dictionary or list of dictionaries containing data field elements
6193
- classification_name: str
6194
- The type of collection.
6195
- filter: The search string used to find the elements
6196
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
6197
-
6198
- Returns:
6199
- Formatted output as a string or list of dictionaries
6459
+ props['members'] = member_names[:-2]
6460
+ logger.trace(f"Extracted properties: {props}")
6461
+ return props
6462
+
6463
+
6464
+ def generate_collection_output(self, elements: Union[Dict, List[Dict]], filter: Optional[str],
6465
+ classification_name: Optional[str], output_format: str = "DICT",
6466
+ output_format_set: Optional[dict] | str = None) -> Union[str, List[Dict]]:
6467
+ """ Generate output for collections in the specified format.
6468
+
6469
+ Args:
6470
+ elements (Union[Dict, List[Dict]]): Dictionary or list of dictionaries containing data field elements
6471
+ filter (Optional[str]): The search string used to find the elements
6472
+ classification_name (Optional[str]): The type of collection
6473
+ output_format (str): The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
6474
+ output_format_set (Optional[dict], optional): List of dictionaries containing column data. Defaults
6475
+ to None.
6476
+
6477
+ Returns:
6478
+ Union[str, List[Dict]]: Formatted output as a string or list of dictionaries
6200
6479
  """
6201
6480
  if classification_name is None:
6202
- entity_type = "Collection"
6481
+ entity_type = "Collections"
6203
6482
  else:
6204
6483
  entity_type = classification_name
6205
-
6206
- if output_format == "HTML":
6207
- return generate_output(
6208
- elements=elements,
6209
- search_string=filter,
6210
- entity_type=entity_type,
6211
- output_format="HTML",
6212
- extract_properties_func=self._extract_collection_properties
6484
+ # First see if the user has specified an output_format_set - either a label or a dict
6485
+ if output_format_set:
6486
+ if isinstance(output_format_set, str):
6487
+ output_formats = select_output_format_set(entity_type, output_format)
6488
+ if isinstance(output_format_set, dict):
6489
+ output_formats = output_format_set
6490
+
6491
+ # If no output_format was set, then use the classification_name to lookup the output format
6492
+ elif classification_name:
6493
+ output_formats = select_output_format_set(classification_name, output_format)
6494
+ else:
6495
+ output_formats = None
6496
+ logger.trace(f"Executing generate_collection_output for {entity_type}: {output_formats}")
6497
+ return generate_output(
6498
+ elements,
6499
+ filter,
6500
+ entity_type,
6501
+ output_format,
6502
+ self._extract_collection_properties,
6503
+ None,
6504
+ output_formats,
6213
6505
  )
6214
6506
 
6215
- elif output_format in ["MD", "FORM", "REPORT", "LIST", "DICT", "MERMAID"]:
6216
- # Define columns for LIST format
6217
- columns = [{'name': 'Name', 'key': 'display_name'},
6218
- {'name': 'Qualified Name', 'key': 'qualified_name', 'format': True},
6219
- {'name': 'Collection Type', 'key': 'collection_type'},
6220
- {'name': 'Description', 'key': 'description', 'format': True},
6221
- {'name': "Classifications", 'key': 'classifications'},
6222
- {'name': 'Members', 'key': 'members', 'format': True}, ]
6223
-
6224
- return generate_output(elements=elements, search_string=filter, entity_type=entity_type,
6225
- output_format=output_format,
6226
- extract_properties_func=self._extract_collection_properties,
6227
- columns=columns if output_format == 'LIST' else None)
6228
- else:
6229
- return self.generate_basic_structured_output(elements, filter, output_format)
6230
6507
 
6508
+ from typing import Union, Dict, List, Optional
6231
6509
 
6232
6510
  if __name__ == "__main__":
6233
6511
  print("Main-Collection Manager")