pyegeria 5.4.3.2__py3-none-any.whl → 5.4.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. commands/cat/debug_log.2025-09-01_07-02-58_818650.log.zip +0 -0
  2. commands/cat/debug_log.2025-09-02_07-44-39_567276.log.zip +0 -0
  3. commands/cat/debug_log.2025-09-03_07-45-21_986388.log.zip +0 -0
  4. commands/cat/debug_log.log +5379 -8107
  5. commands/cat/list_format_set.py +2 -2
  6. commands/tech/list_information_supply_chains.py +1 -1
  7. commands/tech/list_solution_blueprints.py +1 -1
  8. commands/tech/list_solution_components.py +1 -1
  9. commands/tech/list_solution_roles.py +1 -1
  10. md_processing/__init__.py +0 -4
  11. md_processing/data/commands.json +1258 -615
  12. md_processing/dr_egeria.py +6 -9
  13. md_processing/dr_egeria_inbox/data_spec_test.md +44 -418
  14. md_processing/dr_egeria_inbox/gov_def.md +239 -3
  15. md_processing/dr_egeria_inbox/product.md +13 -5
  16. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 14:03-product.md +209 -0
  17. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 14:24-product.md +263 -0
  18. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 16:03-data_spec_test.md +2374 -0
  19. md_processing/dr_egeria_outbox/monday/processed-2025-09-01 16:05-data_spec_test.md +2374 -0
  20. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:28-data_spec_test.md +2321 -0
  21. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:37-data_spec_test.md +2304 -0
  22. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 08:56-data_spec_test.md +2324 -0
  23. md_processing/dr_egeria_outbox/monday/processed-2025-09-02 09:00-data_spec_test.md +2324 -0
  24. md_processing/md_commands/data_designer_commands.py +170 -570
  25. md_processing/md_commands/product_manager_commands.py +1 -1
  26. md_processing/md_processing_utils/common_md_utils.py +55 -13
  27. md_processing/md_processing_utils/extraction_utils.py +14 -7
  28. md_processing/md_processing_utils/md_processing_constants.py +1 -1
  29. pyegeria/___external_references.py +3255 -0
  30. pyegeria/__init__.py +1 -1
  31. pyegeria/_client_new.py +9 -7
  32. pyegeria/_output_formats.py +124 -3
  33. pyegeria/collection_manager.py +17 -56
  34. pyegeria/config.py +10 -1
  35. pyegeria/data_designer.py +172 -124
  36. pyegeria/egeria_client.py +1 -1
  37. pyegeria/egeria_tech_client.py +1 -1
  38. pyegeria/glossary_manager.py +71 -85
  39. pyegeria/governance_officer.py +26 -29
  40. pyegeria/output_formatter.py +127 -1
  41. pyegeria/project_manager.py +33 -36
  42. pyegeria/{solution_architect_omvs.py → solution_architect.py} +443 -388
  43. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/METADATA +1 -1
  44. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/RECORD +47 -41
  45. md_processing/dr_egeria_outbox/friday/processed-2025-08-29 16:30-output_tests.md +0 -103
  46. md_processing/dr_egeria_outbox/friday/processed-2025-08-29 16:40-output_tests.md +0 -115
  47. md_processing/dr_egeria_outbox/friday/processed-2025-08-30 21:15-glossary_test1.md +0 -326
  48. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 13:27-glossary_test1.md +0 -369
  49. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 13:33-glossary_test1.md +0 -392
  50. md_processing/dr_egeria_outbox/friday/processed-2025-08-31 20:57-glossary_test1.md +0 -400
  51. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/LICENSE +0 -0
  52. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/WHEEL +0 -0
  53. {pyegeria-5.4.3.2.dist-info → pyegeria-5.4.3.4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,3255 @@
1
+ """
2
+ PDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+
5
+ Manage external references to a variety of artifacts.
6
+
7
+ """
8
+
9
+ import asyncio
10
+ from typing import Optional
11
+
12
+ from loguru import logger
13
+ from pydantic import HttpUrl
14
+
15
+ from pyegeria._globals import NO_GUID_RETURNED
16
+ from pyegeria._output_formats import select_output_format_set, get_output_format_type_match
17
+ from pyegeria.config import settings
18
+ from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequestBody, NewElementRequestBody,
19
+ TemplateRequestBody,
20
+ UpdateElementRequestBody, UpdateStatusRequestBody, NewRelationshipRequestBody,
21
+ DeleteRequestBody, UpdateRelationshipRequestBody, get_defined_field_values)
22
+ from pyegeria.output_formatter import (generate_output,
23
+ _extract_referenceable_properties, populate_columns_from_properties,
24
+ get_required_relationships)
25
+ from pyegeria.utils import dynamic_catch
26
+
27
+ app_settings = settings
28
+ EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
29
+
30
+ from pyegeria._client_new import Client2
31
+
32
+
33
+ class ExternalReferences(Client2):
34
+ """
35
+ Establish linkage to external references which can be a variety of artifacts. Including media,
36
+ documents, data, and more.
37
+
38
+ Attributes:
39
+
40
+ server_name: str
41
+ The name of the View Server to connect to.
42
+ platform_url : str
43
+ URL of the server platform to connect to
44
+ user_id : str
45
+ The identity of the user calling the method - this sets a default optionally used by the methods
46
+ when the user doesn't pass the user_id on a method call.
47
+ user_pwd: str
48
+ The password associated with the user_id. Defaults to None
49
+ token: str
50
+ An optional bearer token
51
+
52
+ """
53
+
54
+ def __init__(self, view_server: str, platform_url: str, user_id: str, user_pwd: str = None, token: str = None, ):
55
+ self.view_server = view_server
56
+ self.platform_url = platform_url
57
+ self.user_id = user_id
58
+ self.user_pwd = user_pwd
59
+
60
+ Client2.__init__(self, view_server, platform_url, user_id, user_pwd, token)
61
+ result = self.get_platform_origin()
62
+ logger.info(f"ExternalReferences initialized, platform origin is: {result}")
63
+ self.command_root: str = (
64
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external-references")
65
+
66
+ @dynamic_catch
67
+ async def _async_create_external_reference(self, body: dict | NewElementRequestBody = None) -> str:
68
+ """ Create a new generic external_reference. If the body is not present, the display_name, description, category,
69
+ and classification will be used to create a simple, self-anchored external_reference.
70
+ Collections: https://egeria-project.org/concepts/external_reference
71
+ Async version.
72
+
73
+ Parameters
74
+ ----------
75
+
76
+
77
+ body: dict | NewElementRequestBody, optional
78
+ A dict or NewElementRequestBody representing the details of the external_reference to create. If supplied, this
79
+ information will be used to create the external_reference and the other attributes will be ignored. The body is
80
+ validated before being used.
81
+
82
+ Returns
83
+ -------
84
+ str - the guid of the created external_reference
85
+
86
+ Raises
87
+ ------
88
+ PyegeriaException
89
+ One of the pyegeria exceptions will be raised if there are issues in communications, message format, or
90
+ Egeria errors.
91
+ ValidationError
92
+ Pydantic validation errors are raised if the body does not conform to the NewElementRequestBody.
93
+ NotAuthorizedException
94
+ The principle specified by the user_id does not have authorization for the requested action
95
+
96
+ Notes:
97
+ -----
98
+ simple:
99
+ {
100
+ "class": "NewElementRequestBody",
101
+ "isOwnAnchor": true,
102
+ "properties": {
103
+ "class": "ExternalReferenceProperties",
104
+ "qualifiedName": "Must provide a unique name here",
105
+ "name": "Add display name here",
106
+ "description": "Add description of the external_reference here",
107
+ "category": "Add appropriate valid value for type",
108
+ "referenceTitle: "Add reference title here",
109
+ "referenceAbstract": "Add reference abstract here",
110
+ "authors": ["Add author names here"],
111
+ "url": "Add url here",
112
+ "datePublished": "2023-01-01",
113
+ "dateConnected": "2023-01-01",
114
+ "dateCreated": "2023-01-01",
115
+ }
116
+ }
117
+
118
+ anchored:
119
+ {
120
+ "class": "NewElementRequestBody",
121
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
122
+ "isOwnAnchor": false,
123
+ "anchorScopeGUID": "optional GUID of search scope",
124
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
125
+ "parentRelationshipTypeName": "open metadata type name",
126
+ "parentAtEnd1": true,
127
+ "properties": {
128
+ "class": "ExternalReferenceProperties",
129
+ "qualifiedName": "Must provide a unique name here",
130
+ "name": "Add display name here",
131
+ "description": "Add description of the external_reference here",
132
+ "category": "Add appropriate valid value for type",
133
+ "referenceTitle: "Add reference title here",
134
+ "referenceAbstract": "Add reference abstract here",
135
+ "authors": ["Add author names here"],
136
+ "url": "Add url here",
137
+ "datePublished": "2023-01-01",
138
+ "dateConnected": "2023-01-01",
139
+ "dateCreated": "2023-01-01",
140
+ },
141
+ "externalSourceGUID": "add guid here",
142
+ "externalSourceName": "add qualified name here",
143
+ "effectiveTime": "{{$isoTimestamp}}",
144
+ "forLineage": false,
145
+ "forDuplicateProcessing": false
146
+ }
147
+
148
+ """
149
+
150
+ url = f"{self.external_reference_command_root}/external-references"
151
+ response = await self._async_create_collection(body=body)
152
+ return response
153
+
154
+ def create_external_reference(self, body: dict | NewElementRequestBody = None) -> str:
155
+ """ Create a new generic external_reference. If the body is not present, the display_name, description, category,
156
+ and classification will be used to create a simple, self-anchored external_reference.
157
+ Collections: https://egeria-project.org/concepts/external_reference
158
+ Async version.
159
+
160
+ Parameters
161
+ ----------
162
+
163
+
164
+ body: dict | NewElementRequestBody, optional
165
+ A dict or NewElementRequestBody representing the details of the external_reference to create. If supplied, this
166
+ information will be used to create the external_reference and the other attributes will be ignored. The body is
167
+ validated before being used.
168
+
169
+ Returns
170
+ -------
171
+ str - the guid of the created external_reference
172
+
173
+ Raises
174
+ ------
175
+ PyegeriaException
176
+ One of the pyegeria exceptions will be raised if there are issues in communications, message format, or
177
+ Egeria errors.
178
+ ValidationError
179
+ Pydantic validation errors are raised if the body does not conform to the NewElementRequestBody.
180
+ NotAuthorizedException
181
+ The principle specified by the user_id does not have authorization for the requested action
182
+
183
+ Notes:
184
+ -----
185
+ simple:
186
+ {
187
+ "class": "NewElementRequestBody",
188
+ "isOwnAnchor": true,
189
+ "properties": {
190
+ "class": "ExternalReferenceProperties",
191
+ "qualifiedName": "Must provide a unique name here",
192
+ "name": "Add display name here",
193
+ "description": "Add description of the external_reference here",
194
+ "category": "Add appropriate valid value for type",
195
+ "referenceTitle: "Add reference title here",
196
+ "referenceAbstract": "Add reference abstract here",
197
+ "authors": ["Add author names here"],
198
+ "url": "Add url here",
199
+ "datePublished": "2023-01-01",
200
+ "dateConnected": "2023-01-01",
201
+ "dateCreated": "2023-01-01",
202
+ }
203
+ }
204
+
205
+ anchored:
206
+ {
207
+ "class": "NewElementRequestBody",
208
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
209
+ "isOwnAnchor": false,
210
+ "anchorScopeGUID": "optional GUID of search scope",
211
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
212
+ "parentRelationshipTypeName": "open metadata type name",
213
+ "parentAtEnd1": true,
214
+ "properties": {
215
+ "class": "ExternalReferenceProperties",
216
+ "qualifiedName": "Must provide a unique name here",
217
+ "name": "Add display name here",
218
+ "description": "Add description of the external_reference here",
219
+ "category": "Add appropriate valid value for type",
220
+ "referenceTitle: "Add reference title here",
221
+ "referenceAbstract": "Add reference abstract here",
222
+ "authors": ["Add author names here"],
223
+ "url": "Add url here",
224
+ "datePublished": "2023-01-01",
225
+ "dateConnected": "2023-01-01",
226
+ "dateCreated": "2023-01-01",
227
+ },
228
+ "externalSourceGUID": "add guid here",
229
+ "externalSourceName": "add qualified name here",
230
+ "effectiveTime": "{{$isoTimestamp}}",
231
+ "forLineage": false,
232
+ "forDuplicateProcessing": false
233
+ }
234
+
235
+
236
+ """
237
+
238
+ return asyncio.get_event_loop().run_until_complete(self._async_create_external_reference(body))
239
+
240
+
241
+ #######
242
+
243
+ @dynamic_catch
244
+ async def _async_create_external_reference_from_template(self, body: TemplateRequestBody | dict) -> str:
245
+ """Create a new metadata element to represent a external_reference using an existing metadata element as a template.
246
+ The template defines additional classifications and relationships that are added to the new external_reference.
247
+ Async version.
248
+
249
+ Parameters
250
+ ----------
251
+
252
+ body: dict
253
+ A dict representing the details of the external_reference to create.
254
+
255
+ Returns
256
+ -------
257
+ str - the guid of the created external_reference
258
+
259
+ Raises
260
+ ------
261
+ InvalidParameterException
262
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
263
+ PropertyServerException
264
+ Raised by the server when an issue arises in processing a valid request
265
+ NotAuthorizedException
266
+ The principle specified by the user_id does not have authorization for the requested action
267
+
268
+ Notes
269
+ -----
270
+ JSON Structure looks like:
271
+
272
+ {
273
+ "class": "TemplateRequestBody",
274
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
275
+ "isOwnAnchor": false,
276
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
277
+ "parentRelationshipTypeName": "open metadata type name",
278
+ "parentAtEnd1": true,
279
+ "templateGUID": "template GUID",
280
+ "replacementProperties": {
281
+ "class": "ElementProperties",
282
+ "propertyValueMap" : {
283
+ "propertyName" : {
284
+ "class": "PrimitiveTypePropertyValue",
285
+ "typeName": "string",
286
+ "primitiveTypeCategory" : "OM_PRIMITIVE_TYPE_STRING",
287
+ "primitiveValue" : "value of property"
288
+ }
289
+ }
290
+ },
291
+ "placeholderPropertyValues" : {
292
+ "placeholderProperty1Name" : "property1Value",
293
+ "placeholderProperty2Name" : "property2Value"
294
+ }
295
+ }
296
+
297
+ """
298
+
299
+ if isinstance(body, TemplateRequestBody):
300
+ validated_body = body
301
+
302
+ elif isinstance(body, dict):
303
+ validated_body = self._template_request_adapter.validate_python(body)
304
+
305
+ url = f"{self.external_reference_command_root}/from-template"
306
+ json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
307
+ logger.info(json_body)
308
+ resp = await self._async_make_request("POST", url, json_body, is_json=True)
309
+ logger.info(f"Create external_reference from template with GUID: {resp.json().get('guid')}")
310
+ return resp.json().get("guid", NO_GUID_RETURNED)
311
+
312
+
313
+ def create_external_reference_from_template(self, body: dict) -> str:
314
+ """Create a new metadata element to represent a external_reference using an existing metadata element as a template.
315
+ The template defines additional classifications and relationships that are added to the new external_reference.
316
+
317
+ Parameters
318
+ ----------
319
+ body: dict
320
+ A dict representing the details of the external_reference to create.
321
+
322
+ Returns
323
+ -------
324
+ str - the guid of the created external_reference
325
+
326
+ Raises
327
+ ------
328
+ InvalidParameterException
329
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
330
+ PropertyServerException
331
+ Raised by the server when an issue arises in processing a valid request
332
+ NotAuthorizedException
333
+ The principle specified by the user_id does not have authorization for the requested action
334
+
335
+ Notes
336
+ -----
337
+ JSON Structure looks like:
338
+
339
+ {
340
+ "class": "TemplateRequestBody",
341
+ "anchorGUID": "anchor GUID, if set then isOwnAnchor=false",
342
+ "isOwnAnchor": false,
343
+ "parentGUID": "parent GUID, if set, set all parameters beginning 'parent'",
344
+ "parentRelationshipTypeName": "open metadata type name",
345
+ "parentAtEnd1": true,
346
+ "templateGUID": "template GUID",
347
+ "replacementProperties": {
348
+ "class": "ElementProperties",
349
+ "propertyValueMap" : {
350
+ "propertyName" : {
351
+ "class": "PrimitiveTypePropertyValue",
352
+ "typeName": "string",
353
+ "primitiveTypeCategory" : "OM_PRIMITIVE_TYPE_STRING",
354
+ "primitiveValue" : "value of property"
355
+ }
356
+ }
357
+ },
358
+ "placeholderPropertyValues" : {
359
+ "placeholderProperty1Name" : "property1Value",
360
+ "placeholderProperty2Name" : "property2Value"
361
+ }
362
+ }
363
+ """
364
+ loop = asyncio.get_event_loop()
365
+ resp = loop.run_until_complete(self._async_create_external_reference_from_template(body))
366
+ return resp
367
+
368
+ #
369
+ # Manage external_references
370
+ #
371
+
372
+
373
+ @dynamic_catch
374
+ async def _async_update_external_reference(self, external_reference_guid: str,
375
+ body: dict | UpdateElementRequestBody) -> None:
376
+ """ Update the properties of a external_reference. Use the correct properties object (CollectionProperties,
377
+ DigitalProductProperties, AgreementProperties, etc), that is appropriate for your element.
378
+ Collections: https://egeria-project.org/concepts/external_reference
379
+
380
+ Async version.
381
+ Parameters
382
+ ----------
383
+ external_reference_guid: str
384
+ The guid of the external_reference to update.
385
+
386
+ body: dict | UpdateElementRequestBody, optional
387
+ A dict or NewElementRequestBody representing the details of the external_reference to create. If supplied, this
388
+ information will be used to create the external_reference and the other attributes will be ignored. The body is
389
+ validated before being used.
390
+ merge_update: bool, optional, default = True
391
+ If true then property changes will be overlaid on top of existing properties. If false, existing
392
+ properties will all be replaced by the set provided in the update request.
393
+
394
+ Returns
395
+ -------
396
+ None
397
+
398
+ Raises
399
+ ------
400
+ PyegeriaException
401
+ One of the pyegeria exceptions will be raised if there are issues in communications, message format, or
402
+ Egeria errors.
403
+ ValidationError
404
+ Pydantic validation errors are raised if the body does not conform to the NewElementRequestBody.
405
+ NotAuthorizedException
406
+ The principle specified by the user_id does not have authorization for the requested action
407
+
408
+ Notes:
409
+ -----
410
+ simple example:
411
+ {
412
+ "class" : "UpdateElementRequestBody",
413
+ "properties": {
414
+ "class" : "CollectionProperties",
415
+ "qualifiedName": "Must provide a unique name here",
416
+ "name" : "Add display name here",
417
+ "description" : "Add description of the external_reference here",
418
+ "category": "Add appropriate valid value for type"
419
+ },
420
+ "externalSourceGUID": "add guid here",
421
+ "externalSourceName": "add qualified name here",
422
+ "effectiveTime" : "{{$isoTimestamp}}",
423
+ "forLineage" : false,
424
+ "forDuplicateProcessing" : false
425
+ }
426
+ """
427
+
428
+ # try:
429
+
430
+ url = (f"{self.external_reference_command_root}/{external_reference_guid}/update")
431
+ await self._async_update_element_body_request(url, [""], body)
432
+
433
+
434
+ @dynamic_catch
435
+ def update_external_reference(self, external_reference_guid: str, body: dict | NewElementRequestBody) -> None:
436
+ """ Update the properties of a external_reference. Use the correct properties object (CollectionProperties,
437
+ DigitalProductProperties, AgreementProperties, etc), that is appropriate for your element.
438
+ Collections: https://egeria-project.org/concepts/external_reference
439
+
440
+ Parameters
441
+ ----------
442
+ external_reference_guid: str
443
+ The guid of the external_reference to update.
444
+
445
+ body: dict | NewElementRequestBody, optional
446
+ A dict or NewElementRequestBody representing the details of the external_reference to create. If supplied, this
447
+ information will be used to create the external_reference and the other attributes will be ignored. The body is
448
+ validated before being used.
449
+ merge_update: bool, optional, default = True
450
+ If true then property changes will be overlaid on top of existing properties. If false, existing
451
+ properties will all be replaced by the set provided in the update request.
452
+
453
+ Returns
454
+ -------
455
+ None
456
+
457
+ Raises
458
+ ------
459
+ PyegeriaException
460
+ One of the pyegeria exceptions will be raised if there are issues in communications, message format, or
461
+ Egeria errors.
462
+ ValidationError
463
+ Pydantic validation errors are raised if the body does not conform to the NewElementRequestBody.
464
+ NotAuthorizedException
465
+ The principle specified by the user_id does not have authorization for the requested action
466
+
467
+ Notes:
468
+ -----
469
+ simple example:
470
+ {
471
+ "class" : "UpdateElementRequestBody",
472
+ "properties": {
473
+ "class" : "CollectionProperties",
474
+ "qualifiedName": "Must provide a unique name here",
475
+ "name" : "Add display name here",
476
+ "description" : "Add description of the external_reference here",
477
+ "category": "Add appropriate valid value for type"
478
+ },
479
+ "externalSourceGUID": "add guid here",
480
+ "externalSourceName": "add qualified name here",
481
+ "effectiveTime" : "{{$isoTimestamp}}",
482
+ "forLineage" : false,
483
+ "forDuplicateProcessing" : false
484
+ }
485
+ """
486
+
487
+ return asyncio.get_event_loop().run_until_complete(
488
+ self._async_update_external_reference(external_reference_guid, body))
489
+
490
+
491
+ def get_attached_external_references(self, parent_guid: str, start_from: int = 0, page_size: int = 0, body: dict = None,
492
+ output_format: str = "JSON", output_format_set: str | dict = None) -> list:
493
+ """Returns the list of external_references that are linked off of the supplied element using the ResourceList
494
+ relationship. Async version.
495
+
496
+ Parameters
497
+ ----------
498
+ parent_guid: str
499
+ The identity of the parent to find linked external_references from.
500
+ start_from: int, [default=0], optional
501
+ When multiple pages of results are available, the page number to start from.
502
+ page_size: int, [default=None]
503
+ The number of items to return in a single page. If not specified, the default will be taken from
504
+ the class instance.
505
+ body: dict, optional, default = None
506
+ If supplied, adds addition request details - for instance, to filter the results on external_referenceType
507
+ output_format: str, default = "JSON"
508
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
509
+ output_format_set: str | dict = None), optional, default = None
510
+ The desired output columns/fields to include.
511
+
512
+
513
+ Returns
514
+ -------
515
+ List
516
+
517
+ A list of external_references linked off of the supplied element.
518
+
519
+ Raises
520
+ ------
521
+
522
+ InvalidParameterException
523
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
524
+ PropertyServerException
525
+ Raised by the server when an issue arises in processing a valid request
526
+ NotAuthorizedException
527
+ The principle specified by the user_id does not have authorization for the requested action
528
+
529
+ Notes
530
+ -----
531
+ Sample body:
532
+ {
533
+ "class": "FilterRequestBody",
534
+ "asOfTime": "{{$isoTimestamp}}",
535
+ "effectiveTime": "{{$isoTimestamp}}",
536
+ "forLineage": false,
537
+ "forDuplicateProcessing": false,
538
+ "limitResultsByStatus": ["ACTIVE"],
539
+ "sequencingOrder": "PROPERTY_ASCENDING",
540
+ "sequencingProperty": "qualifiedName",
541
+ "filter": "Add external_referenceType value here"
542
+ }
543
+
544
+ """
545
+ return asyncio.get_event_loop().run_until_complete(
546
+ self._async_get_attached_external_references(parent_guid, start_from, page_size,
547
+ body, output_format, output_format_set))
548
+
549
+
550
+ @dynamic_catch
551
+ async def _async_find_external_references(self, search_string: str = "*", classification_names: list[str] = None,
552
+ metadata_element_types: list[str] = None,
553
+ starts_with: bool = True, ends_with: bool = False, ignore_case: bool = False,
554
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
555
+ output_format_set: str | dict = None,
556
+ body: dict | SearchStringRequestBody = None) -> list | str:
557
+ """ Returns the list of external_references matching the search string filtered by the optional classification.
558
+ This method can either be used with a body, allowing full control, or with the individual parameters.
559
+ If the body is provided it will be used and the search_string will be ignored.
560
+
561
+ Parameters
562
+ ----------
563
+ search_string: str
564
+ Search string to match against - None or '*' indicate match against all external_references (may be filtered by
565
+ classification).
566
+ classification_names: list[str], optional, default=None
567
+ A list of classification names to filter on - for example, ["DataSpec"], for data specifications. If none,
568
+ then all classifications are returned.
569
+ metadata_element_types: list[str], optional, default=None
570
+ A list of metadata element types to filter on - for example, ["DataSpec"], for data specifications. If none,
571
+ starts_with : bool, [default=False], optional
572
+ Starts with the supplied string.
573
+ ends_with : bool, [default=False], optional
574
+ Ends with the supplied string
575
+ ignore_case : bool, [default=False], optional
576
+ Ignore case when searching
577
+ start_from: int, [default=0], optional
578
+ When multiple pages of results are available, the page number to start from.
579
+ page_size: int, [default=None]
580
+ The number of items to return in a single page. If not specified, the default will be taken from
581
+ the class instance.
582
+ output_format: str, default = "JSON"
583
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
584
+ output_format_set: str | dict , optional, default = None
585
+ - The desired output columns/fields to include.
586
+ body: dict | SearchStringRequestBody, optional, default = None
587
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
588
+
589
+ Returns
590
+ -------
591
+ List | str
592
+
593
+ Output depends on the output format specified.
594
+
595
+ Raises
596
+ ------
597
+
598
+ ValidationError
599
+ If the client passes incorrect parameters on the request that don't conform to the data model.
600
+ PyegeriaException
601
+ Issues raised in communicating or server side processing.
602
+ NotAuthorizedException
603
+ The principle specified by the user_id does not have authorization for the requested action
604
+
605
+ """
606
+ url = str(HttpUrl(f"{self.external_reference_command_root}/by-search-string"))
607
+ response = await self._async_find_request(url, _type="Collection",
608
+ _gen_output=self._generate_external_reference_output,
609
+ search_string=search_string, classification_names=classification_names,
610
+ metadata_element_types=metadata_element_types,
611
+ starts_with=starts_with, ends_with=ends_with, ignore_case=ignore_case,
612
+ start_from=start_from, page_size=page_size,
613
+ output_format=output_format, output_format_set=output_format_set,
614
+ body=body)
615
+
616
+ return response
617
+
618
+
619
+ @dynamic_catch
620
+ def find_external_references(self, search_string: str = '*', classification_names: str = None,
621
+ metadata_element_types: list[str] = None, starts_with: bool = True,
622
+ ends_with: bool = False, ignore_case: bool = False,
623
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
624
+ output_format_set: str | dict = None,
625
+ body: dict | SearchStringRequestBody = None) -> list | str:
626
+ """ Returns the list of external_references matching the search string filtered by the optional classification.
627
+ This method can either be used with a body, allowing full control, or with the individual parameters.
628
+ If the body is provided it will be used and the search_string will be ignored.
629
+
630
+ Parameters
631
+ ----------
632
+ search_string: str
633
+ Search string to match against - None or '*' indicate match against all external_references (may be filtered by
634
+ classification).
635
+ classification_names: list[str], optional, default=None
636
+ A list of classification names to filter on - for example, ["DataSpec"], for data specifications. If none,
637
+ then all classifications are returned.
638
+ metadata_element_types: list[str], optional, default=None
639
+ A list of metadata element types to filter on - for example, ["DataSpec"], for data specifications. If none,
640
+ then all metadata element types are returned.
641
+ starts_with : bool, [default=False], optional
642
+ Starts with the supplied string.
643
+ ends_with : bool, [default=False], optional
644
+ Ends with the supplied string
645
+ ignore_case : bool, [default=False], optional
646
+ Ignore case when searching
647
+ start_from: int, [default=0], optional
648
+ When multiple pages of results are available, the page number to start from.
649
+ page_size: int, [default=None]
650
+ The number of items to return in a single page. If not specified, the default will be taken from
651
+ the class instance.
652
+ output_format: str, default = "JSON"
653
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
654
+ output_format_set: str | dict , optional, default = None
655
+ - The desired output columns/fields to include.
656
+ body: dict | SearchStringRequestBody, optional, default = None
657
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
658
+
659
+ Returns
660
+ -------
661
+ List | str
662
+
663
+ Output depends on the output format specified.
664
+
665
+ Raises
666
+ ------
667
+
668
+ ValidationError
669
+ If the client passes incorrect parameters on the request that don't conform to the data model.
670
+ PyegeriaException
671
+ Issues raised in communicating or server side processing.
672
+ NotAuthorizedException
673
+ The principle specified by the user_id does not have authorization for the requested action
674
+
675
+ Args:
676
+ classification_names ():
677
+ metadata_element_types ():
678
+
679
+ """
680
+ return asyncio.get_event_loop().run_until_complete(
681
+ self._async_find_external_references(search_string, classification_names, metadata_element_types,
682
+ starts_with, ends_with, ignore_case,
683
+ start_from, page_size, output_format,
684
+ output_format_set, body))
685
+
686
+
687
+ @dynamic_catch
688
+ async def _async_get_external_references_by_name(self, filter_string: str = None,
689
+ classification_names: list[str] = None,
690
+ body: dict | FilterRequestBody = None,
691
+ start_from: int = 0, page_size: int = 0,
692
+ output_format: str = 'JSON',
693
+ output_format_set: str | dict = None) -> list | str:
694
+ """ Returns the list of external_references with a particular name.
695
+
696
+ Parameters
697
+ ----------
698
+ name: str,
699
+ name to use to find matching external_references.
700
+ classification_names: list[str], optional, default = None
701
+ type of external_reference to filter by - e.g., DataDict, Folder, Root
702
+ body: dict, optional, default = None
703
+ Provides, a full request body. If specified, the body supercedes the name parameter.
704
+ start_from: int, [default=0], optional
705
+ When multiple pages of results are available, the page number to start from.
706
+ page_size: int, [default=None]
707
+ The number of items to return in a single page. If not specified, the default will be taken from
708
+ the class instance.
709
+ output_format: str, default = "JSON"
710
+ - one of "DICT", "MERMAID" or "JSON"
711
+ output_format_set: dict , optional, default = None
712
+ The desired output columns/fields to include.
713
+
714
+ Returns
715
+ -------
716
+ List | str
717
+
718
+ A list of external_references match matching the name. Returns a string if none found.
719
+
720
+ Raises
721
+ ------
722
+
723
+ InvalidParameterException
724
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
725
+ PropertyServerException
726
+ Raised by the server when an issue arises in processing a valid request
727
+ NotAuthorizedException
728
+ The principle specified by the user_id does not have authorization for the requested action
729
+ """
730
+ url = str(HttpUrl(f"{self.external_reference_command_root}/by-name"))
731
+ response = await self._async_get_name_request(url, _type="Collection",
732
+ _gen_output=self._generate_external_reference_output,
733
+ filter_string=filter_string,
734
+ classification_names=classification_names,
735
+ start_from=start_from, page_size=page_size,
736
+ output_format=output_format, output_format_set=output_format_set,
737
+ body=body)
738
+
739
+ return response
740
+
741
+
742
+ def get_external_references_by_name(self, name: str = None, classification_names: list[str] = None,
743
+ body: dict | FilterRequestBody = None,
744
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
745
+ output_format_set: str | dict = None) -> list | str:
746
+ """Returns the list of external_references matching the search string. Async version.
747
+ The search string is located in the request body and is interpreted as a plain string.
748
+ The request parameters, startsWith, endsWith, and ignoreCase can be used to allow a fuzzy search.
749
+
750
+ Parameters
751
+ ----------
752
+ name: str,
753
+ name to use to find matching external_references.
754
+ classification_names: list[str], optional, default = None
755
+ type of external_reference to filter by - e.g., DataDict, Folder, Root
756
+ body: dict, optional, default = None
757
+ Provides, a full request body. If specified, the body supercedes the name parameter.
758
+ start_from: int, [default=0], optional
759
+ When multiple pages of results are available, the page number to start from.
760
+ page_size: int, [default=None]
761
+ The number of items to return in a single page. If not specified, the default will be taken from
762
+ the class instance.
763
+ output_format: str, default = "JSON"
764
+ - one of "DICT", "MERMAID" or "JSON"
765
+ output_format_set: str | dict, optional, default = None
766
+ The desired output columns/fields to include.
767
+
768
+ Returns
769
+ -------
770
+ List | str
771
+
772
+ A list of external_references match matching the search string. Returns a string if none found.
773
+
774
+ Raises
775
+ ------
776
+ PyegeriaException
777
+
778
+ """
779
+ return asyncio.get_event_loop().run_until_complete(
780
+ self._async_get_external_references_by_name(name, classification_names, body, start_from, page_size,
781
+ output_format, output_format_set))
782
+
783
+
784
+ @dynamic_catch
785
+ async def _async_get_external_references_by_category(self, category: str, classification_names: list[str] = None,
786
+ body: dict | FilterRequestBody = None, start_from: int = 0,
787
+ page_size: int = 0,
788
+ output_format: str = 'JSON',
789
+ output_format_set: str | dict = None) -> list | str:
790
+ """Returns the list of external_references with a particular category. This is an optional text field in the
791
+ external_reference element.
792
+
793
+ Parameters
794
+ ----------
795
+ category: str
796
+ category to use to find matching external_references.
797
+ classification_names: str, optional
798
+ An optional filter on the search, e.g., DataSpec
799
+ body: dict, optional, default = None
800
+ Provides, a full request body. If specified, the body filter parameter supercedes the external_reference_type
801
+ parameter.
802
+ start_from: int, [default=0], optional
803
+ When multiple pages of results are available, the page number to start from.
804
+ page_size: int, [default=None]
805
+ The number of items to return in a single page. If not specified, the default will be taken from
806
+ the class instance.
807
+ output_format: str, default = "JSON"
808
+ - one of "DICT", "MERMAID" or "JSON"
809
+ output_format_set: str | dict , optional, default = None
810
+ The desired output columns/fields to include.
811
+
812
+ Returns
813
+ -------
814
+ List | str
815
+
816
+ A list of external_references matching the external_reference type. Returns a string if none found.
817
+
818
+ Raises
819
+ ------
820
+ PyegeriaException
821
+
822
+ Notes
823
+ -----
824
+ Body sample:
825
+
826
+ {
827
+ "class": "FilterRequestBody",
828
+ "asOfTime": "{{$isoTimestamp}}",
829
+ "effectiveTime": "{{$isoTimestamp}}",
830
+ "forLineage": false,
831
+ "forDuplicateProcessing": false,
832
+ "limitResultsByStatus": ["ACTIVE"],
833
+ "sequencingOrder": "PROPERTY_ASCENDING",
834
+ "sequencingProperty": "qualifiedName",
835
+ "filter": "Add category here"
836
+ }
837
+
838
+ """
839
+ url = str(HttpUrl(f"{self.external_reference_command_root}/by-external_reference-category"))
840
+ response = await self._async_get_name_request(url, _type="Collection",
841
+ _gen_output=self._generate_external_reference_output,
842
+ filter_string=category, classification_names=classification_names,
843
+ start_from=start_from, page_size=page_size,
844
+ output_format=output_format, output_format_set=output_format_set,
845
+ body=body)
846
+
847
+ return response
848
+
849
+
850
+ def get_external_references_by_category(self, category: str, classification_names: list[str] = None,
851
+ body: dict | FilterRequestBody = None,
852
+ start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
853
+ output_format_set: str | dict = None) -> list | str:
854
+ """Returns the list of external_references with a particular external_referenceType. This is an optional text field in the
855
+ external_reference element.
856
+
857
+ Parameters
858
+ ----------
859
+ category: str
860
+ category to use to find matching external_references.
861
+ classification_names: list[str], optional
862
+ An optional filter on the search, e.g., DataSpec
863
+ body: dict, optional, default = None
864
+ Provides, a full request body. If specified, the body filter parameter supersedes the category
865
+ parameter.
866
+ start_from: int, [default=0], optional
867
+ When multiple pages of results are available, the page number to start from.
868
+ page_size: int, [default=None]
869
+ The number of items to return in a single page. If not specified, the default will be taken from
870
+ the class instance.
871
+ output_format: str, default = "JSON"
872
+ - one of "DICT", "MERMAID" or "JSON"
873
+ output_format_set: str | dict, optional, default = None
874
+ The desired output columns/fields to include.
875
+
876
+ Returns
877
+ -------
878
+ List | str
879
+
880
+ A list of external_references filtered by the specified category. Output based on specified output format.
881
+
882
+ Raises
883
+ ------
884
+
885
+ InvalidParameterException
886
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
887
+ PropertyServerException
888
+ Raised by the server when an issue arises in processing a valid request
889
+ NotAuthorizedException
890
+ The principle specified by the user_id does not have authorization for the requested action
891
+
892
+ Notes
893
+ -----
894
+ Body sample:
895
+
896
+ {
897
+ "class": "FilterRequestBody",
898
+ "asOfTime": "{{$isoTimestamp}}",
899
+ "effectiveTime": "{{$isoTimestamp}}",
900
+ "forLineage": false,
901
+ "forDuplicateProcessing": false,
902
+ "limitResultsByStatus": ["ACTIVE"],
903
+ "sequencingOrder": "PROPERTY_ASCENDING",
904
+ "sequencingProperty": "qualifiedName",
905
+ "filter": "Add category here"
906
+ }
907
+
908
+ """
909
+
910
+ return asyncio.get_event_loop().run_until_complete(
911
+ self._async_get_external_references_by_category(category, classification_names, body, start_from, page_size,
912
+ output_format, output_format_set))
913
+
914
+
915
+ @dynamic_catch
916
+ async def _async_get_external_reference_by_guid(self, external_reference_guid: str, element_type: str = None,
917
+ body: dict | GetRequestBody = None,
918
+ output_format: str = 'JSON',
919
+ output_format_set: str | dict = None) -> dict | str:
920
+ """Return the properties of a specific external_reference. Async version.
921
+
922
+ Parameters
923
+ ----------
924
+ external_reference_guid: str,
925
+ unique identifier of the external_reference.
926
+ element_type: str, default = None, optional
927
+ type of external_reference - Collection, DataSpec, Agreement, etc.
928
+ body: dict | GetRequestBody, optional, default = None
929
+ full request body.
930
+ output_format: str, default = "JSON"
931
+ - one of "DICT", "MERMAID" or "JSON"
932
+ output_format_set: str | dict, optional, default = None
933
+ The desired output columns/fields to include.
934
+
935
+ Returns
936
+ -------
937
+ dict | str
938
+
939
+ A JSON dict representing the specified external_reference. Returns a string if none found.
940
+
941
+ Raises
942
+ ------
943
+
944
+ InvalidParameterException
945
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
946
+ PropertyServerException
947
+ Raised by the server when an issue arises in processing a valid request
948
+ NotAuthorizedException
949
+ The principle specified by the user_id does not have authorization for the requested action
950
+
951
+ Notes
952
+ ----
953
+ Body sample:
954
+ {
955
+ "class": "GetRequestBody",
956
+ "asOfTime": "{{$isoTimestamp}}",
957
+ "effectiveTime": "{{$isoTimestamp}}",
958
+ "forLineage": false,
959
+ "forDuplicateProcessing": false
960
+ }
961
+ """
962
+
963
+ url = str(HttpUrl(f"{self.external_reference_command_root}/{external_reference_guid}/retrieve"))
964
+ type = element_type if element_type else "Collection"
965
+
966
+ response = await self._async_get_guid_request(url, _type=type,
967
+ _gen_output=self._generate_external_reference_output,
968
+ output_format=output_format, output_format_set=output_format_set,
969
+ body=body)
970
+
971
+ return response
972
+
973
+
974
+ def get_external_reference_by_guid(self, external_reference_guid: str, element_type: str = None,
975
+ body: dict | GetRequestBody = None,
976
+ output_format: str = 'JSON', output_format_set: str | dict = None) -> dict | str:
977
+ """ Return the properties of a specific external_reference. Async version.
978
+
979
+ Parameters
980
+ ----------
981
+ external_reference_guid: str,
982
+ unique identifier of the external_reference.
983
+ element_type: str, default = None, optional
984
+ type of element - Collection, DataSpec, Agreement, etc.
985
+ body: dict | GetRequestBody, optional, default = None
986
+ full request body.
987
+ output_format: str, default = "JSON"
988
+ - one of "DICT", "MERMAID" or "JSON"
989
+ output_format_set: dict , optional, default = None
990
+ The desired output columns/fields to include.
991
+
992
+
993
+ Returns
994
+ -------
995
+ dict | str
996
+
997
+ A JSON dict representing the specified external_reference. Returns a string if none found.
998
+
999
+ Raises
1000
+ ------
1001
+
1002
+ InvalidParameterException
1003
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1004
+ PropertyServerException
1005
+ Raised by the server when an issue arises in processing a valid request
1006
+ NotAuthorizedException
1007
+ The principle specified by the user_id does not have authorization for the requested action
1008
+
1009
+ Notes
1010
+ ----
1011
+ Body sample:
1012
+ {
1013
+ "class": "AnyTimeRequestBody",
1014
+ "asOfTime": "{{$isoTimestamp}}",
1015
+ "effectiveTime": "{{$isoTimestamp}}",
1016
+ "forLineage": false,
1017
+ "forDuplicateProcessing": false
1018
+ }
1019
+ """
1020
+ return asyncio.get_event_loop().run_until_complete(
1021
+ self._async_get_external_reference_by_guid(external_reference_guid, element_type, body,
1022
+ output_format, output_format_set))
1023
+
1024
+
1025
+ @dynamic_catch
1026
+ async def _async_update_external_reference_status(self, external_reference_guid: str, status: str = None,
1027
+ body: dict | UpdateStatusRequestBody = None):
1028
+ """Update the status of a external_reference. Async version.
1029
+
1030
+ Parameters
1031
+ ----------
1032
+ external_reference_guid: str
1033
+ The guid of the external_reference to update.
1034
+ status: str, optional
1035
+ The new lifecycle status for the external_reference. Ignored, if the body is provided.
1036
+ body: dict | UpdateStatusRequestBody, optional
1037
+ A structure representing the details of the external_reference to create. If supplied, these details
1038
+ supersede the status parameter provided.
1039
+
1040
+ Returns
1041
+ -------
1042
+ Nothing
1043
+
1044
+ Raises
1045
+ ------
1046
+ InvalidParameterException
1047
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1048
+ PropertyServerException
1049
+ Raised by the server when an issue arises in processing a valid request
1050
+ NotAuthorizedException
1051
+ The principle specified by the user_id does not have authorization for the requested action
1052
+
1053
+ Notes
1054
+ -----
1055
+ JSON Structure looks like:
1056
+ {
1057
+ "class": "UpdateStatusRequestBody",
1058
+ "status": "APPROVED",
1059
+ "externalSourceGUID": "add guid here",
1060
+ "externalSourceName": "add qualified name here",
1061
+ "effectiveTime": "{{$isoTimestamp}}",
1062
+ "forLineage": false,
1063
+ "forDuplicateProcessing": false
1064
+ }
1065
+ """
1066
+
1067
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/metadata-elements/{external_reference_guid}/update-status"
1068
+ await self._async_update_status_request(url, status, body)
1069
+
1070
+
1071
+ @dynamic_catch
1072
+ def update_external_reference_status(self, external_reference_guid: str, status: str = None,
1073
+ body: dict | UpdateStatusRequestBody = None):
1074
+ """Update the status of a DigitalProduct external_reference.
1075
+
1076
+ Parameters
1077
+ ----------
1078
+ external_reference_guid: str
1079
+ The guid of the external_reference to update.
1080
+ status: str, optional
1081
+ The new lifecycle status for the digital product. Ignored, if the body is provided.
1082
+ body: dict | UpdateStatusRequestBody, optional
1083
+ A structure representing the details of the external_reference to create. If supplied, these details
1084
+ supersede the status parameter provided.
1085
+
1086
+ Returns
1087
+ -------
1088
+ Nothing
1089
+
1090
+ Raises
1091
+ ------
1092
+ InvalidParameterException
1093
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1094
+ PropertyServerException
1095
+ Raised by the server when an issue arises in processing a valid request
1096
+ NotAuthorizedException
1097
+ The principle specified by the user_id does not have authorization for the requested action
1098
+
1099
+ Notes
1100
+ -----
1101
+ JSON Structure looks like:
1102
+ {
1103
+ "class": "UpdateStatusRequestBody",
1104
+ "status": "APPROVED",
1105
+ "externalSourceGUID": "add guid here",
1106
+ "externalSourceName": "add qualified name here",
1107
+ "effectiveTime": "{{$isoTimestamp}}",
1108
+ "forLineage": false,
1109
+ "forDuplicateProcessing": false
1110
+ }
1111
+ """
1112
+ loop = asyncio.get_event_loop()
1113
+ loop.run_until_complete(self._async_update_external_reference_status(external_reference_guid, status, body))
1114
+
1115
+
1116
+ @dynamic_catch
1117
+ async def _async_link_digital_product_dependency(self, upstream_digital_prod_guid: str,
1118
+ downstream_digital_prod_guid: str,
1119
+ body: dict | NewRelationshipRequestBody = None):
1120
+ """ Link two dependent digital products. The linked elements are of type DigitalProduct.
1121
+ Request body is optional. Async version.
1122
+
1123
+ Parameters
1124
+ ----------
1125
+ upstream_digital_prod_guid: str
1126
+ The guid of the first digital product
1127
+ downstream_digital_prod_guid: str
1128
+ The guid of the downstream digital product
1129
+ body: dict | NewRelationshipRequestBody, optional, default = None
1130
+ A dict representing the details of the relationship.
1131
+
1132
+ Returns
1133
+ -------
1134
+ Nothing
1135
+
1136
+ Raises
1137
+ ------
1138
+ InvalidParameterException
1139
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1140
+ PropertyServerException
1141
+ Raised by the server when an issue arises in processing a valid request
1142
+ NotAuthorizedException
1143
+ The principle specified by the user_id does not have authorization for the requested action
1144
+
1145
+ Notes
1146
+ -----
1147
+ JSON Structure looks like:
1148
+ {
1149
+ "class" : "NewRelationshipRequestBody",
1150
+ "externalSourceGUID": "add guid here",
1151
+ "externalSourceName": "add qualified name here",
1152
+ "effectiveTime" : "{{$isoTimestamp}}",
1153
+ "forLineage" : false,
1154
+ "forDuplicateProcessing" : false,
1155
+ "properties": {
1156
+ "class": "InformationSupplyChainLinkProperties",
1157
+ "label": "add label here",
1158
+ "description": "add description here",
1159
+ "effectiveFrom": "{{$isoTimestamp}}",
1160
+ "effectiveTo": "{{$isoTimestamp}}"
1161
+ }
1162
+ }
1163
+ """
1164
+ url = (
1165
+ f"{self.platform_url}/servers/"
1166
+ f"{self.view_server}/api/open-metadata/external_reference-manager/external_references/digital-products/"
1167
+ f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/attach")
1168
+ await self._async_new_relationship_request(url, "InformationSupplyChainLinkProperties", body)
1169
+ logger.info(f"Linked {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
1170
+
1171
+
1172
+ def link_digital_product_dependency(self, upstream_digital_prod_guid: str, downstream_digital_prod_guid: str,
1173
+ body: dict | NewRelationshipRequestBody = None):
1174
+ """ Link two dependent digital products. The linked elements are of type DigitalProduct.
1175
+ Request body is optional.
1176
+
1177
+ Parameters
1178
+ ----------
1179
+ upstream_digital_prod_guid: str
1180
+ The guid of the first digital product
1181
+ downstream_digital_prod_guid: str
1182
+ The guid of the downstream digital product
1183
+ body: dict | NewRelationshipRequestBody, optional, default = None
1184
+ A structure representing the details of the relationship.
1185
+
1186
+ Returns
1187
+ -------
1188
+ Nothing
1189
+
1190
+ Raises
1191
+ ------
1192
+ InvalidParameterException
1193
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1194
+ PropertyServerException
1195
+ Raised by the server when an issue arises in processing a valid request
1196
+ NotAuthorizedException
1197
+ The principle specified by the user_id does not have authorization for the requested action
1198
+
1199
+ Notes
1200
+ -----
1201
+ JSON Structure looks like:
1202
+ JSON Structure looks like:
1203
+ {
1204
+ "class" : "NewRelationshipRequestBody",
1205
+ "externalSourceGUID": "add guid here",
1206
+ "externalSourceName": "add qualified name here",
1207
+ "effectiveTime" : "{{$isoTimestamp}}",
1208
+ "forLineage" : false,
1209
+ "forDuplicateProcessing" : false,
1210
+ "properties": {
1211
+ "class": "InformationSupplyChainLinkProperties",
1212
+ "label": "add label here",
1213
+ "description": "add description here",
1214
+ "effectiveFrom": "{{$isoTimestamp}}",
1215
+ "effectiveTo": "{{$isoTimestamp}}"
1216
+ }
1217
+ }
1218
+ """
1219
+ loop = asyncio.get_event_loop()
1220
+ loop.run_until_complete(
1221
+ self._async_link_digital_product_dependency(upstream_digital_prod_guid, downstream_digital_prod_guid,
1222
+ body))
1223
+
1224
+
1225
+ @dynamic_catch
1226
+ async def _async_detach_digital_product_dependency(self, upstream_digital_prod_guid: str,
1227
+ downstream_digital_prod_guid: str,
1228
+ body: dict | DeleteRequestBody = None) -> None:
1229
+ """ Unlink two dependent digital products. The linked elements are of type DigitalProduct.
1230
+ Request body is optional. Async version.
1231
+
1232
+ Parameters
1233
+ ----------
1234
+ upstream_digital_prod_guid: str
1235
+ The guid of the first digital product
1236
+ downstream_digital_prod_guid: str
1237
+ The guid of the downstream digital product
1238
+ body: dict | DeleteRequestBody, optional, default = None
1239
+ A structure representing the details of the relationship.
1240
+
1241
+ Returns
1242
+ -------
1243
+ Nothing
1244
+
1245
+ Raises
1246
+ ------
1247
+ InvalidParameterException
1248
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1249
+ PropertyServerException
1250
+ Raised by the server when an issue arises in processing a valid request
1251
+ NotAuthorizedException
1252
+ The principle specified by the user_id does not have authorization for the requested action
1253
+
1254
+ Notes
1255
+ -----
1256
+ JSON Structure looks like:
1257
+ {
1258
+ "class": "DeleteRequestBody",
1259
+ "externalSourceGUID": "add guid here",
1260
+ "externalSourceName": "add qualified name here",
1261
+ "effectiveTime": "{{$isoTimestamp}}",
1262
+ "forLineage": false,
1263
+ "forDuplicateProcessing": false
1264
+ }
1265
+
1266
+ """
1267
+
1268
+ url = (
1269
+ f"{self.platform_url}/servers/"
1270
+ f"{self.view_server}/api/open-metadata/external_reference-manager/external_references/digital-products/"
1271
+ f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/detach")
1272
+ await self._async_delete_request(url, body)
1273
+ logger.info(f"Detached digital product dependency {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
1274
+
1275
+
1276
+ def detach_digital_product_dependency(self, upstream_digital_prod_guid: str, downstream_digital_prod_guid: str,
1277
+ body: dict | DeleteRequestBody = None):
1278
+ """ Unlink two dependent digital products. The linked elements are of type DigitalProduct.
1279
+ Request body is optional.
1280
+
1281
+ Parameters
1282
+ ----------
1283
+ upstream_digital_prod_guid: str
1284
+ The guid of the first digital product
1285
+ downstream_digital_prod_guid: str
1286
+ The guid of the downstream digital product
1287
+ body: dict | DeleteRequestBody, optional, default = None
1288
+ A structure representing the details of the relationship.
1289
+
1290
+ Returns
1291
+ -------
1292
+ Nothing
1293
+
1294
+ Raises
1295
+ ------
1296
+ InvalidParameterException
1297
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1298
+ PropertyServerException
1299
+ Raised by the server when an issue arises in processing a valid request
1300
+ NotAuthorizedException
1301
+ The principle specified by the user_id does not have authorization for the requested action
1302
+
1303
+ Notes
1304
+ -----
1305
+ JSON Structure looks like:
1306
+ {
1307
+ "class": "DeleteRequestBody",
1308
+ "externalSourceGUID": "add guid here",
1309
+ "externalSourceName": "add qualified name here",
1310
+ "effectiveTime": "{{$isoTimestamp}}",
1311
+ "forLineage": false,
1312
+ "forDuplicateProcessing": false
1313
+ }
1314
+ """
1315
+ loop = asyncio.get_event_loop()
1316
+ loop.run_until_complete(
1317
+ self._async_detach_digital_product_dependency(upstream_digital_prod_guid, downstream_digital_prod_guid,
1318
+ body))
1319
+
1320
+
1321
+ #
1322
+
1323
+ ###
1324
+
1325
+ @dynamic_catch
1326
+ async def _async_link_agreement_item(self, agreement_guid: str, agreement_item_guid: str,
1327
+ body: dict | NewRelationshipRequestBody = None) -> None:
1328
+ """ Attach an agreement to an element referenced in its definition. The agreement item element is of type
1329
+ 'Referenceable' to allow the agreement to refer to many things. Request body is optional. Async version.
1330
+
1331
+ Parameters
1332
+ ----------
1333
+ agreement_guid: str
1334
+ The guid of the agreement to update.
1335
+ agreement_item_guid: str
1336
+ The guid of the element to attach.
1337
+ body: dict | NewRelationshipRequestBody, optional, default = None
1338
+ A dict representing the details of the relationship.
1339
+
1340
+ Returns
1341
+ -------
1342
+ Nothing
1343
+
1344
+ Raises
1345
+ ------
1346
+ InvalidParameterException
1347
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1348
+ PropertyServerException
1349
+ Raised by the server when an issue arises in processing a valid request
1350
+ NotAuthorizedException
1351
+ The principle specified by the user_id does not have authorization for the requested action
1352
+
1353
+ Notes
1354
+ _____
1355
+ {
1356
+ "class" : "NewRelationshipRequestBody",
1357
+ "externalSourceGUID": "add guid here",
1358
+ "externalSourceName": "add qualified name here",
1359
+ "effectiveTime" : "{{$isoTimestamp}}",
1360
+ "forLineage" : false,
1361
+ "forDuplicateProcessing" : false,
1362
+ "properties": {
1363
+ "class": "AgreementItemProperties",
1364
+ "agreementItemId": "add label here",
1365
+ "agreementStart": "{{$isoTimestamp}}",
1366
+ "agreementEnd": "{{$isoTimestamp}}",
1367
+ "restrictions": {
1368
+ "property1Name" : "property1Value",
1369
+ "property2Name" : "property2Value"
1370
+ },
1371
+ "obligations" : {
1372
+ "property1Name" : "property1Value",
1373
+ "property2Name" : "property2Value"
1374
+ },
1375
+ "entitlements" : {
1376
+ "property1Name" : "property1Value",
1377
+ "property2Name" : "property2Value"
1378
+ },
1379
+ "usageMeasurements" : {
1380
+ "property1Name" : "property1Value",
1381
+ "property2Name" : "property2Value"
1382
+ },
1383
+ "effectiveFrom": "{{$isoTimestamp}}",
1384
+ "effectiveTo": "{{$isoTimestamp}}"
1385
+ }
1386
+ }
1387
+
1388
+ """
1389
+ url = (
1390
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references/"
1391
+ f"agreements/{agreement_guid}/agreement-items/{agreement_item_guid}/attach")
1392
+
1393
+ await self._async_new_relationship_request(url, "AgreementItemProperties", body)
1394
+ logger.info(f"Attached agreement item {agreement_item_guid} to {agreement_guid}")
1395
+
1396
+
1397
+ def link_agreement_item(self, agreement_guid: str, agreement_item_guid: str, body: dict = None) -> None:
1398
+ """ Attach an agreement to an element referenced in its definition. The agreement item element is of type
1399
+ 'Referenceable' to allow the agreement to refer to many things. Request body is optional.
1400
+
1401
+ Parameters
1402
+ ----------
1403
+ agreement_guid: str
1404
+ The guid of the agreement to update.
1405
+ agreement_item_guid: str
1406
+ The guid of the element to attach.
1407
+ body: dict, optional, default = None
1408
+ A dict representing the details of the relationship.
1409
+
1410
+ Returns
1411
+ -------
1412
+ Nothing
1413
+
1414
+ Raises
1415
+ ------
1416
+ InvalidParameterException
1417
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1418
+ PropertyServerException
1419
+ Raised by the server when an issue arises in processing a valid request
1420
+ NotAuthorizedException
1421
+ The principle specified by the user_id does not have authorization for the requested action
1422
+
1423
+ Notes
1424
+ _____
1425
+
1426
+ {
1427
+ "class" : "RelationshipRequestBody",
1428
+ "externalSourceGUID": "add guid here",
1429
+ "externalSourceName": "add qualified name here",
1430
+ "effectiveTime" : "{{$isoTimestamp}}",
1431
+ "forLineage" : false,
1432
+ "forDuplicateProcessing" : false,
1433
+ "properties": {
1434
+ "class": "AgreementItemProperties",
1435
+ "agreementItemId": "add label here",
1436
+ "agreementStart": "{{$isoTimestamp}}",
1437
+ "agreementEnd": "{{$isoTimestamp}}",
1438
+ "restrictions": {
1439
+ "property1Name" : "property1Value",
1440
+ "property2Name" : "property2Value"
1441
+ },
1442
+ "obligations" : {
1443
+ "property1Name" : "property1Value",
1444
+ "property2Name" : "property2Value"
1445
+ },
1446
+ "usageMeasurements" : {
1447
+ "property1Name" : "property1Value",
1448
+ "property2Name" : "property2Value"
1449
+ },
1450
+ "effectiveFrom": "{{$isoTimestamp}}",
1451
+ "effectiveTo": "{{$isoTimestamp}}"
1452
+ }
1453
+ }
1454
+
1455
+ """
1456
+ loop = asyncio.get_event_loop()
1457
+ loop.run_until_complete(self._async_link_agreement_item(agreement_guid, agreement_item_guid, body))
1458
+
1459
+
1460
+ @dynamic_catch
1461
+ async def _async_detach_agreement_item(self, agreement_guid: str, agreement_item_guid: str,
1462
+ body: dict | DeleteRequestBody = None) -> None:
1463
+ """Detach an agreement item from an agreement. Request body is optional. Async version.
1464
+
1465
+ Parameters
1466
+ ----------
1467
+ agreement_guid: str
1468
+ The guid of the agreement to link.
1469
+ agreement_item_guid: str
1470
+ The guid of the element to attach.
1471
+ body: dict | DeleteRequestBody, optional, default = None
1472
+ A structure representing the details of the relationship.
1473
+
1474
+ Returns
1475
+ -------
1476
+ Nothing
1477
+
1478
+ Raises
1479
+ ------
1480
+ InvalidParameterException
1481
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1482
+ PropertyServerException
1483
+ Raised by the server when an issue arises in processing a valid request
1484
+ NotAuthorizedException
1485
+ The principle specified by the user_id does not have authorization for the requested action
1486
+
1487
+ Notes
1488
+ _____
1489
+ {
1490
+ "class": "DeleteRequestBody",
1491
+ "externalSourceGUID": "add guid here",
1492
+ "externalSourceName": "add qualified name here",
1493
+ "effectiveTime": "{{$isoTimestamp}}",
1494
+ "forLineage": false,
1495
+ "forDuplicateProcessing": false
1496
+ }
1497
+
1498
+ """
1499
+ url = (
1500
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
1501
+ f"/agreements"
1502
+ f"{agreement_guid}/agreement-items/{agreement_item_guid}/detach")
1503
+ await self._async_delete_request(url, body)
1504
+ logger.info(f"Detached agreement item {agreement_item_guid} from {agreement_guid}")
1505
+
1506
+
1507
+ def detach_agreement_item(self, agreement_guid: str, agreement_item_guid: str, body: dict = None) -> None:
1508
+ """Detach an agreement item from an agreement. Request body is optional. Async version.
1509
+
1510
+ Parameters
1511
+ ----------
1512
+ agreement_guid: str
1513
+ The guid of the agreement to link.
1514
+ agreement_item_guid: str
1515
+ The guid of the element to attach.
1516
+ body: dict, optional, default = None
1517
+ A dict representing the details of the relationship.
1518
+
1519
+ Returns
1520
+ -------
1521
+ Nothing
1522
+
1523
+ Raises
1524
+ ------
1525
+ InvalidParameterException
1526
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1527
+ PropertyServerException
1528
+ Raised by the server when an issue arises in processing a valid request
1529
+ NotAuthorizedException
1530
+ The principle specified by the user_id does not have authorization for the requested action
1531
+
1532
+ Notes
1533
+ _____
1534
+ {
1535
+ "class" : "MetadataSourceRequestBody",
1536
+ "externalSourceGUID": "add guid here",
1537
+ "externalSourceName": "add qualified name here",
1538
+ "effectiveTime" : "{{$isoTimestamp}}",
1539
+ "forLineage" : false,
1540
+ "forDuplicateProcessing" : false
1541
+ }
1542
+
1543
+ """
1544
+ loop = asyncio.get_event_loop()
1545
+ loop.run_until_complete(self._async_detach_agreement_item(agreement_guid, agreement_item_guid, body))
1546
+
1547
+
1548
+ @dynamic_catch
1549
+ async def _async_link_contract(self, agreement_guid: str, external_ref_guid: str,
1550
+ body: dict | NewRelationshipRequestBody = None) -> None:
1551
+ """ Attach an agreement to an external reference element that describes the location of the contract
1552
+ documents.
1553
+ Request body is optional. Async version.
1554
+
1555
+ Parameters
1556
+ ----------
1557
+ agreement_guid: str
1558
+ The guid of the agreement to update.
1559
+ external_ref_guid: str
1560
+ The guid of the external reference to attach.
1561
+ body: dict | NewRelationshipRequestBody, optional, default = None
1562
+ A structure representing the details of the relationship.
1563
+
1564
+ Returns
1565
+ -------
1566
+ Nothing
1567
+
1568
+ Raises
1569
+ ------
1570
+ InvalidParameterException
1571
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1572
+ PropertyServerException
1573
+ Raised by the server when an issue arises in processing a valid request
1574
+ NotAuthorizedException
1575
+ The principle specified by the user_id does not have authorization for the requested action
1576
+
1577
+ Notes
1578
+ _____
1579
+
1580
+ {
1581
+ "class" : "RelationshipRequestBody",
1582
+ "externalSourceGUID": "add guid here",
1583
+ "externalSourceName": "add qualified name here",
1584
+ "effectiveTime" : "{{$isoTimestamp}}",
1585
+ "forLineage" : false,
1586
+ "forDuplicateProcessing" : false,
1587
+ "properties": {
1588
+ "class": "ContractLinkProperties",
1589
+ "contractId": "add id here",
1590
+ "contractLiaison": "add identifier of actor here",
1591
+ "contractLiaisonTypeName": "add type of actor here",
1592
+ "contractLiaisonPropertyName": "add property of actor's identifier here",
1593
+ "effectiveFrom": "{{$isoTimestamp}}",
1594
+ "effectiveTo": "{{$isoTimestamp}}"
1595
+ }
1596
+ }
1597
+
1598
+ """
1599
+ url = (
1600
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references/"
1601
+ f"agreements/{agreement_guid}/contract-links/{external_ref_guid}/attach")
1602
+ await self._async_new_relationship_request(url, "ContractLinkProperties", body)
1603
+ logger.info(f"Attached agreement {agreement_guid} to contract {external_ref_guid}")
1604
+
1605
+
1606
+ @dynamic_catch
1607
+ def link_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
1608
+ """ Attach an agreement to an external reference element that describes the location of the contract
1609
+ documents.
1610
+ Request body is optional.
1611
+
1612
+ Parameters
1613
+ ----------
1614
+ agreement_guid: str
1615
+ The guid of the agreement to update.
1616
+ external_ref_guid: str
1617
+ The guid of the external reference to attach.
1618
+ body: dict, optional, default = None
1619
+ A dict representing the details of the relationship.
1620
+
1621
+ Returns
1622
+ -------
1623
+ Nothing
1624
+
1625
+ Raises
1626
+ ------
1627
+ InvalidParameterException
1628
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1629
+ PropertyServerException
1630
+ Raised by the server when an issue arises in processing a valid request
1631
+ NotAuthorizedException
1632
+ The principle specified by the user_id does not have authorization for the requested action
1633
+
1634
+ Notes
1635
+ _____
1636
+
1637
+ {
1638
+ "class" : "RelationshipRequestBody",
1639
+ "externalSourceGUID": "add guid here",
1640
+ "externalSourceName": "add qualified name here",
1641
+ "effectiveTime" : "{{$isoTimestamp}}",
1642
+ "forLineage" : false,
1643
+ "forDuplicateProcessing" : false,
1644
+ "properties": {
1645
+ "class": "ContractLinkProperties",
1646
+ "contractId": "add id here",
1647
+ "contractLiaison": "add identifier of actor here",
1648
+ "contractLiaisonTypeName": "add type of actor here",
1649
+ "contractLiaisonPropertyName": "add property of actor's identifier here",
1650
+ "effectiveFrom": "{{$isoTimestamp}}",
1651
+ "effectiveTo": "{{$isoTimestamp}}"
1652
+ }
1653
+ }
1654
+
1655
+ """
1656
+ loop = asyncio.get_event_loop()
1657
+ loop.run_until_complete(self._async_link_contract(agreement_guid, external_ref_guid, body))
1658
+
1659
+
1660
+ @dynamic_catch
1661
+ async def _async_detach_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
1662
+ """Detach an external reference to a contract, from an agreement. Request body is optional. Async version.
1663
+
1664
+ Parameters
1665
+ ----------
1666
+ agreement_guid: str
1667
+ The guid of the agreement to link.
1668
+ external_ref_guid: str
1669
+ The guid of the element to attach.
1670
+ body: dict, optional, default = None
1671
+ A dict representing the details of the relationship.
1672
+
1673
+ Returns
1674
+ -------
1675
+ Nothing
1676
+
1677
+ Raises
1678
+ ------
1679
+ InvalidParameterException
1680
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1681
+ PropertyServerException
1682
+ Raised by the server when an issue arises in processing a valid request
1683
+ NotAuthorizedException
1684
+ The principle specified by the user_id does not have authorization for the requested action
1685
+
1686
+ Notes
1687
+ _____
1688
+ {
1689
+ "class" : "MetadataSourceRequestBody",
1690
+ "externalSourceGUID": "add guid here",
1691
+ "externalSourceName": "add qualified name here",
1692
+ "effectiveTime" : "{{$isoTimestamp}}",
1693
+ "forLineage" : false,
1694
+ "forDuplicateProcessing" : false
1695
+ }
1696
+
1697
+ """
1698
+
1699
+ url = (
1700
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
1701
+ f"/agreements/{agreement_guid}/contract-links/{external_ref_guid}/detach")
1702
+ await self._async_delete_request(url, body)
1703
+ logger.info(f"Detached contract: {external_ref_guid} from {agreement_guid}")
1704
+
1705
+
1706
+ @dynamic_catch
1707
+ def detach_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
1708
+ """Detach an external reference to a contract, from an agreement. Request body is optional.
1709
+
1710
+ Parameters
1711
+ ----------
1712
+ agreement_guid: str
1713
+ The guid of the agreement to link.
1714
+ external_ref_guid: str
1715
+ The guid of the element to attach.
1716
+ body: dict, optional, default = None
1717
+ A dict representing the details of the relationship.
1718
+
1719
+ Returns
1720
+ -------
1721
+ Nothing
1722
+
1723
+ Raises
1724
+ ------
1725
+ InvalidParameterException
1726
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1727
+ PropertyServerException
1728
+ Raised by the server when an issue arises in processing a valid request
1729
+ NotAuthorizedException
1730
+ The principle specified by the user_id does not have authorization for the requested action
1731
+
1732
+ Notes
1733
+ _____
1734
+ {
1735
+ "class" : "MetadataSourceRequestBody",
1736
+ "externalSourceGUID": "add guid here",
1737
+ "externalSourceName": "add qualified name here",
1738
+ "effectiveTime" : "{{$isoTimestamp}}",
1739
+ "forLineage" : false,
1740
+ "forDuplicateProcessing" : false
1741
+ }
1742
+
1743
+ """
1744
+ loop = asyncio.get_event_loop()
1745
+ loop.run_until_complete(self._async_detach_contract(agreement_guid, external_ref_guid, body))
1746
+
1747
+ #
1748
+ # Digital Subscriptions
1749
+ #
1750
+
1751
+
1752
+ @dynamic_catch
1753
+ async def _async_create_digital_subscription(self, body: dict | NewElementRequestBody) -> str:
1754
+ """Create a new external_reference that represents a type of agreement called a digital_subscription. Async version.
1755
+
1756
+ Parameters
1757
+ ----------
1758
+ body | NewElementRequewstBody: dict
1759
+ A structure representing the details of the external_reference to create.
1760
+
1761
+ Returns
1762
+ -------
1763
+ str - the guid of the created external_reference
1764
+
1765
+ Raises
1766
+ ------
1767
+ InvalidParameterException
1768
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1769
+ PropertyServerException
1770
+ Raised by the server when an issue arises in processing a valid request
1771
+ NotAuthorizedException
1772
+ The principle specified by the user_id does not have authorization for the requested action
1773
+
1774
+ Notes
1775
+ -----
1776
+ Note: the three dates: introductionDate, nextVersionDate, and withdrawDate must
1777
+ be valid dates if specified, otherwise you will get a 400 error response.
1778
+
1779
+ JSON Structure looks like:
1780
+ {
1781
+ "class" : "NewElementRequestBody",
1782
+ "isOwnAnchor" : true,
1783
+ "anchorScopeGUID" : "optional GUID of search scope",
1784
+ "parentGUID" : "xxx",
1785
+ "parentRelationshipTypeName" : "CollectionMembership",
1786
+ "parentAtEnd1": true,
1787
+ "properties": {
1788
+ "class" : "DigitalSubscriptionProperties",
1789
+ "qualifiedName": "DigitalSubscription::Add subscription name here",
1790
+ "name" : "display name",
1791
+ "description" : "Add description of the subscription here",
1792
+ "userDefinedStatus" : "OBSOLETE",
1793
+ "identifier" : "Add subscription identifier here",
1794
+ "supportLevel" : "Add the level of support agreed/requested",
1795
+ "serviceLevels" : {
1796
+ "property1Name" : "property1Value",
1797
+ "property2Name" : "property2Value"
1798
+ },
1799
+ "additionalProperties": {
1800
+ "property1Name" : "property1Value",
1801
+ "property2Name" : "property2Value"
1802
+ }
1803
+ },
1804
+ "externalSourceGUID": "add guid here",
1805
+ "externalSourceName": "add qualified name here",
1806
+ "effectiveTime" : "{{$isoTimestamp}}",
1807
+ "forLineage" : false,
1808
+ "forDuplicateProcessing" : false
1809
+ }
1810
+
1811
+ With a lifecycle, the body is:
1812
+
1813
+ The DigitalSubscription is a type of Agreement and so can have lifecycle states.
1814
+ Note: the three dates: introductionDate, nextVersionDate, and withdrawDate must be valid dates if specified,
1815
+ otherwise you will get a 400 error response.
1816
+ The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED
1817
+ ACTIVE, DEPRECATED, OTHER. If using OTHER, set the userDefinedStatus with the statu value you want.
1818
+
1819
+ {
1820
+ "class" : "NewAgreementRequestBody",
1821
+ "isOwnAnchor" : true,
1822
+ "anchorScopeGUID" : "optional GUID of search scope",
1823
+ "parentGUID" : "xxx",
1824
+ "parentRelationshipTypeName" : "CollectionMembership",
1825
+ "parentAtEnd1": true,
1826
+ "properties": {
1827
+ "class" : "DigitalSubscriptionProperties",
1828
+ "qualifiedName": "DigitalSubscription::Add subscription name here",
1829
+ "name" : "display name",
1830
+ "description" : "Add description of the subscription here",
1831
+ "userDefinedStatus" : "OBSOLETE",
1832
+ "identifier" : "Add subscription identifier here",
1833
+ "supportLevel" : "Add the level of support agreed/requested",
1834
+ "serviceLevels" : {
1835
+ "property1Name" : "property1Value",
1836
+ "property2Name" : "property2Value"
1837
+ },
1838
+ "additionalProperties": {
1839
+ "property1Name" : "property1Value",
1840
+ "property2Name" : "property2Value"
1841
+ }
1842
+ },
1843
+ "initialStatus" : "OTHER",
1844
+ "externalSourceGUID": "add guid here",
1845
+ "externalSourceName": "add qualified name here",
1846
+ "effectiveTime" : "{{$isoTimestamp}}",
1847
+ "forLineage" : false,
1848
+ "forDuplicateProcessing" : false
1849
+ }
1850
+ """
1851
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
1852
+ return await self._async_create_element_body_request(url, "DigitalSubscriptionProperties", body)
1853
+
1854
+
1855
+ def create_digital_subscription(self, body: dict) -> str:
1856
+ """Create a new external_reference that represents a type of agreement called a digital_subscription.
1857
+
1858
+ Parameters
1859
+ ----------
1860
+ body: dict
1861
+ A dict representing the details of the external_reference to create.
1862
+
1863
+ Returns
1864
+ -------
1865
+ str - the guid of the created external_reference
1866
+
1867
+ Raises
1868
+ ------
1869
+ InvalidParameterException
1870
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1871
+ PropertyServerException
1872
+ Raised by the server when an issue arises in processing a valid request
1873
+ NotAuthorizedException
1874
+ The principle specified by the user_id does not have authorization for the requested action
1875
+
1876
+ Notes
1877
+ -----
1878
+ Note: the three dates: introductionDate, nextVersionDate, and withdrawDate must
1879
+ be valid dates if specified, otherwise you will get a 400 error response.
1880
+
1881
+ JSON Structure looks like:
1882
+ With a lifecycle, the body is:
1883
+
1884
+ The DigitalSubscription is a type of Agreement and so can have lifecycle states.
1885
+ Note: the three dates: introductionDate, nextVersionDate, and withdrawDate must be valid dates if specified,
1886
+ otherwise you will get a 400 error response.
1887
+ The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED
1888
+ ACTIVE, DEPRECATED, OTHER. If using OTHER, set the userDefinedStatus with the statu value you want.
1889
+
1890
+ {
1891
+ "class" : "NewAgreementRequestBody",
1892
+ "isOwnAnchor" : true,
1893
+ "anchorScopeGUID" : "optional GUID of search scope",
1894
+ "parentGUID" : "xxx",
1895
+ "parentRelationshipTypeName" : "CollectionMembership",
1896
+ "parentAtEnd1": true,
1897
+ "properties": {
1898
+ "class" : "DigitalSubscriptionProperties",
1899
+ "qualifiedName": "DigitalSubscription::Add subscription name here",
1900
+ "name" : "display name",
1901
+ "description" : "Add description of the subscription here",
1902
+ "userDefinedStatus" : "OBSOLETE",
1903
+ "identifier" : "Add subscription identifier here",
1904
+ "supportLevel" : "Add the level of support agreed/requested",
1905
+ "serviceLevels" : {
1906
+ "property1Name" : "property1Value",
1907
+ "property2Name" : "property2Value"
1908
+ },
1909
+ "additionalProperties": {
1910
+ "property1Name" : "property1Value",
1911
+ "property2Name" : "property2Value"
1912
+ }
1913
+ },
1914
+ "initialStatus" : "OTHER",
1915
+ "externalSourceGUID": "add guid here",
1916
+ "externalSourceName": "add qualified name here",
1917
+ "effectiveTime" : "{{$isoTimestamp}}",
1918
+ "forLineage" : false,
1919
+ "forDuplicateProcessing" : false
1920
+ }
1921
+ """
1922
+ loop = asyncio.get_event_loop()
1923
+ resp = loop.run_until_complete(self._async_create_digital_subscription(body))
1924
+ return resp
1925
+
1926
+
1927
+ @dynamic_catch
1928
+ async def _async_update_digital_subscription(self, digital_subscription_guid: str,
1929
+ body: dict | UpdateElementRequestBody) -> None:
1930
+ """Update the properties of the digital_subscription external_reference. Async version.
1931
+
1932
+ Parameters
1933
+ ----------
1934
+ digital_subscription_guid: str
1935
+ The guid of the digital_subscription to update.
1936
+ body: dict | UpdateElementRequestBody
1937
+ A structure representing the details of the external_reference to create.
1938
+
1939
+ Returns
1940
+ -------
1941
+ Nothing
1942
+
1943
+ Raises
1944
+ ------
1945
+ InvalidParameterException
1946
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
1947
+ PropertyServerException
1948
+ Raised by the server when an issue arises in processing a valid request
1949
+ NotAuthorizedException
1950
+ The principle specified by the user_id does not have authorization for the requested action
1951
+
1952
+ Notes
1953
+ -----
1954
+ JSON Structure looks like:
1955
+ {
1956
+ "class" : "UpdateElementRequestBody",
1957
+ "properties": {
1958
+ "class" : "DigitalSubscriptionProperties",
1959
+ "qualifiedName": "DigitalSubscription::Add subscription name here",
1960
+ "name" : "display name",
1961
+ "description" : "Add description of the subscription here",
1962
+ "userDefinedStatus" : "OBSOLETE",
1963
+ "identifier" : "Add subscription identifier here",
1964
+ "supportLevel" : "Add the level of support agreed/requested",
1965
+ "serviceLevels" : {
1966
+ "property1Name" : "property1Value",
1967
+ "property2Name" : "property2Value"
1968
+ },
1969
+ "additionalProperties": {
1970
+ "property1Name" : "property1Value",
1971
+ "property2Name" : "property2Value"
1972
+ }
1973
+ },
1974
+ "externalSourceGUID": "add guid here",
1975
+ "externalSourceName": "add qualified name here",
1976
+ "effectiveTime" : "{{$isoTimestamp}}",
1977
+ "forLineage" : false,
1978
+ "forDuplicateProcessing" : false
1979
+ }
1980
+ """
1981
+ url = (
1982
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references/"
1983
+ f"{digital_subscription_guid}/update")
1984
+ await self._async_update_element_body_request(url, ["DigitalSubscriptionProperties"], body)
1985
+ logger.info(f"Updated digital subscription {digital_subscription_guid}")
1986
+
1987
+
1988
+ @dynamic_catch
1989
+ def update_digital_subscription(self, digital_subscription_guid: str, body: dict, ):
1990
+ """Update the properties of the DigitalProduct classification attached to a external_reference.
1991
+
1992
+ Parameters
1993
+ ----------
1994
+ digital_subscription_guid: str
1995
+ The guid of the digital_subscription to update.
1996
+ body: dict
1997
+ A dict representing the details of the external_reference to create.
1998
+ replace_all_props: bool, optional, defaults to False
1999
+ Whether to replace all properties in the external_reference.
2000
+
2001
+
2002
+ Returns
2003
+ -------
2004
+ Nothing
2005
+
2006
+ Raises
2007
+ ------
2008
+ InvalidParameterException
2009
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2010
+ PropertyServerException
2011
+ Raised by the server when an issue arises in processing a valid request
2012
+ NotAuthorizedException
2013
+ The principle specified by the user_id does not have authorization for the requested action
2014
+
2015
+ Notes
2016
+ -----
2017
+ JSON Structure looks like:
2018
+ {
2019
+ "class" : "UpdateElementRequestBody",
2020
+ "properties": {
2021
+ "class" : "AgreementProperties",
2022
+ "qualifiedName": "Agreement::Add digital_subscription name here",
2023
+ "name" : "display name",
2024
+ "description" : "Add description of the digital_subscription here",
2025
+ "userDefinedStatus" : "OBSOLETE",
2026
+ "identifier" : "Add digital_subscription identifier here",
2027
+ "additionalProperties": {
2028
+ "property1Name" : "property1Value",
2029
+ "property2Name" : "property2Value"
2030
+ }
2031
+ },
2032
+ "externalSourceGUID": "add guid here",
2033
+ "externalSourceName": "add qualified name here",
2034
+ "effectiveTime" : "{{$isoTimestamp}}",
2035
+ "forLineage" : false,
2036
+ "forDuplicateProcessing" : false
2037
+ }
2038
+
2039
+ """
2040
+ loop = asyncio.get_event_loop()
2041
+ loop.run_until_complete(
2042
+ self._async_update_digital_subscription(digital_subscription_guid, body))
2043
+
2044
+
2045
+ @dynamic_catch
2046
+ async def _async_update_digital_subscription_status(self, digital_subscription_guid: str, status: str = None,
2047
+ body: dict | UpdateStatusRequestBody = None) -> None:
2048
+ """Update the status of a digital_subscription external_reference. Async version.
2049
+
2050
+ Parameters
2051
+ ----------
2052
+ digital_subscription_guid: str
2053
+ The guid of the digital product external_reference to update.
2054
+ status: str, optional
2055
+ The new status of the digital_subscription external_reference. Will be used only if body is not provided.
2056
+ body: dict | UpdateStatusRequestBody, optional, defaults to None
2057
+ A structure representing the details of the external_reference to create.
2058
+
2059
+ Returns
2060
+ -------
2061
+ Nothing
2062
+
2063
+ Raises
2064
+ ------
2065
+ InvalidParameterException
2066
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2067
+ PropertyServerException
2068
+ Raised by the server when an issue arises in processing a valid request
2069
+ NotAuthorizedException
2070
+ The principle specified by the user_id does not have authorization for the requested action
2071
+
2072
+ Notes
2073
+ -----
2074
+ JSON Structure looks like:
2075
+ {
2076
+ "class": "UpdateStatusRequestBody",
2077
+ "status": "APPROVED",
2078
+ "externalSourceGUID": "add guid here",
2079
+ "externalSourceName": "add qualified name here",
2080
+ "effectiveTime": "{{$isoTimestamp}}",
2081
+ "forLineage": false,
2082
+ "forDuplicateProcessing": false
2083
+ }
2084
+ """
2085
+ url = (
2086
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
2087
+ f"/agreements/"
2088
+ f"{digital_subscription_guid}/update-status")
2089
+ await self._async_update_status_request(url, status, body)
2090
+ logger.info(f"Updated status for DigitalProduct {digital_subscription_guid}")
2091
+
2092
+
2093
+ @dynamic_catch
2094
+ def update_digital_subscription_status(self, digital_subscription_guid: str,
2095
+ body: dict | UpdateStatusRequestBody = None, ):
2096
+ """Update the status of an digital_subscription external_reference. Async version.
2097
+
2098
+ Parameters
2099
+ ----------
2100
+ digital_subscription_guid: str
2101
+ The guid of the digital product external_reference to update.
2102
+ body: dict
2103
+ A dict representing the details of the external_reference to create.
2104
+
2105
+ Returns
2106
+ -------
2107
+ Nothing
2108
+
2109
+ Raises
2110
+ ------
2111
+ InvalidParameterException
2112
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2113
+ PropertyServerException
2114
+ Raised by the server when an issue arises in processing a valid request
2115
+ NotAuthorizedException
2116
+ The principle specified by the user_id does not have authorization for the requested action
2117
+
2118
+ Notes
2119
+ -----
2120
+ JSON Structure looks like:
2121
+ {
2122
+ "class": "AgreementStatusRequestBody",
2123
+ "status": "APPROVED",
2124
+ "externalSourceGUID": "add guid here",
2125
+ "externalSourceName": "add qualified name here",
2126
+ "effectiveTime": "{{$isoTimestamp}}",
2127
+ "forLineage": false,
2128
+ "forDuplicateProcessing": false
2129
+ }
2130
+
2131
+ """
2132
+ loop = asyncio.get_event_loop()
2133
+ loop.run_until_complete(self._async_update_digital_subscription_status(digital_subscription_guid, body))
2134
+
2135
+
2136
+ @dynamic_catch
2137
+ async def _async_link_subscriber(self, subscriber_guid: str, subscription_guid: str,
2138
+ body: dict | NewRelationshipRequestBody = None) -> None:
2139
+ """ Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
2140
+ products, team, or business capabilities to be the subscriber. The subscription is an element of type
2141
+ DigitalSubscription.
2142
+ Async version.
2143
+
2144
+ Parameters
2145
+ ----------
2146
+ subscriber_guid: str
2147
+ The unique identifier of the subscriber.
2148
+ subscription_guid: str
2149
+ The identifier of the subscription.
2150
+ body: dict | NewRelationshipRequestBody, optional, default = None
2151
+ A structure representing the details of the relationship.
2152
+
2153
+ Returns
2154
+ -------
2155
+ Nothing
2156
+
2157
+ Raises
2158
+ ------
2159
+ InvalidParameterException
2160
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2161
+ PropertyServerException
2162
+ Raised by the server when an issue arises in processing a valid request
2163
+ NotAuthorizedException
2164
+ The principle specified by the user_id does not have authorization for the requested action
2165
+
2166
+ Notes
2167
+ -----
2168
+ JSON Structure looks like:
2169
+ {
2170
+ "class" : "NewRelationshipRequestBody",
2171
+ "externalSourceGUID": "add guid here",
2172
+ "externalSourceName": "add qualified name here",
2173
+ "effectiveTime" : "{{$isoTimestamp}}",
2174
+ "forLineage" : false,
2175
+ "forDuplicateProcessing" : false,
2176
+ "properties": {
2177
+ "class": "DigitalSubscriberProperties",
2178
+ "subscriberId": "add id here",
2179
+ "effectiveFrom": "{{$isoTimestamp}}",
2180
+ "effectiveTo": "{{$isoTimestamp}}"
2181
+ }
2182
+ }
2183
+ """
2184
+ url = (
2185
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
2186
+ f"/subscribers/"
2187
+ f"{subscriber_guid}/subscriptions/{subscription_guid}/attach")
2188
+ await self._async_new_relationship_request(url, "DigitalSubscriberProperties", body)
2189
+ logger.info(f"Linking subscriber {subscriber_guid} to subscription {subscription_guid}")
2190
+
2191
+
2192
+ @dynamic_catch
2193
+ def link_subscriber(self, subscriber_guid: str, subscription_guid: str,
2194
+ body: dict | NewRelationshipRequestBody = None):
2195
+ """ Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
2196
+ products, team, or business capabilities to be the subscriber. The subscription is an element of type
2197
+ DigitalSubscription.
2198
+ Async version.
2199
+
2200
+ Parameters
2201
+ ----------
2202
+ subscriber_guid: str
2203
+ The unique identifier of the subscriber.
2204
+ subscription_guid: str
2205
+ The identifier of the subscription.
2206
+ body: dict, optional, default = None
2207
+ A dict representing the details of the relationship.
2208
+
2209
+ Returns
2210
+ -------
2211
+ Nothing
2212
+
2213
+ Raises
2214
+ ------
2215
+ InvalidParameterException
2216
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2217
+ PropertyServerException
2218
+ Raised by the server when an issue arises in processing a valid request
2219
+ NotAuthorizedException
2220
+ The principle specified by the user_id does not have authorization for the requested action
2221
+
2222
+ Notes
2223
+ -----
2224
+ JSON Structure looks like:
2225
+ {
2226
+ "class" : "RelationshipRequestBody",
2227
+ "externalSourceGUID": "add guid here",
2228
+ "externalSourceName": "add qualified name here",
2229
+ "effectiveTime" : "{{$isoTimestamp}}",
2230
+ "forLineage" : false,
2231
+ "forDuplicateProcessing" : false,
2232
+ "properties": {
2233
+ "class": "DigitalSubscriberProperties",
2234
+ "subscriberId": "add id here",
2235
+ "effectiveFrom": "{{$isoTimestamp}}",
2236
+ "effectiveTo": "{{$isoTimestamp}}"
2237
+ }
2238
+ }
2239
+ """
2240
+ loop = asyncio.get_event_loop()
2241
+ loop.run_until_complete(self._async_link_subscriber(subscriber_guid, subscription_guid, body))
2242
+
2243
+
2244
+ @dynamic_catch
2245
+ async def _async_detach_subscriber(self, subscriber_guid: str, subscription_guid: str,
2246
+ body: dict | DeleteRequestBody = None) -> None:
2247
+ """ Detach a subscriber from a subscription Request body is optional. Async version.
2248
+
2249
+ Parameters
2250
+ ----------
2251
+ subscriber_guid: str
2252
+ The unique identifier of the subscriber.
2253
+ subscription_guid: str
2254
+ The unique identifier of the subscription.
2255
+ body: dict | DeleteRequestBody, optional, default = None
2256
+ A structure representing the details of the relationship.
2257
+
2258
+ Returns
2259
+ -------
2260
+ Nothing
2261
+
2262
+ Raises
2263
+ ------
2264
+ InvalidParameterException
2265
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2266
+ PropertyServerException
2267
+ Raised by the server when an issue arises in processing a valid request
2268
+ NotAuthorizedException
2269
+ The principle specified by the user_id does not have authorization for the requested action
2270
+
2271
+ Notes
2272
+ -----
2273
+ JSON Structure looks like:
2274
+ {
2275
+ "class": "MetadataSourceRequestBody",
2276
+ "externalSourceGUID": "add guid here",
2277
+ "externalSourceName": "add qualified name here",
2278
+ "effectiveTime": "{{$isoTimestamp}}",
2279
+ "forLineage": false,
2280
+ "forDuplicateProcessing": false
2281
+ }
2282
+ """
2283
+ url = (
2284
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/external_reference-manager/external_references"
2285
+ f"/agreements/"
2286
+ f"{subscriber_guid}/agreement-actors/{subscription_guid}/detach")
2287
+ await self._async_delete_request(url, body)
2288
+ logger.info(f"Detached subscriber {subscriber_guid} from subscription {subscription_guid}")
2289
+
2290
+
2291
+ def detach_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict | DeleteRequestBody = None):
2292
+ """ Detach a subscriber from a subscription. Request body is optional.
2293
+
2294
+ Parameters
2295
+ ----------
2296
+ subscriber_guid: str
2297
+ The unique identifier of the subscriber.
2298
+ subscription_guid: str
2299
+ The unique identifier of the subscription.
2300
+ body: dict, optional, default = None
2301
+ A dict representing the details of the relationship.
2302
+
2303
+ Returns
2304
+ -------
2305
+ Nothing
2306
+
2307
+ Raises
2308
+ ------
2309
+ InvalidParameterException
2310
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2311
+ PropertyServerException
2312
+ Raised by the server when an issue arises in processing a valid request
2313
+ NotAuthorizedException
2314
+ The principle specified by the user_id does not have authorization for the requested action
2315
+
2316
+ Notes
2317
+ -----
2318
+ JSON Structure looks like:
2319
+ {
2320
+ "class": "MetadataSourceRequestBody",
2321
+ "externalSourceGUID": "add guid here",
2322
+ "externalSourceName": "add qualified name here",
2323
+ "effectiveTime": "{{$isoTimestamp}}",
2324
+ "forLineage": false,
2325
+ "forDuplicateProcessing": false
2326
+ }
2327
+ """
2328
+ loop = asyncio.get_event_loop()
2329
+ loop.run_until_complete(self._async_detach_subscriber(subscriber_guid, subscription_guid, body))
2330
+
2331
+ #
2332
+ #
2333
+ #
2334
+
2335
+
2336
+ @dynamic_catch
2337
+ async def _async_attach_external_reference(self, parent_guid: str, external_reference_guid: str,
2338
+ body: dict | NewRelationshipRequestBody = None):
2339
+ """ Connect an existing external_reference to an element using the ResourceList relationship (0019).
2340
+ Async version.
2341
+
2342
+ Parameters
2343
+ ----------
2344
+ parent_guid: str
2345
+ The unique identifier of the parent to attach to.
2346
+ external_reference_guid: str
2347
+ The identifier of the external_reference being attached.
2348
+ body: dict | NewRelationshipRequestBody, optional, default = None
2349
+ A structure representing the details of the relationship.
2350
+
2351
+ Returns
2352
+ -------
2353
+ Nothing
2354
+
2355
+ Raises
2356
+ ------
2357
+ InvalidParameterException
2358
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2359
+ PropertyServerException
2360
+ Raised by the server when an issue arises in processing a valid request
2361
+ NotAuthorizedException
2362
+ The principle specified by the user_id does not have authorization for the requested action
2363
+
2364
+ Notes
2365
+ -----
2366
+ JSON Structure looks like:
2367
+
2368
+ {
2369
+ "class" : "NewRelationshipRequestBody",
2370
+ "properties": {
2371
+ "class": "ResourceListProperties",
2372
+ "resourceUse": "Add valid value here",
2373
+ "resourceUseDescription": "Add description here",
2374
+ "watchResource": false,
2375
+ "resourceUseProperties": {
2376
+ "property1Name": "property1Value",
2377
+ "property2Name": "property2Value"
2378
+ }
2379
+ },
2380
+ "externalSourceGUID": "add guid here",
2381
+ "externalSourceName": "add qualified name here",
2382
+ "effectiveTime" : "{{$isoTimestamp}}",
2383
+ "forLineage" : false,
2384
+ "forDuplicateProcessing" : false
2385
+ }
2386
+
2387
+ """
2388
+
2389
+ url = (
2390
+ f"{self.platform_url}/servers/"
2391
+ f"{self.view_server}/api/open-metadata/external_reference-manager/metadata-elements/"
2392
+ f"{parent_guid}/external_references/{external_reference_guid}/attach")
2393
+ await self._async_new_relationship_request(url, "ResourceListProperties", body)
2394
+ logger.info(f"Attached {external_reference_guid} to {parent_guid}")
2395
+
2396
+
2397
+ @dynamic_catch
2398
+ def attach_external_reference(self, parent_guid: str, external_reference_guid: str,
2399
+ body: dict | NewRelationshipRequestBody = None):
2400
+ """ Connect an existing external_reference to an element using the ResourceList relationship (0019).
2401
+
2402
+ Parameters
2403
+ ----------
2404
+ parent_guid: str
2405
+ The unique identifier of the parent to attach to.
2406
+ external_reference_guid: str
2407
+ The identifier of the external_reference being attached.
2408
+ body: dict, optional, default = None
2409
+ A dict representing the details of the relationship.
2410
+ make_anchor: bool, optional, default = False
2411
+ Indicates if the external_reference should be anchored to the element.
2412
+
2413
+ Returns
2414
+ -------
2415
+ Nothing
2416
+
2417
+ Raises
2418
+ ------
2419
+ InvalidParameterException
2420
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2421
+ PropertyServerException
2422
+ Raised by the server when an issue arises in processing a valid request
2423
+ NotAuthorizedException
2424
+ The principle specified by the user_id does not have authorization for the requested action
2425
+
2426
+ Notes
2427
+ -----
2428
+ JSON Structure looks like:
2429
+
2430
+ {
2431
+ "class" : "RelationshipRequestBody",
2432
+ "properties": {
2433
+ "class": "ResourceListProperties",
2434
+ "resourceUse": "Add valid value here",
2435
+ "resourceUseDescription": "Add description here",
2436
+ "watchResource": false,
2437
+ "resourceUseProperties": {
2438
+ "property1Name": "property1Value",
2439
+ "property2Name": "property2Value"
2440
+ }
2441
+ },
2442
+ "externalSourceGUID": "add guid here",
2443
+ "externalSourceName": "add qualified name here",
2444
+ "effectiveTime" : "{{$isoTimestamp}}",
2445
+ "forLineage" : false,
2446
+ "forDuplicateProcessing" : false
2447
+ }
2448
+ """
2449
+ loop = asyncio.get_event_loop()
2450
+ loop.run_until_complete(self._async_attach_external_reference(parent_guid, external_reference_guid, body))
2451
+
2452
+
2453
+ @dynamic_catch
2454
+ async def _async_detach_external_reference(self, parent_guid: str, external_reference_guid: str,
2455
+ body: dict | DeleteRequestBody = None):
2456
+ """ Detach an existing external_reference from an element. If the external_reference is anchored to the element,
2457
+ it is delete.
2458
+ Async version.
2459
+
2460
+ Parameters
2461
+ ----------
2462
+ parent_guid: str
2463
+ The unique identifier of the parent to detach from.
2464
+ external_reference_guid: str
2465
+ The identifier of the external_reference being detached.
2466
+ body: dict | DeleteRequestBody, optional, default = None
2467
+ A structure representing the details of the relationship.
2468
+
2469
+
2470
+ Returns
2471
+ -------
2472
+ Nothing
2473
+
2474
+ Raises
2475
+ ------
2476
+ InvalidParameterException
2477
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2478
+ PropertyServerException
2479
+ Raised by the server when an issue arises in processing a valid request
2480
+ NotAuthorizedException
2481
+ The principle specified by the user_id does not have authorization for the requested action
2482
+
2483
+ Notes
2484
+ -----
2485
+ JSON Structure looks like:
2486
+ {
2487
+ "class": "DeleteRequestBody",
2488
+ "externalSourceGUID": "add guid here",
2489
+ "externalSourceName": "add qualified name here",
2490
+ "effectiveTime": "{{$isoTimestamp}}",
2491
+ "forLineage": false,
2492
+ "forDuplicateProcessing": false
2493
+ }
2494
+
2495
+ """
2496
+ url = (
2497
+ f"{self.platform_url}/servers/"
2498
+ f"{self.view_server}/api/open-metadata/external_reference-manager/metadata-elements/"
2499
+ f"{parent_guid}/external_references/{external_reference_guid}/detach")
2500
+ await self._async_delete_request(url, body)
2501
+ logger.info(f"Detached external_reference {external_reference_guid} from {parent_guid}")
2502
+
2503
+
2504
+ def detach_external_reference(self, parent_guid: str, external_reference_guid: str,
2505
+ body: dict | DeleteRequestBody = None):
2506
+ """ Detach an existing external_reference from an element. If the external_reference is anchored to the element,
2507
+ it is delete.
2508
+
2509
+ Parameters
2510
+ ----------
2511
+ parent_guid: str
2512
+ The unique identifier of the parent to detach from.
2513
+ external_reference_guid: str
2514
+ The identifier of the external_reference being detached.
2515
+ body: dict, optional, default = None
2516
+ A dict representing the details of the relationship.
2517
+
2518
+ Returns
2519
+ -------
2520
+ Nothing
2521
+
2522
+ Raises
2523
+ ------
2524
+ InvalidParameterException
2525
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2526
+ PropertyServerException
2527
+ Raised by the server when an issue arises in processing a valid request
2528
+ NotAuthorizedException
2529
+ The principle specified by the user_id does not have authorization for the requested action
2530
+
2531
+ Notes
2532
+ -----
2533
+ JSON Structure looks like:
2534
+ {
2535
+ "class": "MetadataSourceRequestBody",
2536
+ "externalSourceGUID": "add guid here",
2537
+ "externalSourceName": "add qualified name here",
2538
+ "effectiveTime": "{{$isoTimestamp}}",
2539
+ "forLineage": false,
2540
+ "forDuplicateProcessing": false
2541
+ }
2542
+ """
2543
+ loop = asyncio.get_event_loop()
2544
+ loop.run_until_complete(self._async_detach_external_reference(parent_guid, external_reference_guid, body))
2545
+
2546
+
2547
+ @dynamic_catch
2548
+ async def _async_delete_external_reference(self, external_reference_guid: str, body: dict | DeleteRequestBody = None,
2549
+ cascade: bool = False) -> None:
2550
+ """Delete a external_reference. It is detected from all parent elements. If members are anchored to the external_reference
2551
+ then they are also deleted. Async version
2552
+
2553
+
2554
+ Parameters
2555
+ ----------
2556
+ external_reference_guid: str
2557
+ The guid of the external_reference to delete.
2558
+
2559
+ cascade: bool, optional, defaults to True
2560
+ If true, a cascade delete is performed.
2561
+
2562
+ body: dict | DeleteRequestBody, optional, default = None
2563
+ A structure representing the details of the relationship.
2564
+
2565
+ Returns
2566
+ -------
2567
+ Nothing
2568
+
2569
+ Raises
2570
+ ------
2571
+ InvalidParameterException
2572
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2573
+ PropertyServerException
2574
+ Raised by the server when an issue arises in processing a valid request
2575
+ NotAuthorizedException
2576
+ The principle specified by the user_id does not have authorization for the requested action
2577
+
2578
+ Notes
2579
+ _____
2580
+ JSON Structure looks like:
2581
+ {
2582
+ "class": "DeleteRequestBody",
2583
+ "externalSourceGUID": "add guid here",
2584
+ "externalSourceName": "add qualified name here",
2585
+ "effectiveTime": "{{$isoTimestamp}}",
2586
+ "forLineage": false,
2587
+ "forDuplicateProcessing": false
2588
+ }
2589
+
2590
+
2591
+ """
2592
+ url = f"{self.external_reference_command_root}/{external_reference_guid}/delete"
2593
+ await self._async_delete_request(url, body, cascade)
2594
+ logger.info(f"Deleted external_reference {external_reference_guid} with cascade {cascade}")
2595
+
2596
+
2597
+ def delete_external_reference(self, external_reference_guid: str, body: dict | DeleteRequestBody = None,
2598
+ cascade: bool = False) -> None:
2599
+ """Delete a external_reference. It is deleted from all parent elements. If members are anchored to the external_reference
2600
+ then they are also deleted.
2601
+
2602
+ Parameters
2603
+ ----------
2604
+ external_reference_guid: str
2605
+ The guid of the external_reference to delete.
2606
+
2607
+ cascade: bool, optional, defaults to True
2608
+ If true, a cascade delete is performed.
2609
+
2610
+ body: dict DeleteRequestBodyt, optional, default = None
2611
+ A dict representing the details of the relationship.
2612
+
2613
+ Returns
2614
+ -------
2615
+ Nothing
2616
+
2617
+ Raises
2618
+ ------
2619
+ InvalidParameterException
2620
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2621
+ PropertyServerException
2622
+ Raised by the server when an issue arises in processing a valid request
2623
+ NotAuthorizedException
2624
+ The principle specified by the user_id does not have authorization for the requested action
2625
+
2626
+ Notes
2627
+ _____
2628
+ JSON Structure looks like:
2629
+
2630
+
2631
+
2632
+ """
2633
+ loop = asyncio.get_event_loop()
2634
+ loop.run_until_complete(self._async_delete_external_reference(external_reference_guid, body, cascade))
2635
+
2636
+
2637
+ @dynamic_catch
2638
+ async def _async_add_to_external_reference(self, external_reference_guid: str, element_guid: str,
2639
+ body: dict | NewRelationshipRequestBody = None, ) -> None:
2640
+ """Add an element to a external_reference. The request body is optional. Async version.
2641
+
2642
+ Parameters
2643
+ ----------
2644
+ external_reference_guid: str
2645
+ identity of the external_reference to return members for.
2646
+ element_guid: str
2647
+ Effective time of the query. If not specified will default to any time.
2648
+ body: dict NewRelationshipRequestBody, optional, defaults to None
2649
+ The body of the request to add to the external_reference. See notes.
2650
+
2651
+ Returns
2652
+ -------
2653
+ None
2654
+
2655
+ Raises
2656
+ ------
2657
+
2658
+ InvalidParameterException
2659
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2660
+ PropertyServerException
2661
+ Raised by the server when an issue arises in processing a valid request
2662
+ NotAuthorizedException
2663
+ The principle specified by the user_id does not have authorization for the requested action
2664
+
2665
+ Notes
2666
+ -----
2667
+ Example body:
2668
+ { "class": "NewRelationshipRequestBody",
2669
+ "properties" : {
2670
+ "class" : "CollectionMembershipProperties",
2671
+ "membershipRationale": "xxx",
2672
+ "createdBy": "user id here",
2673
+ "expression": "expression that described why the element is a part of this external_reference",
2674
+ "confidence": 100,
2675
+ "status": "PROPOSED",
2676
+ "userDefinedStatus": "Add valid value here",
2677
+ "steward": "identifier of steward that validated this member",
2678
+ "stewardTypeName": "type name of element identifying the steward",
2679
+ "stewardPropertyName": "property name if the steward's identifier",
2680
+ "source": "source of the member",
2681
+ "notes": "Add notes here"
2682
+ },
2683
+ },
2684
+ "externalSourceGUID": "add guid here",
2685
+ "externalSourceName": "add qualified name here",
2686
+ "effectiveTime" : "{{$isoTimestamp}}",
2687
+ "forLineage" : false,
2688
+ "forDuplicateProcessing" : false
2689
+ }
2690
+
2691
+ """
2692
+
2693
+ url = (f"{self.external_reference_command_root}/{external_reference_guid}/members/"
2694
+ f"{element_guid}/attach")
2695
+ await self._async_new_relationship_request(url, "CollectionMembershipProperties", body)
2696
+ logger.info(f"Added {element_guid} to {external_reference_guid}")
2697
+
2698
+
2699
+ def add_to_external_reference(self, external_reference_guid: str, element_guid: str,
2700
+ body: dict | NewRelationshipRequestBody = None, ) -> None:
2701
+ """Add an element to a external_reference. The request body is optional.
2702
+
2703
+ Parameters
2704
+ ----------
2705
+ external_reference_guid: str
2706
+ identity of the external_reference to return members for.
2707
+ element_guid: str
2708
+ Effective time of the query. If not specified will default to any time.
2709
+ body: dict, optional, defaults to None
2710
+ The body of the request to add to the external_reference. See notes.
2711
+
2712
+ The name of the server to use.
2713
+
2714
+
2715
+ Returns
2716
+ -------
2717
+ None
2718
+
2719
+ Raises
2720
+ ------
2721
+
2722
+ InvalidParameterException
2723
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2724
+ PropertyServerException
2725
+ Raised by the server when an issue arises in processing a valid request
2726
+ NotAuthorizedException
2727
+ The principle specified by the user_id does not have authorization for the requested action
2728
+
2729
+ Notes
2730
+ -----
2731
+ Example body:
2732
+ { "class": "RelationshipRequestBody",
2733
+ "properties" : {
2734
+ "class" : "CollectionMembershipProperties",
2735
+ "membershipRationale": "xxx",
2736
+ "createdBy": "user id here",
2737
+ "expression": "expression that described why the element is a part of this external_reference",
2738
+ "confidence": 100,
2739
+ "status": "PROPOSED",
2740
+ "userDefinedStatus": "Add valid value here",
2741
+ "steward": "identifier of steward that validated this member",
2742
+ "stewardTypeName": "type name of element identifying the steward",
2743
+ "stewardPropertyName": "property name if the steward's identifier",
2744
+ "source": "source of the member",
2745
+ "notes": "Add notes here"
2746
+ },
2747
+ },
2748
+ "externalSourceGUID": "add guid here",
2749
+ "externalSourceName": "add qualified name here",
2750
+ "effectiveTime" : "{{$isoTimestamp}}",
2751
+ "forLineage" : false,
2752
+ "forDuplicateProcessing" : false
2753
+ }
2754
+
2755
+ """
2756
+ loop = asyncio.get_event_loop()
2757
+ loop.run_until_complete(self._async_add_to_external_reference(external_reference_guid, element_guid, body))
2758
+
2759
+
2760
+ def add_term_to_folder(self, folder_guid: str, term_guid: str,
2761
+ body: dict | NewRelationshipRequestBody = None) -> None:
2762
+ """Add a term to a category. The request body is optional."""
2763
+ loop = asyncio.get_event_loop()
2764
+ loop.run_until_complete(self._async_add_to_external_reference(folder_guid, term_guid, body))
2765
+
2766
+
2767
+ @dynamic_catch
2768
+ async def _async_update_external_reference_membership_prop(self, external_reference_guid: str, element_guid: str,
2769
+ body: dict = None,
2770
+ ) -> None:
2771
+ """Update an element's membership to a external_reference. Async version.
2772
+
2773
+ Parameters
2774
+ ----------
2775
+ external_reference_guid: str
2776
+ identity of the external_reference to return members for.
2777
+ element_guid: str
2778
+ Effective time of the query. If not specified will default to any time.
2779
+ body: dict, optional, defaults to None
2780
+ The body of the request to add to the external_reference. See notes.
2781
+ replace_all_props: bool, optional, defaults to False
2782
+ Replace all properties or just update ones specified in body.
2783
+
2784
+ The name of the server to use.
2785
+
2786
+
2787
+ Returns
2788
+ -------
2789
+ None
2790
+
2791
+ Raises
2792
+ ------
2793
+
2794
+ InvalidParameterException
2795
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2796
+ PropertyServerException
2797
+ Raised by the server when an issue arises in processing a valid request
2798
+ NotAuthorizedException
2799
+ The principle specified by the user_id does not have authorization for the requested action
2800
+
2801
+ Notes
2802
+ -----
2803
+ Example body:
2804
+ {
2805
+ "class" : "RelationshipRequestBody",
2806
+ "properties" : {
2807
+ "class": "CollectionMembershipProperties",
2808
+ "membershipRationale": "xxx",
2809
+ "createdBy": "user id here",
2810
+ "expression": "expression that described why the element is a part of this external_reference",
2811
+ "confidence": 100,
2812
+ "membershipStatus": "PROPOSED",
2813
+ "userDefinedStatus": "Add valid value here",
2814
+ "steward": "identifier of steward that validated this member",
2815
+ "stewardTypeName": "type name of element identifying the steward",
2816
+ "stewardPropertyName": "property name if the steward's identifier",
2817
+ "source": "source of the member",
2818
+ "notes": "Add notes here"
2819
+ },
2820
+ "externalSourceGUID": "add guid here",
2821
+ "externalSourceName": "add qualified name here",
2822
+ "effectiveTime" : "{{$isoTimestamp}}",
2823
+ "forLineage" : false,
2824
+ "forDuplicateProcessing" : false
2825
+ }
2826
+ """
2827
+
2828
+ url = (f"{self.external_reference_command_root}/{external_reference_guid}/members/"
2829
+ f"{element_guid}/update")
2830
+ await self._async_update_relationship_request(url, "CollectionMembershipProperties", body)
2831
+ logger.info(f"Updated membership for external_reference {external_reference_guid}")
2832
+
2833
+
2834
+ def update_external_reference_membership_prop(self, external_reference_guid: str, element_guid: str,
2835
+ body: dict | UpdateRelationshipRequestBody = None,
2836
+ ) -> None:
2837
+ """Update an element's membership to a external_reference.
2838
+
2839
+ Parameters
2840
+ ----------
2841
+ external_reference_guid: str
2842
+ identity of the external_reference to return members for.
2843
+ element_guid: str
2844
+ Effective time of the query. If not specified will default to any time.
2845
+ body: dict, optional, defaults to None
2846
+ The body of the request to add to the external_reference. See notes.
2847
+ replace_all_props: bool, optional, defaults to False
2848
+ Replace all properties or just update ones specified in body.
2849
+
2850
+ The name of the server to use.
2851
+
2852
+
2853
+ Returns
2854
+ -------
2855
+ None
2856
+
2857
+ Raises
2858
+ ------
2859
+
2860
+ InvalidParameterException
2861
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2862
+ PropertyServerException
2863
+ Raised by the server when an issue arises in processing a valid request
2864
+ NotAuthorizedException
2865
+ The principle specified by the user_id does not have authorization for the requested action
2866
+
2867
+ Notes
2868
+ -----
2869
+ Example body:
2870
+ {
2871
+ "class" : "RelationshipRequestBody",
2872
+ "properties" : {
2873
+ "class": "CollectionMembershipProperties",
2874
+ "membershipRationale": "xxx",
2875
+ "createdBy": "user id here",
2876
+ "expression": "expression that described why the element is a part of this external_reference",
2877
+ "confidence": 100,
2878
+ "membershipStatus": "PROPOSED",
2879
+ "userDefinedStatus": "Add valid value here",
2880
+ "steward": "identifier of steward that validated this member",
2881
+ "stewardTypeName": "type name of element identifying the steward",
2882
+ "stewardPropertyName": "property name if the steward's identifier",
2883
+ "source": "source of the member",
2884
+ "notes": "Add notes here"
2885
+ },
2886
+ "externalSourceGUID": "add guid here",
2887
+ "externalSourceName": "add qualified name here",
2888
+ "effectiveTime" : "{{$isoTimestamp}}",
2889
+ "forLineage" : false,
2890
+ "forDuplicateProcessing" : false
2891
+ }
2892
+ """
2893
+ loop = asyncio.get_event_loop()
2894
+ loop.run_until_complete(
2895
+ self._async_update_external_reference_membership(external_reference_guid, element_guid, body))
2896
+
2897
+
2898
+ @dynamic_catch
2899
+ async def _async_remove_from_external_reference(self, external_reference_guid: str, element_guid: str,
2900
+ body: dict | DeleteRequestBody = None) -> None:
2901
+ """Remove an element from a external_reference. Async version.
2902
+
2903
+ Parameters
2904
+ ----------
2905
+ external_reference_guid: str
2906
+ identity of the external_reference to return members for.
2907
+ element_guid: str
2908
+ Effective time of the query. If not specified will default to any time.
2909
+ body: dict | DeleteRequestBody, optional, defaults to None
2910
+ The body of the request to add to the external_reference. See notes.
2911
+
2912
+ Returns
2913
+ -------
2914
+ None
2915
+
2916
+ Raises
2917
+ ------
2918
+
2919
+ InvalidParameterException
2920
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2921
+ PropertyServerException
2922
+ Raised by the server when an issue arises in processing a valid request
2923
+ NotAuthorizedException
2924
+ The principle specified by the user_id does not have authorization for the requested action
2925
+
2926
+ Notes
2927
+ -----
2928
+ {
2929
+ "class" : "DeleteRequestBody",
2930
+ "externalSourceGUID": "add guid here",
2931
+ "externalSourceName": "add qualified name here",
2932
+ "effectiveTime" : "{{$isoTimestamp}}",
2933
+ "forLineage" : false,
2934
+ "forDuplicateProcessing" : false
2935
+ }
2936
+
2937
+ """
2938
+
2939
+ url = (f"{self.external_reference_command_root}/{external_reference_guid}/members/"
2940
+ f"{element_guid}/detach")
2941
+ await self._async_delete_request(url, body)
2942
+ logger.info(f"Removed member {element_guid} from external_reference {external_reference_guid}")
2943
+
2944
+
2945
+ def remove_from_external_reference(self, external_reference_guid: str, element_guid: str,
2946
+ body: dict | DeleteRequestBody = None) -> None:
2947
+ """Remove an element from a external_reference. Async version.
2948
+
2949
+ Parameters
2950
+ ----------
2951
+ external_reference_guid: str
2952
+ identity of the external_reference to return members for.
2953
+ element_guid: str
2954
+ Effective time of the query. If not specified will default to any time.
2955
+ body: dict, optional, defaults to None
2956
+ The body of the request to add to the external_reference. See notes.
2957
+
2958
+ Returns
2959
+ -------
2960
+ None
2961
+
2962
+ Raises
2963
+ ------
2964
+
2965
+ InvalidParameterException
2966
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
2967
+ PropertyServerException
2968
+ Raised by the server when an issue arises in processing a valid request
2969
+ NotAuthorizedException
2970
+ The principle specified by the user_id does not have authorization for the requested action
2971
+
2972
+ Notes
2973
+ -----
2974
+ {
2975
+ "class" : "MetadataSourceRequestBody",
2976
+ "externalSourceGUID": "add guid here",
2977
+ "externalSourceName": "add qualified name here",
2978
+ "effectiveTime" : "{{$isoTimestamp}}",
2979
+ "forLineage" : false,
2980
+ "forDuplicateProcessing" : false
2981
+ }
2982
+
2983
+ """
2984
+ loop = asyncio.get_event_loop()
2985
+ loop.run_until_complete(self._async_remove_from_external_reference(external_reference_guid, element_guid, body))
2986
+
2987
+ #
2988
+ #
2989
+ #
2990
+
2991
+
2992
+ def remove_term_from_category(self, folder_guid: str, term_guid: str,
2993
+ body: dict | DeleteRequestBody = None) -> None:
2994
+ """Remove a term from a category.
2995
+
2996
+ Parameters
2997
+ ----------
2998
+ category_guid: str
2999
+ identity of the external_reference to return members for.
3000
+ term_guid: str
3001
+ Effective time of the query. If not specified will default to any time.
3002
+ body: dict, optional, defaults to None
3003
+ The body of the request to add to the external_reference. See notes.
3004
+
3005
+ Returns
3006
+ -------
3007
+ None
3008
+
3009
+ Raises
3010
+ ------
3011
+
3012
+ InvalidParameterException
3013
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
3014
+ PropertyServerException
3015
+ Raised by the server when an issue arises in processing a valid request
3016
+ NotAuthorizedException
3017
+ The principle specified by the user_id does not have authorization for the requested action
3018
+
3019
+ Notes
3020
+ -----
3021
+
3022
+ """
3023
+ loop = asyncio.get_event_loop()
3024
+ loop.run_until_complete(self._async_remove_from_external_reference(folder_guid, term_guid, body))
3025
+
3026
+ #
3027
+ #
3028
+ #
3029
+
3030
+
3031
+ @dynamic_catch
3032
+ async def _async_get_member_list(self, external_reference_guid: str = None, external_reference_name: str = None,
3033
+ external_reference_qname: str = None, ) -> list | str:
3034
+ """Get the member list for the external_reference - async version.
3035
+ Parameters
3036
+ ----------
3037
+ external_reference_guid: str,
3038
+ identity of the external_reference to return members for. If none, external_reference_name or
3039
+ external_reference_qname are used.
3040
+ external_reference_name: str,
3041
+ display name of the external_reference to return members for. If none, external_reference_guid
3042
+ or external_reference_qname are used.
3043
+ external_reference_qname: str,
3044
+ qualified name of the external_reference to return members for. If none, external_reference_guid
3045
+ or external_reference_name are used.
3046
+
3047
+ Returns
3048
+ -------
3049
+ list | str
3050
+ The list of member information if successful, otherwise the string "No members found"
3051
+
3052
+ Raises
3053
+ ------
3054
+ InvalidParameterException
3055
+ If the root_external_reference_name does not have exactly one root external_reference.
3056
+
3057
+ """
3058
+
3059
+ # first find the guid for the external_reference we are using as root
3060
+
3061
+ # now find the members of the external_reference
3062
+ member_list = []
3063
+ members = await self._async_get_external_reference_members(external_reference_guid, external_reference_name,
3064
+ external_reference_qname)
3065
+ if (type(members) is str) or (len(members) == 0):
3066
+ logger.trace(f"No members found for external_reference {external_reference_guid}")
3067
+ return "No members found"
3068
+ # finally, construct a list of member information
3069
+ for member_rel in members:
3070
+ member_guid = member_rel["elementHeader"]["guid"]
3071
+ member = await self._async_get_element_by_guid_(member_guid)
3072
+ if isinstance(member, dict):
3073
+ member_instance = {
3074
+ "name": member["properties"].get('displayName', ''),
3075
+ "qualifiedName": member["properties"]["qualifiedName"], "guid": member["elementHeader"]["guid"],
3076
+ "description": member["properties"].get("description", ''),
3077
+ "type": member["elementHeader"]["type"]['typeName'],
3078
+ }
3079
+ member_list.append(member_instance)
3080
+ logger.debug(f"Member list for external_reference {external_reference_guid}: {member_list}")
3081
+ return member_list if len(member_list) > 0 else "No members found"
3082
+
3083
+
3084
+ def get_member_list(self, external_reference_guid: str = None, external_reference_name: str = None,
3085
+ external_reference_qname: str = None, ) -> list | bool:
3086
+ """Get the member list for a external_reference - async version.
3087
+ Parameters
3088
+ ----------
3089
+ external_reference_guid: str,
3090
+ identity of the external_reference to return members for. If none, external_reference_name or
3091
+ external_reference_qname are used.
3092
+ external_reference_name: str,
3093
+ display name of the external_reference to return members for. If none, external_reference_guid
3094
+ or external_reference_qname are used.
3095
+ external_reference_qname: str,
3096
+ qualified name of the external_reference to return members for. If none, external_reference_guid
3097
+ or external_reference_name are used.
3098
+ Returns
3099
+ -------
3100
+ list | bool
3101
+ The list of member information if successful, otherwise False.
3102
+
3103
+ Raises
3104
+ ------
3105
+ InvalidParameterException
3106
+ If the root_external_reference_name does not have exactly one root external_reference.
3107
+
3108
+ """
3109
+ loop = asyncio.get_event_loop()
3110
+ resp = loop.run_until_complete(
3111
+ self._async_get_member_list(external_reference_guid, external_reference_name, external_reference_qname))
3112
+ return resp
3113
+
3114
+
3115
+
3116
+
3117
+
3118
+ def _extract_agreement_properties(self, element: dict, guid: str, output_format: str) -> dict:
3119
+ props = element["properties"]
3120
+ # agreement = Collections.model_validate(props)
3121
+ # added_props = get_defined_field_values(agreement)
3122
+
3123
+ added_props = {}
3124
+ agreement_items = element.get("agreementItems", "")
3125
+ if isinstance(agreement_items, (list | dict)):
3126
+ agreement_items_list = ""
3127
+ for item in agreement_items:
3128
+ agreement_items_list += f"{item["relatedElement"]["properties"]["qualifiedName"]}, "
3129
+ added_props["agreementItems"] = agreement_items_list[:-2]
3130
+
3131
+ return added_props
3132
+
3133
+
3134
+ def _extract_external_reference_properties(self, element: dict, columns_struct: dict) -> dict:
3135
+ """
3136
+ Extract common properties from a external_reference element and populate into the provided columns_struct.
3137
+
3138
+ Args:
3139
+ element (dict): The external_reference element
3140
+ columns_struct (dict): The columns structure to populate
3141
+
3142
+ Returns:
3143
+ dict: columns_struct with column 'value' fields populated
3144
+ """
3145
+ # First, populate from element.properties using the utility
3146
+ col_data = populate_columns_from_properties(element, columns_struct)
3147
+
3148
+ columns_list = col_data.get("formats", {}).get("columns", [])
3149
+
3150
+ # Populate header-derived values
3151
+ header_props = _extract_referenceable_properties(element)
3152
+ for column in columns_list:
3153
+ key = column.get('key')
3154
+ if key in header_props:
3155
+ column['value'] = header_props.get(key)
3156
+ elif isinstance(key, str) and key.lower() == 'guid':
3157
+ column['value'] = header_props.get('GUID')
3158
+
3159
+ # Derived/computed fields
3160
+ # external_referenceCategories are classifications
3161
+ classification_names = ""
3162
+ classifications = element.get('elementHeader', {}).get("external_referenceCategories", [])
3163
+ for classification in classifications:
3164
+ classification_names += f"{classification['classificationName']}, "
3165
+ if classification_names:
3166
+ for column in columns_list:
3167
+ if column.get('key') == 'classifications':
3168
+ column['value'] = classification_names[:-2]
3169
+ break
3170
+
3171
+ # Populate requested relationship-based columns generically from top-level keys
3172
+ col_data = get_required_relationships(element, col_data)
3173
+
3174
+ # Subject area classification
3175
+ subject_area = element.get('elementHeader', {}).get("subjectArea", "") or ""
3176
+ subj_val = ""
3177
+ if isinstance(subject_area, dict):
3178
+ subj_val = subject_area.get("classificationProperties", {}).get("subjectAreaName", "")
3179
+ for column in columns_list:
3180
+ if column.get('key') == 'subject_area':
3181
+ column['value'] = subj_val
3182
+ break
3183
+
3184
+ # Mermaid graph
3185
+ mermaid_val = element.get('mermaidGraph', "") or ""
3186
+ for column in columns_list:
3187
+ if column.get('key') == 'mermaid':
3188
+ column['value'] = mermaid_val
3189
+ break
3190
+
3191
+ logger.trace(f"Extracted/Populated columns: {col_data}")
3192
+
3193
+ return col_data
3194
+
3195
+
3196
+ def _generate_external_reference_output(self, elements: dict | list[dict], filter: Optional[str],
3197
+ element_type_name: Optional[str], output_format: str = "DICT",
3198
+ output_format_set: dict | str = None) -> str | list[dict]:
3199
+ """ Generate output for external_references in the specified format.
3200
+
3201
+ Args:
3202
+ elements (Union[Dict, List[Dict]]): Dictionary or list of dictionaries containing data field elements
3203
+ filter (Optional[str]): The search string used to find the elements
3204
+ element_type_name (Optional[str]): The type of external_reference
3205
+ output_format (str): The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
3206
+ output_format_set (Optional[dict], optional): List of dictionaries containing column data. Defaults
3207
+ to None.
3208
+
3209
+ Returns:
3210
+ Union[str, List[Dict]]: Formatted output as a string or list of dictionaries
3211
+ """
3212
+ if element_type_name is None:
3213
+ entity_type = "Collections"
3214
+ else:
3215
+ entity_type = element_type_name
3216
+ # First see if the user has specified an output_format_set - either a label or a dict
3217
+ get_additional_props_func = None
3218
+ if output_format_set:
3219
+ if isinstance(output_format_set, str):
3220
+ output_formats = select_output_format_set(output_format_set, output_format)
3221
+ elif isinstance(output_format_set, dict):
3222
+ output_formats = get_output_format_type_match(output_format_set, output_format)
3223
+
3224
+ # If no output_format was set, then use the element_type_name to lookup the output format
3225
+ elif element_type_name:
3226
+ output_formats = select_output_format_set(element_type_name, output_format)
3227
+ else:
3228
+ # fallback to external_references or entity type
3229
+ output_formats = select_output_format_set(entity_type, output_format)
3230
+ if output_formats is None:
3231
+ output_formats = select_output_format_set("Default", output_format)
3232
+
3233
+ if output_formats:
3234
+ get_additional_props_name = output_formats.get("get_additional_props", {}).get("function", None)
3235
+ if isinstance(get_additional_props_name, str):
3236
+ class_name, method_name = get_additional_props_name.split(".")
3237
+ if hasattr(self, method_name):
3238
+ get_additional_props_func = getattr(self, method_name)
3239
+
3240
+ logger.trace(f"Executing generate_external_reference_output for {entity_type}: {output_formats}")
3241
+ return generate_output(
3242
+ elements,
3243
+ filter,
3244
+ entity_type,
3245
+ output_format,
3246
+ self._extract_external_reference_properties,
3247
+ get_additional_props_func,
3248
+ output_formats,
3249
+ )
3250
+
3251
+
3252
+ from typing import Union, Dict, List, Optional
3253
+
3254
+ if __name__ == "__main__":
3255
+ print("Main-Collection Manager")