pyegeria 5.4.0.20__py3-none-any.whl → 5.4.0.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- commands/cat/.DS_Store +0 -0
- commands/cat/.env +8 -0
- commands/cat/debug_log.log +0 -0
- commands/cat/list_collections.py +15 -6
- commands/cat/list_format_set.py +90 -85
- commands/cat/logs/pyegeria.log +136 -0
- commands/cli/debug_log.log +0 -0
- commands/ops/logs/pyegeria.log +0 -0
- md_processing/.DS_Store +0 -0
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-30-37.md +163 -0
- md_processing/dr-egeria-outbox/Collections-2025-08-12-13-35-58.md +474 -0
- md_processing/dr_egeria_inbox/Derive-Dr-Gov-Defs.md +8 -0
- md_processing/dr_egeria_inbox/Dr.Egeria Templates.md +873 -0
- md_processing/dr_egeria_inbox/arch_test.md +57 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +254 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +696 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +254 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +298 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +608 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +94 -0
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +284 -0
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +275 -0
- md_processing/dr_egeria_inbox/archive/test-term.md +110 -0
- md_processing/dr_egeria_inbox/cat_test.md +100 -0
- md_processing/dr_egeria_inbox/collections.md +39 -0
- md_processing/dr_egeria_inbox/data_designer_debug.log +6 -0
- md_processing/dr_egeria_inbox/data_designer_out.md +60 -0
- md_processing/dr_egeria_inbox/data_designer_search_test.md +11 -0
- md_processing/dr_egeria_inbox/data_field.md +54 -0
- md_processing/dr_egeria_inbox/data_spec.md +77 -0
- md_processing/dr_egeria_inbox/data_spec_test.md +2406 -0
- md_processing/dr_egeria_inbox/data_test.md +179 -0
- md_processing/dr_egeria_inbox/data_test2.md +429 -0
- md_processing/dr_egeria_inbox/data_test3.md +462 -0
- md_processing/dr_egeria_inbox/dr_egeria_data_designer_1.md +124 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +168 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +280 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +313 -0
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +1073 -0
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +44 -0
- md_processing/dr_egeria_inbox/generated_help_report.md +9 -0
- md_processing/dr_egeria_inbox/glossary_list.md +5 -0
- md_processing/dr_egeria_inbox/glossary_search_test.md +40 -0
- md_processing/dr_egeria_inbox/glossary_test1.md +324 -0
- md_processing/dr_egeria_inbox/gov_def.md +424 -0
- md_processing/dr_egeria_inbox/gov_def2.md +447 -0
- md_processing/dr_egeria_inbox/product.md +50 -0
- md_processing/dr_egeria_inbox/rel.md +8 -0
- md_processing/dr_egeria_inbox/sb.md +119 -0
- md_processing/dr_egeria_inbox/solution-components.md +136 -0
- md_processing/dr_egeria_inbox/solution_blueprints.md +118 -0
- md_processing/dr_egeria_inbox/synonym_test.md +42 -0
- md_processing/dr_egeria_inbox/t2.md +268 -0
- md_processing/dr_egeria_outbox/.obsidian/app.json +1 -0
- md_processing/dr_egeria_outbox/.obsidian/appearance.json +1 -0
- md_processing/dr_egeria_outbox/.obsidian/community-plugins.json +6 -0
- md_processing/dr_egeria_outbox/.obsidian/core-plugins.json +31 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/data.json +10 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/main.js +4459 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/manifest.json +10 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/data.json +3 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/main.js +153 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/manifest.json +11 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/styles.css +1 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/main.js +500 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +12 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/styles.css +1 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/main.js +37 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/manifest.json +11 -0
- md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/styles.css +220 -0
- md_processing/dr_egeria_outbox/.obsidian/types.json +28 -0
- md_processing/dr_egeria_outbox/.obsidian/workspace.json +220 -0
- md_processing/dr_egeria_outbox/Untitled.canvas +1 -0
- md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:00-product.md +62 -0
- md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:13-product.md +62 -0
- md_processing/dr_egeria_outbox/friday/processed-2025-07-20 13:23-product.md +47 -0
- md_processing/dr_egeria_outbox/friday/processed-2025-08-01 11:55-data_test3.md +503 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +2744 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +62 -0
- md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +444 -0
- md_processing/dr_egeria_outbox/processed-2025-08-03 16:05-glossary_list.md +37 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 14:55-product.md +77 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:05-product.md +75 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 15:11-product.md +74 -0
- md_processing/dr_egeria_outbox/sunday/processed-2025-07-20 20:40-collections.md +49 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:08-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:10-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:53-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:54-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:03-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:06-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:10-gov_def2.md +486 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox/tuesday/processed-2025-07-17 14:27-gov_def2.md +485 -0
- md_processing/md_processing_utils/debug_log.log +0 -0
- md_processing/md_processing_utils/solution_architect_log.log +0 -0
- pyegeria/.DS_Store +0 -0
- pyegeria/__init__.py +2 -2
- pyegeria/_client_new.py +392 -98
- pyegeria/_exceptions_new.py +16 -13
- pyegeria/_output_format_models.py +22 -17
- pyegeria/_output_formats.py +107 -34
- pyegeria/collection_manager.py +703 -1429
- pyegeria/collection_manager_omvs.py +48 -19
- pyegeria/egeria_cat_client.py +1 -1
- pyegeria/egeria_client.py +6 -0
- pyegeria/egeria_tech_client.py +6 -1
- pyegeria/governance_officer.py +2515 -0
- pyegeria/models.py +23 -6
- pyegeria/output_formatter.py +298 -79
- {pyegeria-5.4.0.20.dist-info → pyegeria-5.4.0.23.dist-info}/METADATA +1 -1
- {pyegeria-5.4.0.20.dist-info → pyegeria-5.4.0.23.dist-info}/RECORD +121 -19
- {pyegeria-5.4.0.20.dist-info → pyegeria-5.4.0.23.dist-info}/LICENSE +0 -0
- {pyegeria-5.4.0.20.dist-info → pyegeria-5.4.0.23.dist-info}/WHEEL +0 -0
- {pyegeria-5.4.0.20.dist-info → pyegeria-5.4.0.23.dist-info}/entry_points.txt +0 -0
pyegeria/collection_manager.py
CHANGED
@@ -9,34 +9,35 @@ Copyright Contributors to the ODPi Egeria project.
|
|
9
9
|
import asyncio
|
10
10
|
import inspect
|
11
11
|
from datetime import datetime
|
12
|
-
from typing import
|
12
|
+
from typing import Optional, Annotated, Literal, Union
|
13
13
|
|
14
|
-
import pydantic_core
|
15
|
-
# from jsonschema import ValidationError
|
16
14
|
from loguru import logger
|
17
|
-
from pydantic import
|
15
|
+
from pydantic import ValidationError, Field, HttpUrl
|
18
16
|
|
19
|
-
from pyegeria._exceptions_new import PyegeriaInvalidParameterException
|
20
|
-
from pyegeria._output_formats import select_output_format_set, get_output_format_type_match
|
21
|
-
from pyegeria._client import Client
|
17
|
+
from pyegeria._exceptions_new import PyegeriaInvalidParameterException
|
22
18
|
from pyegeria._globals import NO_ELEMENTS_FOUND, NO_GUID_RETURNED, NO_MEMBERS_FOUND
|
23
|
-
from pyegeria.
|
24
|
-
from pyegeria.
|
25
|
-
_extract_referenceable_properties)
|
26
|
-
from pyegeria.utils import body_slimmer, dynamic_catch
|
19
|
+
from pyegeria._output_formats import select_output_format_set, get_output_format_type_match
|
20
|
+
from pyegeria.load_config import get_app_config
|
27
21
|
from pyegeria.models import (SearchStringRequestBody, FilterRequestBody, GetRequestBody, NewElementRequestBody,
|
28
22
|
ReferenceableProperties, InitialClassifications, TemplateRequestBody,
|
29
23
|
UpdateElementRequestBody, UpdateStatusRequestBody, NewRelationshipRequestBody,
|
30
|
-
DeleteRequestBody
|
31
|
-
|
24
|
+
DeleteRequestBody, UpdateRelationshipRequestBody, ResultsRequestBody,
|
25
|
+
get_defined_field_values, PyegeriaModel)
|
26
|
+
from pyegeria.output_formatter import (generate_output,
|
27
|
+
_extract_referenceable_properties, populate_columns_from_properties,
|
28
|
+
get_required_relationships)
|
29
|
+
from pyegeria.utils import body_slimmer, dynamic_catch
|
30
|
+
|
32
31
|
|
33
32
|
app_settings = get_app_config()
|
34
33
|
EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
|
35
34
|
|
36
|
-
COLLECTION_PROPERTIES_LIST = ["
|
35
|
+
COLLECTION_PROPERTIES_LIST = ["CollectionProperties", "DataDictionaryProperties",
|
37
36
|
"DataSpecProperties", "DigitalProductProperties",
|
38
37
|
"AgreementProperties"]
|
39
38
|
|
39
|
+
AGREEMENT_PROPERTIES_LIST = ["AgreementProperties", "DigitalSubscriptionProperties",]
|
40
|
+
|
40
41
|
|
41
42
|
def query_seperator(current_string):
|
42
43
|
if current_string == "":
|
@@ -62,28 +63,39 @@ class CollectionProperties(ReferenceableProperties):
|
|
62
63
|
class_: Annotated[Literal["CollectionProperties"], Field(alias="class")]
|
63
64
|
|
64
65
|
|
65
|
-
class DataSpecProperties(
|
66
|
+
class DataSpecProperties(CollectionProperties):
|
66
67
|
class_: Annotated[Literal["DataSpecProperties"], Field(alias="class")]
|
67
68
|
|
68
69
|
|
69
|
-
class DataDictionaryProperties(
|
70
|
+
class DataDictionaryProperties(CollectionProperties):
|
70
71
|
class_: Annotated[Literal["DataDictionaryProperties"], Field(alias="class")]
|
71
72
|
|
72
73
|
|
73
|
-
class AgreementProperties(
|
74
|
+
class AgreementProperties(CollectionProperties):
|
74
75
|
class_: Annotated[Literal["AgreementProperties"], Field(alias="class")]
|
75
76
|
identifier: str | None = None
|
76
77
|
user_defined_status: str | None = None
|
77
78
|
|
79
|
+
class DigitalSubscriptionProperties(AgreementProperties):
|
80
|
+
class_: Annotated[Literal["DigitalSubscriptionProperties"], Field(alias="class")]
|
81
|
+
support_level: str | None = None
|
82
|
+
service_levels: dict | None = None
|
78
83
|
|
79
|
-
|
84
|
+
|
85
|
+
class DigitalProductProperties(CollectionProperties):
|
86
|
+
class_: Annotated[Literal["DigitalProductProperties"], Field(alias="class")]
|
87
|
+
user_defined_status: str | None = None
|
80
88
|
product_name: str | None = None
|
89
|
+
identifier: str | None = None
|
90
|
+
introduction_date: datetime | None = None
|
81
91
|
maturity: str | None = None
|
82
92
|
service_life: str | None = None
|
83
|
-
introduction_date: datetime | None = None
|
84
93
|
next_version_date: datetime | None = None
|
85
94
|
withdrawal_date: datetime | None = None
|
86
|
-
|
95
|
+
|
96
|
+
class Collections(PyegeriaModel):
|
97
|
+
collection: Union[CollectionProperties, DigitalSubscriptionProperties, DigitalProductProperties, AgreementProperties,
|
98
|
+
DataSpecProperties, DataDictionaryProperties] = Field(desciminator="class_")
|
87
99
|
|
88
100
|
|
89
101
|
class CollectionManager(Client2):
|
@@ -128,7 +140,8 @@ class CollectionManager(Client2):
|
|
128
140
|
|
129
141
|
@dynamic_catch
|
130
142
|
async def _async_get_attached_collections(self, parent_guid: str, start_from: int = 0, page_size: int = 0,
|
131
|
-
|
143
|
+
category: str = None, classification_names: list[str]= None,
|
144
|
+
body: dict | FilterRequestBody = None, output_format: str = "JSON",
|
132
145
|
output_format_set: str | dict = None) -> list | str:
|
133
146
|
"""Returns the list of collections that are linked off of the supplied element using the ResourceList
|
134
147
|
relationship. Async version.
|
@@ -181,12 +194,10 @@ class CollectionManager(Client2):
|
|
181
194
|
}
|
182
195
|
|
183
196
|
"""
|
184
|
-
if body is None:
|
185
|
-
body = {}
|
186
197
|
|
187
198
|
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/"
|
188
|
-
f"metadata-elements/{parent_guid}/collections
|
189
|
-
|
199
|
+
f"metadata-elements/{parent_guid}/collections")
|
200
|
+
return await self._async_get_name_request(url, body, output_format, output_format_set)
|
190
201
|
response = await self._async_make_request("POST", url, body_slimmer(body))
|
191
202
|
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
192
203
|
if type(elements) is str:
|
@@ -260,164 +271,26 @@ class CollectionManager(Client2):
|
|
260
271
|
|
261
272
|
|
262
273
|
@dynamic_catch
|
263
|
-
async def
|
264
|
-
|
265
|
-
output_format_set: str | dict = None) -> list | str:
|
266
|
-
""" Returns the list of collections matching the search string filtered by the optional classification.
|
267
|
-
The search string is located in the request body and is interpreted as a plain string. The full
|
268
|
-
body allows complete control including status, asOfTime and effectiveTime.
|
269
|
-
The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
|
270
|
-
|
271
|
-
Parameters
|
272
|
-
----------
|
273
|
-
body: dict
|
274
|
-
Details of the search request - see the notes below for details.
|
275
|
-
output_format: str, default = "JSON"
|
276
|
-
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
277
|
-
output_format_set: str | dict , optional, default = None
|
278
|
-
- The desired output columns/field options.
|
279
|
-
Returns
|
280
|
-
-------
|
281
|
-
List | str
|
282
|
-
|
283
|
-
A list of collections match matching the search string. Returns a string if none found.
|
284
|
-
|
285
|
-
Raises
|
286
|
-
------
|
287
|
-
|
288
|
-
InvalidParameterException
|
289
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
290
|
-
PropertyServerException
|
291
|
-
Raised by the server when an issue arises in processing a valid request
|
292
|
-
NotAuthorizedException
|
293
|
-
The principle specified by the user_id does not have authorization for the requested action
|
294
|
-
|
295
|
-
Notes
|
296
|
-
-----
|
297
|
-
|
298
|
-
{
|
299
|
-
"class" : "SearchStringRequestBody",
|
300
|
-
"searchString" : "Data Product Development Journey",
|
301
|
-
"includeOnlyClassifiedElements" : ["RootCollection"],
|
302
|
-
"startsWith" : false,
|
303
|
-
"endsWith" : false,
|
304
|
-
"ignoreCase" : true,
|
305
|
-
"startFrom" : 0,
|
306
|
-
"pageSize": 0,
|
307
|
-
"asOfTime" : "{{$isoTimestamp}}",
|
308
|
-
"effectiveTime" : "{{$isoTimestamp}}",
|
309
|
-
"forLineage" : false,
|
310
|
-
"forDuplicateProcessing" : false,
|
311
|
-
"limitResultsByStatus" : ["ACTIVE"],
|
312
|
-
"sequencingOrder" : "PROPERTY_ASCENDING",
|
313
|
-
"sequencingProperty" : "qualifiedName"
|
314
|
-
}
|
315
|
-
"""
|
316
|
-
if isinstance(body, SearchStringRequestBody):
|
317
|
-
validated_body = body
|
318
|
-
elif isinstance(body, dict):
|
319
|
-
try:
|
320
|
-
validated_body = self._search_string_request_adapter.validate_python(body)
|
321
|
-
except ValidationError as e:
|
322
|
-
context: dict = {
|
323
|
-
'class name': __class__.__name__, 'caller method': inspect.currentframe().f_back.f_code.co_name
|
324
|
-
}
|
325
|
-
raise PyegeriaInvalidParameterException(context = context, Exception = e)
|
326
|
-
else:
|
327
|
-
raise TypeError("Invalid parameter type")
|
328
|
-
|
329
|
-
val_json = validated_body.model_dump_json()
|
330
|
-
|
331
|
-
url = f"{self.collection_command_root}/by-search-string"
|
332
|
-
classification_name = validated_body.include_only_classified_elements
|
333
|
-
|
334
|
-
response = await self._async_make_request("POST", url, val_json)
|
335
|
-
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
336
|
-
if type(elements) is str:
|
337
|
-
logger.info(NO_ELEMENTS_FOUND)
|
338
|
-
return NO_ELEMENTS_FOUND
|
339
|
-
|
340
|
-
if output_format != 'JSON': # return a simplified markdown representation
|
341
|
-
# logger.info(f"Found elements, output format: {output_format} and output_format_set: {output_format_set}")
|
342
|
-
return self._generate_collection_output(elements, None, classification_name,
|
343
|
-
output_format, output_format_set)
|
344
|
-
return elements
|
345
|
-
|
346
|
-
@dynamic_catch
|
347
|
-
def find_collections_w_body(self, body: dict | SearchStringRequestBody, output_format: str = 'JSON',
|
348
|
-
output_format_set: str | dict = None) -> list | str:
|
349
|
-
""" Returns the list of collections matching the search string filtered by the optional classification.
|
350
|
-
The search string is located in the request body and is interpreted as a plain string. The full
|
351
|
-
body allows complete control including status, asOfTime and effectiveTime.
|
352
|
-
The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
|
353
|
-
|
354
|
-
Parameters
|
355
|
-
----------
|
356
|
-
body: dict
|
357
|
-
Details of the search request - see the notes below for details.
|
358
|
-
output_format: str, default = "JSON"
|
359
|
-
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
360
|
-
output_format_set: str | dict , optional, default = None
|
361
|
-
- The desired output columns/field options.
|
362
|
-
Returns
|
363
|
-
-------
|
364
|
-
List | str
|
365
|
-
|
366
|
-
A list of collections match matching the search string. Returns a string if none found.
|
367
|
-
|
368
|
-
Raises
|
369
|
-
------
|
370
|
-
|
371
|
-
InvalidParameterException
|
372
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
373
|
-
PropertyServerException
|
374
|
-
Raised by the server when an issue arises in processing a valid request
|
375
|
-
NotAuthorizedException
|
376
|
-
The principle specified by the user_id does not have authorization for the requested action
|
377
|
-
|
378
|
-
Notes
|
379
|
-
-----
|
380
|
-
|
381
|
-
{
|
382
|
-
"class" : "SearchStringRequestBody",
|
383
|
-
"searchString" : "Data Product Development Journey",
|
384
|
-
"includeOnlyClassifiedElements" : ["RootCollection"],
|
385
|
-
"startsWith" : false,
|
386
|
-
"endsWith" : false,
|
387
|
-
"ignoreCase" : true,
|
388
|
-
"startFrom" : 0,
|
389
|
-
"pageSize": 0,
|
390
|
-
"asOfTime" : "{{$isoTimestamp}}",
|
391
|
-
"effectiveTime" : "{{$isoTimestamp}}",
|
392
|
-
"forLineage" : false,
|
393
|
-
"forDuplicateProcessing" : false,
|
394
|
-
"limitResultsByStatus" : ["ACTIVE"],
|
395
|
-
"sequencingOrder" : "PROPERTY_ASCENDING",
|
396
|
-
"sequencingProperty" : "qualifiedName"
|
397
|
-
}
|
398
|
-
"""
|
399
|
-
return asyncio.get_event_loop().run_until_complete(
|
400
|
-
self._async_find_collections_w_body(body, output_format, output_format_set))
|
401
|
-
|
402
|
-
|
403
|
-
@dynamic_catch
|
404
|
-
async def _async_find_collections(self, search_string: str = '*', classification_name: str = None,
|
274
|
+
async def _async_find_collections(self, search_string: str = "*", classification_names: list[str] = None,
|
275
|
+
metadata_element_types: list[str] = None,
|
405
276
|
starts_with: bool = True, ends_with: bool = False, ignore_case: bool = False,
|
406
277
|
start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
|
407
|
-
output_format_set: str | dict = None
|
278
|
+
output_format_set: str | dict = None,
|
279
|
+
body: dict | SearchStringRequestBody = None) -> list | str:
|
408
280
|
""" Returns the list of collections matching the search string filtered by the optional classification.
|
409
|
-
|
410
|
-
body
|
411
|
-
The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
|
281
|
+
This method can either be used with a body, allowing full control, or with the individual parameters.
|
282
|
+
If the body is provided it will be used and the search_string will be ignored.
|
412
283
|
|
413
284
|
Parameters
|
414
285
|
----------
|
415
286
|
search_string: str
|
416
287
|
Search string to match against - None or '*' indicate match against all collections (may be filtered by
|
417
288
|
classification).
|
418
|
-
|
419
|
-
A classification
|
289
|
+
classification_names: list[str], optional, default=None
|
290
|
+
A list of classification names to filter on - for example, ["DataSpec"], for data specifications. If none,
|
420
291
|
then all classifications are returned.
|
292
|
+
metadata_element_types: list[str], optional, default=None
|
293
|
+
A list of metadata element types to filter on - for example, ["DataSpec"], for data specifications. If none,
|
421
294
|
starts_with : bool, [default=False], optional
|
422
295
|
Starts with the supplied string.
|
423
296
|
ends_with : bool, [default=False], optional
|
@@ -431,58 +304,62 @@ class CollectionManager(Client2):
|
|
431
304
|
the class instance.
|
432
305
|
output_format: str, default = "JSON"
|
433
306
|
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
434
|
-
|
307
|
+
output_format_set: str | dict , optional, default = None
|
435
308
|
- The desired output columns/fields to include.
|
309
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
310
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
311
|
+
|
436
312
|
Returns
|
437
313
|
-------
|
438
314
|
List | str
|
439
315
|
|
440
|
-
|
316
|
+
Output depends on the output format specified.
|
441
317
|
|
442
318
|
Raises
|
443
319
|
------
|
444
320
|
|
445
|
-
|
446
|
-
If the client passes incorrect parameters on the request
|
447
|
-
|
448
|
-
|
321
|
+
ValidationError
|
322
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
323
|
+
PyegeriaException
|
324
|
+
Issues raised in communicating or server side processing.
|
449
325
|
NotAuthorizedException
|
450
326
|
The principle specified by the user_id does not have authorization for the requested action
|
451
327
|
|
452
328
|
"""
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
)
|
465
|
-
|
466
|
-
resp = await self._async_find_collections_w_body(body, output_format, output_format_set)
|
467
|
-
return resp
|
329
|
+
url = str(HttpUrl(f"{self.collection_command_root}/by-search-string"))
|
330
|
+
response = await self._async_find_request(url, _type="Collection",
|
331
|
+
_gen_output=self._generate_collection_output,
|
332
|
+
search_string = search_string, classification_names = classification_names,
|
333
|
+
metadata_element_types = metadata_element_types,
|
334
|
+
starts_with = starts_with, ends_with = ends_with, ignore_case = ignore_case,
|
335
|
+
start_from = start_from, page_size = page_size,
|
336
|
+
output_format=output_format, output_format_set=output_format_set,
|
337
|
+
body=body)
|
338
|
+
|
339
|
+
return response
|
468
340
|
|
469
341
|
@dynamic_catch
|
470
|
-
def find_collections(self, search_string: str = '*',
|
342
|
+
def find_collections(self, search_string: str = '*', classification_names: str = None,
|
343
|
+
metadata_element_types: list[str] = None, starts_with: bool = True,
|
471
344
|
ends_with: bool = False, ignore_case: bool = False,
|
472
345
|
start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
|
473
|
-
output_format_set: str | dict = None
|
346
|
+
output_format_set: str | dict = None,
|
347
|
+
body: dict | SearchStringRequestBody = None) -> list | str:
|
474
348
|
""" Returns the list of collections matching the search string filtered by the optional classification.
|
475
|
-
|
476
|
-
body
|
477
|
-
The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
|
349
|
+
This method can either be used with a body, allowing full control, or with the individual parameters.
|
350
|
+
If the body is provided it will be used and the search_string will be ignored.
|
478
351
|
|
479
352
|
Parameters
|
480
353
|
----------
|
481
354
|
search_string: str
|
482
|
-
|
483
|
-
|
484
|
-
|
355
|
+
Search string to match against - None or '*' indicate match against all collections (may be filtered by
|
356
|
+
classification).
|
357
|
+
classification_names: list[str], optional, default=None
|
358
|
+
A list of classification names to filter on - for example, ["DataSpec"], for data specifications. If none,
|
485
359
|
then all classifications are returned.
|
360
|
+
metadata_element_types: list[str], optional, default=None
|
361
|
+
A list of metadata element types to filter on - for example, ["DataSpec"], for data specifications. If none,
|
362
|
+
then all metadata element types are returned.
|
486
363
|
starts_with : bool, [default=False], optional
|
487
364
|
Starts with the supplied string.
|
488
365
|
ends_with : bool, [default=False], optional
|
@@ -496,32 +373,41 @@ class CollectionManager(Client2):
|
|
496
373
|
the class instance.
|
497
374
|
output_format: str, default = "JSON"
|
498
375
|
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
499
|
-
|
376
|
+
output_format_set: str | dict , optional, default = None
|
500
377
|
- The desired output columns/fields to include.
|
378
|
+
body: dict | SearchStringRequestBody, optional, default = None
|
379
|
+
- if provided, the search parameters in the body will supercede other attributes, such as "search_string"
|
380
|
+
|
501
381
|
Returns
|
502
382
|
-------
|
503
383
|
List | str
|
504
384
|
|
505
|
-
|
385
|
+
Output depends on the output format specified.
|
506
386
|
|
507
387
|
Raises
|
508
388
|
------
|
509
389
|
|
510
|
-
|
511
|
-
If the client passes incorrect parameters on the request
|
512
|
-
|
513
|
-
|
390
|
+
ValidationError
|
391
|
+
If the client passes incorrect parameters on the request that don't conform to the data model.
|
392
|
+
PyegeriaException
|
393
|
+
Issues raised in communicating or server side processing.
|
514
394
|
NotAuthorizedException
|
515
395
|
The principle specified by the user_id does not have authorization for the requested action
|
516
396
|
|
397
|
+
Args:
|
398
|
+
classification_names ():
|
399
|
+
metadata_element_types ():
|
400
|
+
|
517
401
|
"""
|
518
402
|
return asyncio.get_event_loop().run_until_complete(
|
519
|
-
self._async_find_collections(search_string,
|
520
|
-
|
403
|
+
self._async_find_collections(search_string, classification_names, metadata_element_types,
|
404
|
+
starts_with, ends_with, ignore_case,
|
405
|
+
start_from, page_size, output_format,
|
406
|
+
output_format_set, body))
|
521
407
|
|
522
408
|
|
523
409
|
@dynamic_catch
|
524
|
-
async def _async_get_collections_by_name(self,
|
410
|
+
async def _async_get_collections_by_name(self, filter_string: str = None, classification_names: list[str] = None,
|
525
411
|
body: dict | FilterRequestBody = None,
|
526
412
|
start_from: int = 0, page_size: int = 0,
|
527
413
|
output_format: str = 'JSON',
|
@@ -532,7 +418,7 @@ class CollectionManager(Client2):
|
|
532
418
|
----------
|
533
419
|
name: str,
|
534
420
|
name to use to find matching collections.
|
535
|
-
|
421
|
+
classification_names: list[str], optional, default = None
|
536
422
|
type of collection to filter by - e.g., DataDict, Folder, Root
|
537
423
|
body: dict, optional, default = None
|
538
424
|
Provides, a full request body. If specified, the body supercedes the name parameter.
|
@@ -543,7 +429,7 @@ class CollectionManager(Client2):
|
|
543
429
|
the class instance.
|
544
430
|
output_format: str, default = "JSON"
|
545
431
|
- one of "DICT", "MERMAID" or "JSON"
|
546
|
-
|
432
|
+
output_format_set: dict , optional, default = None
|
547
433
|
The desired output columns/fields to include.
|
548
434
|
|
549
435
|
Returns
|
@@ -562,47 +448,20 @@ class CollectionManager(Client2):
|
|
562
448
|
NotAuthorizedException
|
563
449
|
The principle specified by the user_id does not have authorization for the requested action
|
564
450
|
"""
|
451
|
+
url = str(HttpUrl(f"{self.collection_command_root}/by-name"))
|
452
|
+
response = await self._async_get_name_request(url, _type="Collection",
|
453
|
+
_gen_output=self._generate_collection_output,
|
454
|
+
filter_string = filter_string, classification_names = classification_names,
|
455
|
+
start_from = start_from, page_size = page_size,
|
456
|
+
output_format=output_format, output_format_set=output_format_set,
|
457
|
+
body=body)
|
565
458
|
|
566
|
-
|
567
|
-
validated_body = FilterRequestBody(
|
568
|
-
class_ = "FilterRequestBody",
|
569
|
-
filter = name,
|
570
|
-
start_from = start_from,
|
571
|
-
page_size = page_size,
|
572
|
-
include_only_classified_elements= [classification_name] if classification_name else None
|
573
|
-
)
|
574
|
-
elif isinstance(body, FilterRequestBody):
|
575
|
-
validated_body = body
|
576
|
-
elif isinstance(body, dict):
|
577
|
-
try:
|
578
|
-
validated_body = self._filter_request_adapter.validate_python(body)
|
579
|
-
except ValidationError as e:
|
580
|
-
context: dict = {
|
581
|
-
'class name': __class__.__name__, 'caller method': inspect.currentframe().f_back.f_code.co_name
|
582
|
-
}
|
583
|
-
raise PyegeriaInvalidParameterException(context=context, Exception=e)
|
584
|
-
else:
|
585
|
-
raise TypeError("Invalid parameter type")
|
586
|
-
|
587
|
-
url = f"{self.collection_command_root}/by-name"
|
588
|
-
classification_name = validated_body.include_only_classified_elements
|
459
|
+
return response
|
589
460
|
|
590
|
-
response = await self._async_make_request("POST", url, validated_body.model_dump_json())
|
591
|
-
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
592
|
-
if type(elements) is str:
|
593
|
-
logger.info(NO_ELEMENTS_FOUND)
|
594
|
-
return NO_ELEMENTS_FOUND
|
595
461
|
|
596
|
-
|
597
|
-
logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
598
|
-
return self._generate_collection_output(elements, filter, classification_name,
|
599
|
-
output_format, output_format_set)
|
600
|
-
return elements
|
601
|
-
|
602
|
-
|
603
|
-
def get_collections_by_name(self, name: str = None, classification_name: str = None,
|
462
|
+
def get_collections_by_name(self, name: str = None, classification_names: list[str] = None,
|
604
463
|
body: dict | FilterRequestBody = None,
|
605
|
-
start_from: int = 0, page_size: int =
|
464
|
+
start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
|
606
465
|
output_format_set: str | dict = None) -> list | str:
|
607
466
|
"""Returns the list of collections matching the search string. Async version.
|
608
467
|
The search string is located in the request body and is interpreted as a plain string.
|
@@ -612,7 +471,7 @@ class CollectionManager(Client2):
|
|
612
471
|
----------
|
613
472
|
name: str,
|
614
473
|
name to use to find matching collections.
|
615
|
-
|
474
|
+
classification_names: list[str], optional, default = None
|
616
475
|
type of collection to filter by - e.g., DataDict, Folder, Root
|
617
476
|
body: dict, optional, default = None
|
618
477
|
Provides, a full request body. If specified, the body supercedes the name parameter.
|
@@ -638,24 +497,24 @@ class CollectionManager(Client2):
|
|
638
497
|
|
639
498
|
"""
|
640
499
|
return asyncio.get_event_loop().run_until_complete(
|
641
|
-
self._async_get_collections_by_name(name,
|
500
|
+
self._async_get_collections_by_name(name, classification_names, body, start_from, page_size,
|
642
501
|
output_format, output_format_set))
|
643
502
|
|
644
503
|
|
645
504
|
@dynamic_catch
|
646
|
-
async def
|
505
|
+
async def _async_get_collections_by_category(self, category: str, classification_names: list[str] = None,
|
647
506
|
body: dict | FilterRequestBody = None, start_from: int = 0, page_size: int = 0,
|
648
507
|
output_format: str = 'JSON',
|
649
508
|
output_format_set: str | dict = None) -> list | str:
|
650
|
-
"""Returns the list of collections with a particular
|
509
|
+
"""Returns the list of collections with a particular category. This is an optional text field in the
|
651
510
|
collection element.
|
652
511
|
|
653
512
|
Parameters
|
654
513
|
----------
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
An optional filter on the search,
|
514
|
+
category: str
|
515
|
+
category to use to find matching collections.
|
516
|
+
classification_names: str, optional
|
517
|
+
An optional filter on the search, e.g., DataSpec
|
659
518
|
body: dict, optional, default = None
|
660
519
|
Provides, a full request body. If specified, the body filter parameter supercedes the collection_type
|
661
520
|
parameter.
|
@@ -692,49 +551,23 @@ class CollectionManager(Client2):
|
|
692
551
|
"limitResultsByStatus": ["ACTIVE"],
|
693
552
|
"sequencingOrder": "PROPERTY_ASCENDING",
|
694
553
|
"sequencingProperty": "qualifiedName",
|
695
|
-
"filter": "Add
|
554
|
+
"filter": "Add category here"
|
696
555
|
}
|
697
556
|
|
698
557
|
"""
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
)
|
707
|
-
elif isinstance(body, FilterRequestBody):
|
708
|
-
validated_body = body
|
709
|
-
elif isinstance(body, dict):
|
710
|
-
try:
|
711
|
-
validated_body = self._filter_request_adapter.validate_python(body)
|
712
|
-
except ValidationError as e:
|
713
|
-
context: dict = {
|
714
|
-
'class name': __class__.__name__, 'caller method': inspect.currentframe().f_back.f_code.co_name
|
715
|
-
}
|
716
|
-
raise PyegeriaInvalidParameterException(context=context, Exception=e)
|
717
|
-
else:
|
718
|
-
raise TypeError("Invalid parameter type")
|
719
|
-
|
720
|
-
classification_name = validated_body.include_only_classified_elements
|
558
|
+
url = str(HttpUrl(f"{self.collection_command_root}/by-collection-category"))
|
559
|
+
response = await self._async_get_name_request(url, _type="Collection",
|
560
|
+
_gen_output=self._generate_collection_output,
|
561
|
+
filter_string = category, classification_names = classification_names,
|
562
|
+
start_from = start_from, page_size = page_size,
|
563
|
+
output_format=output_format, output_format_set=output_format_set,
|
564
|
+
body=body)
|
721
565
|
|
722
|
-
|
566
|
+
return response
|
723
567
|
|
724
|
-
response = await self._async_make_request("POST", url, validated_body.model_dump_json())
|
725
|
-
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
726
|
-
if type(elements) is str:
|
727
|
-
logger.info(NO_ELEMENTS_FOUND)
|
728
|
-
return NO_ELEMENTS_FOUND
|
729
|
-
|
730
|
-
if output_format != 'JSON': # return a simplified markdown representation
|
731
|
-
logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
732
|
-
return self._generate_collection_output(elements, filter, classification_name,
|
733
|
-
output_format, output_format_set)
|
734
|
-
return elements
|
735
568
|
|
736
569
|
|
737
|
-
def
|
570
|
+
def get_collections_by_category(self, category: str, classification_names: list[str] = None,
|
738
571
|
body: dict | FilterRequestBody = None,
|
739
572
|
start_from: int = 0, page_size: int = 0, output_format: str = 'JSON',
|
740
573
|
output_format_set: str | dict = None) -> list | str:
|
@@ -743,9 +576,9 @@ class CollectionManager(Client2):
|
|
743
576
|
|
744
577
|
Parameters
|
745
578
|
----------
|
746
|
-
|
579
|
+
category: str
|
747
580
|
category to use to find matching collections.
|
748
|
-
|
581
|
+
classification_names: list[str], optional
|
749
582
|
An optional filter on the search, e.g., DataSpec
|
750
583
|
body: dict, optional, default = None
|
751
584
|
Provides, a full request body. If specified, the body filter parameter supersedes the category
|
@@ -757,14 +590,14 @@ class CollectionManager(Client2):
|
|
757
590
|
the class instance.
|
758
591
|
output_format: str, default = "JSON"
|
759
592
|
- one of "DICT", "MERMAID" or "JSON"
|
760
|
-
|
593
|
+
output_format_set: str | dict, optional, default = None
|
761
594
|
The desired output columns/fields to include.
|
762
595
|
|
763
596
|
Returns
|
764
597
|
-------
|
765
598
|
List | str
|
766
599
|
|
767
|
-
A list of collections
|
600
|
+
A list of collections filtered by the specified category. Output based on specified output format.
|
768
601
|
|
769
602
|
Raises
|
770
603
|
------
|
@@ -789,13 +622,13 @@ class CollectionManager(Client2):
|
|
789
622
|
"limitResultsByStatus": ["ACTIVE"],
|
790
623
|
"sequencingOrder": "PROPERTY_ASCENDING",
|
791
624
|
"sequencingProperty": "qualifiedName",
|
792
|
-
"filter": "Add
|
625
|
+
"filter": "Add category here"
|
793
626
|
}
|
794
627
|
|
795
628
|
"""
|
796
629
|
|
797
630
|
return asyncio.get_event_loop().run_until_complete(
|
798
|
-
self.
|
631
|
+
self._async_get_collections_by_category(category, classification_names, body, start_from, page_size,
|
799
632
|
output_format, output_format_set))
|
800
633
|
|
801
634
|
|
@@ -810,13 +643,13 @@ class CollectionManager(Client2):
|
|
810
643
|
----------
|
811
644
|
collection_guid: str,
|
812
645
|
unique identifier of the collection.
|
813
|
-
|
814
|
-
type of collection -
|
815
|
-
body: dict, optional, default = None
|
646
|
+
element_type: str, default = None, optional
|
647
|
+
type of collection - Collection, DataSpec, Agreement, etc.
|
648
|
+
body: dict | GetRequestBody, optional, default = None
|
816
649
|
full request body.
|
817
650
|
output_format: str, default = "JSON"
|
818
651
|
- one of "DICT", "MERMAID" or "JSON"
|
819
|
-
output_format_set: str | dict
|
652
|
+
output_format_set: str | dict, optional, default = None
|
820
653
|
The desired output columns/fields to include.
|
821
654
|
|
822
655
|
Returns
|
@@ -847,43 +680,20 @@ class CollectionManager(Client2):
|
|
847
680
|
}
|
848
681
|
"""
|
849
682
|
|
850
|
-
|
851
|
-
|
852
|
-
class_ = "GetRequestBody",
|
853
|
-
metadata_element_type_name=element_type
|
854
|
-
)
|
855
|
-
elif isinstance(body, FilterRequestBody):
|
856
|
-
validated_body = body
|
857
|
-
elif isinstance(body, dict):
|
858
|
-
try:
|
859
|
-
validated_body = self._get_request_adapter.validate_python(body)
|
860
|
-
except ValidationError as e:
|
861
|
-
context: dict = {
|
862
|
-
'class name': __class__.__name__, 'caller method': inspect.currentframe().f_back.f_code.co_name
|
863
|
-
}
|
864
|
-
raise PyegeriaInvalidParameterException(context=context, Exception=e)
|
865
|
-
else:
|
866
|
-
raise TypeError("Invalid parameter type")
|
867
|
-
|
868
|
-
url = f"{self.collection_command_root}/{collection_guid}"
|
683
|
+
url = str(HttpUrl(f"{self.collection_command_root}/{collection_guid}"))
|
684
|
+
type = element_type if element_type else "Collection"
|
869
685
|
|
686
|
+
response = await self._async_get_guid_request(url, _type=type,
|
687
|
+
_gen_output=self._generate_collection_output,
|
688
|
+
output_format=output_format, output_format_set=output_format_set,
|
689
|
+
body=body)
|
870
690
|
|
871
|
-
response
|
872
|
-
validated_body.model_dump_json())
|
691
|
+
return response
|
873
692
|
|
874
|
-
elements = response.json().get("element", NO_ELEMENTS_FOUND)
|
875
|
-
if type(elements) is str:
|
876
|
-
logger.info(NO_ELEMENTS_FOUND)
|
877
|
-
return NO_ELEMENTS_FOUND
|
878
693
|
|
879
|
-
if output_format != 'JSON': # return a simplified markdown representation
|
880
|
-
logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
881
|
-
return self._generate_collection_output(elements, None, element_type,
|
882
|
-
output_format, output_format_set)
|
883
|
-
return elements
|
884
694
|
|
885
695
|
|
886
|
-
def get_collection_by_guid(self, collection_guid: str, element_type: str = None, body: dict = None,
|
696
|
+
def get_collection_by_guid(self, collection_guid: str, element_type: str = None, body: dict | GetRequestBody= None,
|
887
697
|
output_format: str = 'JSON', output_format_set: str | dict = None) -> dict | str:
|
888
698
|
""" Return the properties of a specific collection. Async version.
|
889
699
|
|
@@ -891,13 +701,13 @@ class CollectionManager(Client2):
|
|
891
701
|
----------
|
892
702
|
collection_guid: str,
|
893
703
|
unique identifier of the collection.
|
894
|
-
|
895
|
-
type of
|
896
|
-
body: dict, optional, default = None
|
704
|
+
element_type: str, default = None, optional
|
705
|
+
type of element - Collection, DataSpec, Agreement, etc.
|
706
|
+
body: dict | GetRequestBody, optional, default = None
|
897
707
|
full request body.
|
898
708
|
output_format: str, default = "JSON"
|
899
709
|
- one of "DICT", "MERMAID" or "JSON"
|
900
|
-
|
710
|
+
output_format_set: dict , optional, default = None
|
901
711
|
The desired output columns/fields to include.
|
902
712
|
|
903
713
|
|
@@ -935,7 +745,7 @@ class CollectionManager(Client2):
|
|
935
745
|
|
936
746
|
@dynamic_catch
|
937
747
|
async def _async_get_collection_members(self, collection_guid: str = None, collection_name: str = None,
|
938
|
-
collection_qname: str = None, body: dict = None, start_from: int = 0,
|
748
|
+
collection_qname: str = None, body: dict | ResultsRequestBody = None, start_from: int = 0,
|
939
749
|
page_size: int = 0, output_format: str = "JSON",
|
940
750
|
output_format_set: str | dict = None) -> list | str:
|
941
751
|
"""Return a list of elements that are a member of a collection. Async version.
|
@@ -994,27 +804,18 @@ class CollectionManager(Client2):
|
|
994
804
|
"""
|
995
805
|
|
996
806
|
if collection_guid is None:
|
997
|
-
collection_guid = self.__get_guid__(collection_guid, collection_name, "
|
807
|
+
collection_guid = self.__get_guid__(collection_guid, collection_name, "displayName",
|
998
808
|
collection_qname, None, )
|
999
809
|
|
1000
|
-
url = (f"{self.collection_command_root}/{collection_guid}/"
|
1001
|
-
f"members?startFrom={start_from}&pageSize={page_size}")
|
810
|
+
url = str(HttpUrl(f"{self.collection_command_root}/{collection_guid}/members"))
|
1002
811
|
|
1003
|
-
if body:
|
1004
|
-
response = await self._async_make_request("POST", url, body_slimmer(body))
|
1005
|
-
else:
|
1006
|
-
response = await self._async_make_request("POST", url)
|
1007
812
|
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
813
|
+
response = await self._async_get_results_body_request(url, _type="Collection",
|
814
|
+
_gen_output=self._generate_collection_output,
|
815
|
+
output_format=output_format, output_format_set=output_format_set,
|
816
|
+
body=body)
|
1012
817
|
|
1013
|
-
|
1014
|
-
logger.debug(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
1015
|
-
return self._generate_collection_output(elements, None, None,
|
1016
|
-
output_format, output_format_set)
|
1017
|
-
return elements
|
818
|
+
return response
|
1018
819
|
|
1019
820
|
|
1020
821
|
def get_collection_members(self, collection_guid: str = None, collection_name: str = None,
|
@@ -1083,19 +884,17 @@ class CollectionManager(Client2):
|
|
1083
884
|
|
1084
885
|
|
1085
886
|
@dynamic_catch
|
1086
|
-
async def
|
887
|
+
async def _async_get_collection_hierarchy(self, collection_guid: str, body: dict | ResultsRequestBody = None, start_from: int = 0,
|
1087
888
|
page_size: int = 0, output_format: str = "JSON",
|
1088
889
|
output_format_set: str | dict = None) -> list | str:
|
1089
|
-
""" Return a
|
1090
|
-
with elements immediately connected to the starting collection. The result
|
1091
|
-
includes a mermaid graph of the returned elements. Async version.
|
890
|
+
""" Return a hierarchy of nested collections. Request body is optional Async version.
|
1092
891
|
|
1093
892
|
Parameters
|
1094
893
|
----------
|
1095
894
|
collection_guid: str,
|
1096
895
|
identity of the collection to return members for. If none, collection_name or
|
1097
896
|
collection_qname are used.
|
1098
|
-
body: dict, optional, default = None
|
897
|
+
body: dict | ResultsRequestBody, optional, default = None
|
1099
898
|
Providing the body allows full control of the request and replaces filter parameters.
|
1100
899
|
start_from: int, [default=0], optional
|
1101
900
|
When multiple pages of results are available, the page number to start from.
|
@@ -1104,14 +903,14 @@ class CollectionManager(Client2):
|
|
1104
903
|
the class instance.
|
1105
904
|
output_format: str, default = "JSON"
|
1106
905
|
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
1107
|
-
|
906
|
+
output_format_set: dict , optional, default = None
|
1108
907
|
The desired output columns/fields to include.
|
1109
908
|
|
1110
909
|
Returns
|
1111
910
|
-------
|
1112
911
|
List | str
|
1113
912
|
|
1114
|
-
|
913
|
+
Results based on the output format.
|
1115
914
|
|
1116
915
|
Raises
|
1117
916
|
------
|
@@ -1126,37 +925,29 @@ class CollectionManager(Client2):
|
|
1126
925
|
Notes:
|
1127
926
|
-----
|
1128
927
|
Body sample:
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
928
|
+
{
|
929
|
+
"class": "ResultsRequestBody",
|
930
|
+
"startFrom": 0,
|
931
|
+
"pageSize": 0,
|
932
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
933
|
+
"limitResultsByStatus": ["ACTIVE"],
|
934
|
+
"asOfTime": "{{$isoTimestamp}}",
|
935
|
+
"sequencingOrder": "CREATION_DATE_RECENT",
|
936
|
+
"sequencingProperty": ""
|
937
|
+
}
|
1137
938
|
"""
|
1138
939
|
|
1139
|
-
url = (f"{self.collection_command_root}/{collection_guid}/"
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
elements = response.json().get("graph", NO_ELEMENTS_FOUND)
|
1148
|
-
if type(elements) is str:
|
1149
|
-
logger.info(NO_ELEMENTS_FOUND)
|
1150
|
-
return NO_ELEMENTS_FOUND
|
1151
|
-
|
1152
|
-
if output_format != 'JSON': # return a simplified markdown representation
|
1153
|
-
logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
1154
|
-
return self._generate_collection_output(elements, None, None,
|
1155
|
-
output_format, output_format_set)
|
1156
|
-
return elements
|
940
|
+
url = str(HttpUrl(f"{self.collection_command_root}/{collection_guid}/hierarchy"))
|
941
|
+
response = await self._async_get_results_body_request(url, _type="Collection",
|
942
|
+
_gen_output=self._generate_collection_output,
|
943
|
+
start_from=start_from, page_size=page_size,
|
944
|
+
output_format=output_format,
|
945
|
+
output_format_set=output_format_set,
|
946
|
+
body=body)
|
1157
947
|
|
948
|
+
return response
|
1158
949
|
|
1159
|
-
def
|
950
|
+
def get_collection_hierarchy(self, collection_guid: str = None, body: dict| ResultsRequestBody = None, start_from: int = 0,
|
1160
951
|
page_size: int = 0, output_format: str = "JSON",
|
1161
952
|
output_format_set: str | dict = None) -> list | str:
|
1162
953
|
""" Return a graph of elements that are the nested members of a collection along
|
@@ -1209,168 +1000,14 @@ class CollectionManager(Client2):
|
|
1209
1000
|
}
|
1210
1001
|
"""
|
1211
1002
|
return asyncio.get_event_loop().run_until_complete(
|
1212
|
-
self.
|
1003
|
+
self._async_get_collection_hierarchy(collection_guid, body, start_from, page_size,
|
1213
1004
|
output_format, output_format_set))
|
1214
1005
|
|
1215
1006
|
|
1216
|
-
@dynamic_catch
|
1217
|
-
async def _async_get_collection_graph_w_body(self, collection_guid: str, body: dict = None, start_from: int = 0,
|
1218
|
-
page_size: int = None, output_format: str = "JSON",
|
1219
|
-
output_format_set: str | dict = None) -> list | str:
|
1220
|
-
""" Return a graph of elements that are the nested members of a collection along
|
1221
|
-
with elements immediately connected to the starting collection. The result
|
1222
|
-
includes a mermaid graph of the returned elements. Async version.
|
1223
|
-
|
1224
|
-
Parameters
|
1225
|
-
----------
|
1226
|
-
collection_guid: str,
|
1227
|
-
identity of the collection to return members for.
|
1228
|
-
body: dict
|
1229
|
-
A dictionary containing the body of the request. See Note.
|
1230
|
-
start_from: int, [default=0], optional
|
1231
|
-
When multiple pages of results are available, the page number to start from.
|
1232
|
-
page_size: int, [default=None]
|
1233
|
-
The number of items to return in a single page. If not specified, the default will be taken from
|
1234
|
-
the class instance.
|
1235
|
-
output_format: str, default = "JSON"
|
1236
|
-
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
1237
|
-
output_format_set: dict , optional, default = None
|
1238
|
-
|
1239
|
-
Returns
|
1240
|
-
-------
|
1241
|
-
List | str
|
1242
|
-
|
1243
|
-
A list of collection members in the collection.
|
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
|
-
Note
|
1255
|
-
____
|
1256
|
-
{
|
1257
|
-
"class": "ResultsRequestBody",
|
1258
|
-
"effectiveTime": "{{$isoTimestamp}}",
|
1259
|
-
"limitResultsByStatus": ["ACTIVE"],
|
1260
|
-
"asOfTime": "{{$isoTimestamp}}",
|
1261
|
-
"sequencingOrder": "CREATION_DATE_RECENT",
|
1262
|
-
"sequencingProperty": ""
|
1263
|
-
}
|
1264
|
-
|
1265
|
-
"""
|
1266
|
-
|
1267
|
-
if page_size is None:
|
1268
|
-
page_size = self.page_size
|
1269
|
-
|
1270
|
-
url = (f"{self.collection_command_root}/{collection_guid}/"
|
1271
|
-
f"graph?startFrom={start_from}&pageSize={page_size}")
|
1272
|
-
|
1273
|
-
response = await self._async_make_request("GET", url, body_slimmer(body))
|
1274
|
-
elements = response.json().get("elements", NO_ELEMENTS_FOUND)
|
1275
|
-
if type(elements) is str:
|
1276
|
-
logger.info(NO_ELEMENTS_FOUND)
|
1277
|
-
return NO_ELEMENTS_FOUND
|
1278
|
-
|
1279
|
-
if output_format != 'JSON': # return a simplified markdown representation
|
1280
|
-
logger.info(f"Found elements, output format: {output_format}, output_format_set: {output_format_set}")
|
1281
|
-
return self._generate_collection_output(elements, None, None,
|
1282
|
-
output_format, output_format_set)
|
1283
|
-
return elements
|
1284
|
-
|
1285
|
-
|
1286
|
-
def get_collection_graph_w_body(self, collection_guid: str, body: dict = None, start_from: int = 0,
|
1287
|
-
page_size: int = None, output_format: str = "JSON",
|
1288
|
-
output_format_set: str | dict = None) -> list | str:
|
1289
|
-
""" Return a graph of elements that are the nested members of a collection along
|
1290
|
-
with elements immediately connected to the starting collection. The result
|
1291
|
-
includes a mermaid graph of the returned elements.
|
1292
|
-
|
1293
|
-
Parameters
|
1294
|
-
----------
|
1295
|
-
collection_guid: str,
|
1296
|
-
identity of the collection to return members for.
|
1297
|
-
body: dict
|
1298
|
-
A dictionary containing the body of the request. See Note.
|
1299
|
-
start_from: int, [default=0], optional
|
1300
|
-
When multiple pages of results are available, the page number to start from.
|
1301
|
-
page_size: int, [default=None]
|
1302
|
-
The number of items to return in a single page. If not specified, the default will be taken from
|
1303
|
-
the class instance.
|
1304
|
-
output_format: str, default = "JSON"
|
1305
|
-
- one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
|
1306
|
-
output_format_set: str | dict , optional, default = None
|
1307
|
-
The desired output columns/fields to include.
|
1308
|
-
|
1309
|
-
Returns
|
1310
|
-
-------
|
1311
|
-
List | str
|
1312
|
-
|
1313
|
-
A list of collection members in the collection.
|
1314
|
-
|
1315
|
-
Raises
|
1316
|
-
------
|
1317
|
-
InvalidParameterException
|
1318
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
1319
|
-
PropertyServerException
|
1320
|
-
Raised by the server when an issue arises in processing a valid request
|
1321
|
-
NotAuthorizedException
|
1322
|
-
The principle specified by the user_id does not have authorization for the requested action
|
1323
|
-
|
1324
|
-
Note
|
1325
|
-
____
|
1326
|
-
{
|
1327
|
-
"class": "ResultsRequestBody",
|
1328
|
-
"effectiveTime": "{{$isoTimestamp}}",
|
1329
|
-
"limitResultsByStatus": ["ACTIVE"],
|
1330
|
-
"asOfTime": "{{$isoTimestamp}}",
|
1331
|
-
"sequencingOrder": "CREATION_DATE_RECENT",
|
1332
|
-
"sequencingProperty": ""
|
1333
|
-
}
|
1334
|
-
|
1335
|
-
"""
|
1336
|
-
|
1337
|
-
return asyncio.get_event_loop().run_until_complete(
|
1338
|
-
self._async_get_collection_graph_w_body(collection_guid, body, start_from,
|
1339
|
-
page_size, output_format, output_format_set))
|
1340
|
-
|
1341
|
-
#
|
1342
|
-
# Create collection methods
|
1343
|
-
#
|
1344
|
-
|
1345
|
-
###
|
1346
|
-
# =====================================================================================================================
|
1347
|
-
# Create Collections: https://egeria-project.org/concepts/collection
|
1348
|
-
# These requests use the following parameters:
|
1349
|
-
#
|
1350
|
-
# anchorGUID - the unique identifier of the element that should be the anchor for the new element. Set to
|
1351
|
-
# null if
|
1352
|
-
# no anchor,
|
1353
|
-
# or if this collection is to be its own anchor.
|
1354
|
-
#
|
1355
|
-
# isOwnAnchor -this element should be classified as its own anchor or not. The default is false.
|
1356
|
-
#
|
1357
|
-
# parentGUID - the optional unique identifier for an element that should be connected to the newly
|
1358
|
-
# created element.
|
1359
|
-
# If this property is specified, parentRelationshipTypeName must also be specified
|
1360
|
-
#
|
1361
|
-
# parentRelationshipTypeName - the name of the relationship, if any, that should be established between
|
1362
|
-
# the new
|
1363
|
-
# element and the parent element.
|
1364
|
-
# Examples could be "ResourceList" or "DigitalServiceProduct".
|
1365
|
-
#
|
1366
|
-
# parentAtEnd1 -identifies which end any parent entity sits on the relationship.
|
1367
|
-
#
|
1368
|
-
|
1369
|
-
|
1370
1007
|
@dynamic_catch
|
1371
1008
|
async def _async_create_collection(self, display_name: str = None, description: str = None,
|
1372
|
-
|
1373
|
-
|
1009
|
+
category: str = None, initial_classifications: list[str] = None,
|
1010
|
+
body: dict | NewElementRequestBody = None) -> str:
|
1374
1011
|
""" Create a new generic collection. If the body is not present, the display_name, description, category
|
1375
1012
|
and classification will be used to create a simple, self-anchored collection.
|
1376
1013
|
Collections: https://egeria-project.org/concepts/collection
|
@@ -1385,8 +1022,8 @@ class CollectionManager(Client2):
|
|
1385
1022
|
The description of the collection.
|
1386
1023
|
category: str, optional
|
1387
1024
|
An optional user-assigned category for the collection.
|
1388
|
-
|
1389
|
-
An initial
|
1025
|
+
initial_classifications: list[str], optional
|
1026
|
+
An initial list of classifications for the collection. This can be used to distinguish, for instance, Folders
|
1390
1027
|
from Root Collections.
|
1391
1028
|
|
1392
1029
|
body: dict | NewElementRequestBody, optional
|
@@ -1473,30 +1110,19 @@ class CollectionManager(Client2):
|
|
1473
1110
|
}
|
1474
1111
|
|
1475
1112
|
"""
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
elif isinstance(body, dict):
|
1481
|
-
try:
|
1482
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
1483
|
-
except ValidationError as e:
|
1484
|
-
logger.error(f"Validation error: {e}")
|
1485
|
-
raise ValidationError(e)
|
1486
|
-
elif display_name is not None:
|
1487
|
-
pre = classification_name if classification_name is not None else "Collection "
|
1113
|
+
if body:
|
1114
|
+
validated_body = self.validate_new_element_request(body,"CollectionProperties")
|
1115
|
+
elif (body is None) and (display_name is not None):
|
1116
|
+
pre = initial_classifications[0] if initial_classifications is not None else "Collection"
|
1488
1117
|
qualified_name = self.__create_qualified_name__(pre, display_name, EGERIA_LOCAL_QUALIFIER)
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
}
|
1118
|
+
if initial_classifications:
|
1119
|
+
initial_classifications_dict = {}
|
1120
|
+
for c in initial_classifications:
|
1121
|
+
initial_classifications_dict = initial_classifications_dict | {c : {"class": "ClassificationProperties"}}
|
1122
|
+
|
1495
1123
|
else:
|
1496
|
-
|
1497
|
-
|
1498
|
-
classification_name: InitialClassifications.model_validate(initial_classifications_data)
|
1499
|
-
}
|
1124
|
+
initial_classifications_dict = None
|
1125
|
+
|
1500
1126
|
collection_properties = CollectionProperties( class_ = "CollectionProperties",
|
1501
1127
|
qualified_name = qualified_name,
|
1502
1128
|
display_name = display_name,
|
@@ -1506,12 +1132,12 @@ class CollectionManager(Client2):
|
|
1506
1132
|
body = {
|
1507
1133
|
"class" :"NewElementRequestBody",
|
1508
1134
|
"isOwnAnchor": True,
|
1509
|
-
"initialClassifications":
|
1135
|
+
"initialClassifications": initial_classifications_dict,
|
1510
1136
|
"properties": collection_properties.model_dump()
|
1511
1137
|
}
|
1512
1138
|
validated_body = NewElementRequestBody.model_validate(body)
|
1513
1139
|
else:
|
1514
|
-
raise
|
1140
|
+
raise PyegeriaInvalidParameterException(additional_info={"reason": "Invalid input parameters"})
|
1515
1141
|
|
1516
1142
|
url = f"{self.collection_command_root}"
|
1517
1143
|
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
@@ -1522,7 +1148,7 @@ class CollectionManager(Client2):
|
|
1522
1148
|
|
1523
1149
|
|
1524
1150
|
def create_collection(self, display_name: str = None, description: str = None,
|
1525
|
-
category: str = None,
|
1151
|
+
category: str = None, initial_classifications: list[str] = None,
|
1526
1152
|
body: dict | NewElementRequestBody = None) -> str:
|
1527
1153
|
""" Create a new generic collection. If the body is not present, the display_name, description, category
|
1528
1154
|
and classification will be used to create a simple, self-anchored collection.
|
@@ -1537,7 +1163,7 @@ class CollectionManager(Client2):
|
|
1537
1163
|
The description of the collection.
|
1538
1164
|
category: str, optional
|
1539
1165
|
An optional user-assigned category for the collection.
|
1540
|
-
|
1166
|
+
initial_classifications: str, optional
|
1541
1167
|
An initial classification for the collection. This can be used to distinguish, for instance, Folders
|
1542
1168
|
from Root Collections.
|
1543
1169
|
|
@@ -1629,7 +1255,7 @@ class CollectionManager(Client2):
|
|
1629
1255
|
|
1630
1256
|
return asyncio.get_event_loop().run_until_complete(
|
1631
1257
|
self._async_create_collection(display_name, description,category,
|
1632
|
-
|
1258
|
+
initial_classifications, body))
|
1633
1259
|
|
1634
1260
|
|
1635
1261
|
@dynamic_catch
|
@@ -1668,11 +1294,9 @@ class CollectionManager(Client2):
|
|
1668
1294
|
|
1669
1295
|
return asyncio.get_event_loop().run_until_complete(
|
1670
1296
|
self._async_create_collection(display_name, description, category,
|
1671
|
-
"RootCollection", body))
|
1297
|
+
["RootCollection"], body))
|
1672
1298
|
|
1673
|
-
#######
|
1674
1299
|
|
1675
|
-
return resp
|
1676
1300
|
@dynamic_catch
|
1677
1301
|
def create_folder_collection(self, display_name: str = None, description: str = None,
|
1678
1302
|
category: str = None, body: dict | NewElementRequestBody = None) -> str:
|
@@ -1709,7 +1333,7 @@ class CollectionManager(Client2):
|
|
1709
1333
|
|
1710
1334
|
return asyncio.get_event_loop().run_until_complete(
|
1711
1335
|
self._async_create_collection(display_name, description, category,
|
1712
|
-
"Folder", body))
|
1336
|
+
["Folder"], body))
|
1713
1337
|
|
1714
1338
|
|
1715
1339
|
|
@@ -1750,14 +1374,10 @@ class CollectionManager(Client2):
|
|
1750
1374
|
|
1751
1375
|
return asyncio.get_event_loop().run_until_complete(
|
1752
1376
|
self._async_create_collection(display_name, description, category,
|
1753
|
-
"ReferenceList", body))
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1377
|
+
["ReferenceList"], body))
|
1757
1378
|
|
1758
|
-
return resp
|
1759
1379
|
@dynamic_catch
|
1760
|
-
def
|
1380
|
+
def create_context_event_collection(self, display_name: str = None, description: str = None,
|
1761
1381
|
category: str = None, body: dict | NewElementRequestBody = None) -> str:
|
1762
1382
|
""" Create a new collection with the RootCollection classification. Used to identify the top of a
|
1763
1383
|
collection hierarchy.
|
@@ -1792,7 +1412,7 @@ class CollectionManager(Client2):
|
|
1792
1412
|
|
1793
1413
|
return asyncio.get_event_loop().run_until_complete(
|
1794
1414
|
self._async_create_collection(display_name, description, category,
|
1795
|
-
"
|
1415
|
+
["ContextEvent"], body))
|
1796
1416
|
|
1797
1417
|
@dynamic_catch
|
1798
1418
|
async def _async_create_data_spec_collection(self, display_name: str = None, description: str = None,
|
@@ -1900,51 +1520,35 @@ class CollectionManager(Client2):
|
|
1900
1520
|
}
|
1901
1521
|
|
1902
1522
|
"""
|
1523
|
+
validated_body = self.validate_new_element_request(body,"DataSpecProperties")
|
1903
1524
|
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
elif isinstance(body, dict):
|
1913
|
-
if body.get("properties", {}).get("class", "") == "DataSpecProperties":
|
1914
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
1915
|
-
else:
|
1916
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
1917
|
-
{"reason" : "unexpected property class name"})
|
1918
|
-
|
1919
|
-
elif display_name is not None:
|
1920
|
-
qualified_name = self.__create_qualified_name__("DataSpec", display_name, EGERIA_LOCAL_QUALIFIER)
|
1921
|
-
print(f"\n\tDisplayName was {display_name}, classification {classification_name}\n")
|
1922
|
-
initial_classifications_data = {"class" : "ClassificationProperties"}
|
1923
|
-
if classification_name:
|
1924
|
-
initial_classification_dict = {
|
1925
|
-
classification_name: InitialClassifications.model_validate(initial_classifications_data)
|
1926
|
-
}
|
1927
|
-
else:
|
1928
|
-
initial_classification_dict = None
|
1929
|
-
collection_properties = DataSpecProperties( class_ = "DataSpecProperties",
|
1930
|
-
qualified_name = qualified_name,
|
1931
|
-
display_name = display_name,
|
1932
|
-
description = description,
|
1933
|
-
category = category
|
1934
|
-
)
|
1935
|
-
body = {
|
1936
|
-
"class" :"NewElementRequestBody",
|
1937
|
-
"isOwnAnchor": True,
|
1938
|
-
"initialClassifications": initial_classification_dict,
|
1939
|
-
"properties": collection_properties.model_dump()
|
1940
|
-
}
|
1941
|
-
validated_body = NewElementRequestBody.model_validate(body)
|
1525
|
+
if validated_body is None and display_name is not None:
|
1526
|
+
qualified_name = self.__create_qualified_name__("DataSpec", display_name, EGERIA_LOCAL_QUALIFIER)
|
1527
|
+
print(f"\n\tDisplayName was {display_name}, classification {classification_name}\n")
|
1528
|
+
initial_classifications_data = {"class" : "ClassificationProperties"}
|
1529
|
+
if classification_name:
|
1530
|
+
initial_classification_dict = {
|
1531
|
+
classification_name: InitialClassifications.model_validate(initial_classifications_data)
|
1532
|
+
}
|
1942
1533
|
else:
|
1943
|
-
|
1534
|
+
initial_classification_dict = None
|
1535
|
+
collection_properties = DataSpecProperties( class_ = "DataSpecProperties",
|
1536
|
+
qualified_name = qualified_name,
|
1537
|
+
display_name = display_name,
|
1538
|
+
description = description,
|
1539
|
+
category = category
|
1540
|
+
)
|
1541
|
+
body = {
|
1542
|
+
"class" :"NewElementRequestBody",
|
1543
|
+
"isOwnAnchor": True,
|
1544
|
+
"initialClassifications": initial_classification_dict,
|
1545
|
+
"properties": collection_properties.model_dump()
|
1546
|
+
}
|
1547
|
+
validated_body = NewElementRequestBody.model_validate(body)
|
1548
|
+
else:
|
1549
|
+
raise PyegeriaInvalidParameterException(additional_info={"reason": "Invalid input parameters"})
|
1550
|
+
|
1944
1551
|
|
1945
|
-
except ValidationError as e:
|
1946
|
-
logger.error(f"Validation error: {e}")
|
1947
|
-
raise ValidationError(e)
|
1948
1552
|
|
1949
1553
|
|
1950
1554
|
url = f"{self.collection_command_root}"
|
@@ -1971,7 +1575,7 @@ class CollectionManager(Client2):
|
|
1971
1575
|
The description of the collection.
|
1972
1576
|
category: str, optional
|
1973
1577
|
An optional user-assigned category for the collection.
|
1974
|
-
|
1578
|
+
classification_name: str, optional
|
1975
1579
|
An initial classification for the collection. This can be used to distinguish, for instance, Folders
|
1976
1580
|
from Root Collections.
|
1977
1581
|
|
@@ -2173,49 +1777,33 @@ class CollectionManager(Client2):
|
|
2173
1777
|
|
2174
1778
|
"""
|
2175
1779
|
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
if body.get("properties", {}).get("class", "") == "DataDictionaryProperties":
|
2186
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
2187
|
-
else:
|
2188
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
2189
|
-
{"reason" : "unexpected property class name"})
|
2190
|
-
|
2191
|
-
elif display_name is not None:
|
2192
|
-
qualified_name = self.__create_qualified_name__("DataDictionary", display_name, EGERIA_LOCAL_QUALIFIER)
|
2193
|
-
initial_classifications_data = {"class" : "ClassificationProperties"}
|
2194
|
-
if classification_name:
|
2195
|
-
initial_classification_dict = {
|
2196
|
-
classification_name: InitialClassifications.model_validate(initial_classifications_data)
|
2197
|
-
}
|
2198
|
-
else:
|
2199
|
-
initial_classification_dict = None
|
2200
|
-
collection_properties = DataDictionaryProperties( class_ = "DataDictionaryProperties",
|
2201
|
-
qualified_name = qualified_name,
|
2202
|
-
display_name = display_name,
|
2203
|
-
description = description,
|
2204
|
-
category = category
|
2205
|
-
)
|
2206
|
-
body = {
|
2207
|
-
"class" :"NewElementRequestBody",
|
2208
|
-
"isOwnAnchor": True,
|
2209
|
-
"initialClassifications": initial_classification_dict,
|
2210
|
-
"properties": collection_properties.model_dump()
|
2211
|
-
}
|
2212
|
-
validated_body = NewElementRequestBody.model_validate(body)
|
1780
|
+
validated_body = self.validate_new_element_request(body,"DataDictionaryProperties")
|
1781
|
+
|
1782
|
+
if validated_body is None and display_name is not None:
|
1783
|
+
qualified_name = self.__create_qualified_name__("DataDictionary", display_name, EGERIA_LOCAL_QUALIFIER)
|
1784
|
+
initial_classifications_data = {"class" : "ClassificationProperties"}
|
1785
|
+
if classification_name:
|
1786
|
+
initial_classification_dict = {
|
1787
|
+
classification_name: InitialClassifications.model_validate(initial_classifications_data)
|
1788
|
+
}
|
2213
1789
|
else:
|
2214
|
-
|
1790
|
+
initial_classification_dict = None
|
1791
|
+
collection_properties = DataDictionaryProperties( class_ = "DataDictionaryProperties",
|
1792
|
+
qualified_name = qualified_name,
|
1793
|
+
display_name = display_name,
|
1794
|
+
description = description,
|
1795
|
+
category = category
|
1796
|
+
)
|
1797
|
+
body = {
|
1798
|
+
"class" :"NewElementRequestBody",
|
1799
|
+
"isOwnAnchor": True,
|
1800
|
+
"initialClassifications": initial_classification_dict,
|
1801
|
+
"properties": collection_properties.model_dump()
|
1802
|
+
}
|
1803
|
+
validated_body = NewElementRequestBody.model_validate(body)
|
2215
1804
|
|
2216
|
-
|
2217
|
-
|
2218
|
-
raise ValidationError(e)
|
1805
|
+
if validated_body is None:
|
1806
|
+
raise PyegeriaInvalidParameterException(additional_info={"reason": "Invalid input parameters"})
|
2219
1807
|
|
2220
1808
|
|
2221
1809
|
url = f"{self.collection_command_root}"
|
@@ -2480,8 +2068,7 @@ class CollectionManager(Client2):
|
|
2480
2068
|
|
2481
2069
|
|
2482
2070
|
@dynamic_catch
|
2483
|
-
async def _async_update_collection(self, collection_guid: str, body: dict |
|
2484
|
-
merge_update: bool = True) -> None:
|
2071
|
+
async def _async_update_collection(self, collection_guid: str, body: dict | UpdateElementRequestBody) -> None:
|
2485
2072
|
""" Update the properties of a collection. Use the correct properties object (CollectionProperties,
|
2486
2073
|
DigitalProductProperties, AgreementProperties, etc), that is appropriate for your element.
|
2487
2074
|
Collections: https://egeria-project.org/concepts/collection
|
@@ -2492,7 +2079,7 @@ class CollectionManager(Client2):
|
|
2492
2079
|
collection_guid: str
|
2493
2080
|
The guid of the collection to update.
|
2494
2081
|
|
2495
|
-
body: dict |
|
2082
|
+
body: dict | UpdateElementRequestBody, optional
|
2496
2083
|
A dict or NewElementRequestBody representing the details of the collection to create. If supplied, this
|
2497
2084
|
information will be used to create the collection and the other attributes will be ignored. The body is
|
2498
2085
|
validated before being used.
|
@@ -2534,44 +2121,18 @@ class CollectionManager(Client2):
|
|
2534
2121
|
}
|
2535
2122
|
"""
|
2536
2123
|
|
2537
|
-
try:
|
2538
|
-
if isinstance(body, NewElementRequestBody):
|
2539
|
-
if body.properties.class_ in COLLECTION_PROPERTIES_LIST:
|
2540
|
-
validated_body = body
|
2541
|
-
else:
|
2542
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
2543
|
-
{"reason" : "unexpected property class name"})
|
2544
|
-
|
2545
|
-
elif isinstance(body, dict):
|
2546
|
-
if body.get("properties", {}).get("class", "") in COLLECTION_PROPERTIES_LIST:
|
2547
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
2548
|
-
else:
|
2549
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
2550
|
-
{"reason" : "unexpected property class name"})
|
2551
|
-
else:
|
2552
|
-
raise TypeError("Invalid parameter type")
|
2553
|
-
|
2554
|
-
except ValidationError as e:
|
2555
|
-
logger.error(f"Validation error: {e}")
|
2556
|
-
raise ValidationError(e)
|
2557
|
-
|
2558
|
-
merge_update_s = str(merge_update).lower()
|
2559
|
-
|
2560
|
-
url = (f"{self.collection_command_root}/{collection_guid}/update?"
|
2561
|
-
f"replaceAllProperties={merge_update_s}")
|
2124
|
+
# try:
|
2562
2125
|
|
2563
|
-
|
2126
|
+
url = (f"{self.collection_command_root}/{collection_guid}/update")
|
2127
|
+
await self._async_update_element_body_request(url, COLLECTION_PROPERTIES_LIST,body)
|
2564
2128
|
|
2565
|
-
await self._async_make_request("POST", url, json_body)
|
2566
2129
|
|
2567
|
-
logger.info(f"Successfully updated {collection_guid} with {json_body}")
|
2568
2130
|
|
2569
2131
|
|
2570
2132
|
|
2571
2133
|
|
2572
2134
|
@dynamic_catch
|
2573
|
-
def update_collection(self, collection_guid: str, body: dict | NewElementRequestBody
|
2574
|
-
merge_update: bool = True) -> None:
|
2135
|
+
def update_collection(self, collection_guid: str, body: dict | NewElementRequestBody) -> None:
|
2575
2136
|
""" Update the properties of a collection. Use the correct properties object (CollectionProperties,
|
2576
2137
|
DigitalProductProperties, AgreementProperties, etc), that is appropriate for your element.
|
2577
2138
|
Collections: https://egeria-project.org/concepts/collection
|
@@ -2624,7 +2185,7 @@ class CollectionManager(Client2):
|
|
2624
2185
|
"""
|
2625
2186
|
|
2626
2187
|
return asyncio.get_event_loop().run_until_complete(
|
2627
|
-
self._async_update_collection(collection_guid, body
|
2188
|
+
self._async_update_collection(collection_guid, body))
|
2628
2189
|
|
2629
2190
|
|
2630
2191
|
@dynamic_catch
|
@@ -2695,32 +2256,9 @@ class CollectionManager(Client2):
|
|
2695
2256
|
OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
2696
2257
|
default to ACTIVE.
|
2697
2258
|
"""
|
2698
|
-
|
2699
|
-
if isinstance(body, NewElementRequestBody):
|
2700
|
-
if body.properties.class_ == "DigitalProductProperties":
|
2701
|
-
validated_body = body
|
2702
|
-
else:
|
2703
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
2704
|
-
{"reason": "unexpected property class name"})
|
2705
|
-
|
2706
|
-
elif isinstance(body, dict):
|
2707
|
-
if body.get("properties", {}).get("class", "") == "DigitalProductProperties":
|
2708
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
2709
|
-
else:
|
2710
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
2711
|
-
{"reason": "unexpected property class name"})
|
2712
|
-
|
2713
|
-
else:
|
2714
|
-
raise TypeError("Invalid parameter type")
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
2259
|
url = f"{self.collection_command_root}"
|
2719
|
-
|
2720
|
-
|
2721
|
-
resp = await self._async_make_request("POST", url, json_body, is_json=True)
|
2722
|
-
logger.info(f"Create collection with GUID: {resp.json().get('guid')}")
|
2723
|
-
return resp.json().get("guid", NO_GUID_RETURNED)
|
2260
|
+
return await self._async_create_element_body_request(url, "DigitalProductProperties", body)
|
2261
|
+
|
2724
2262
|
|
2725
2263
|
@dynamic_catch
|
2726
2264
|
def create_digital_product(self, body: dict | NewElementRequestBody = None) -> str:
|
@@ -2795,8 +2333,7 @@ class CollectionManager(Client2):
|
|
2795
2333
|
|
2796
2334
|
|
2797
2335
|
@dynamic_catch
|
2798
|
-
async def _async_update_digital_product(self, collection_guid: str, body: dict | UpdateElementRequestBody
|
2799
|
-
merge_update: bool = True) -> None:
|
2336
|
+
async def _async_update_digital_product(self, collection_guid: str, body: dict | UpdateElementRequestBody) -> None:
|
2800
2337
|
""" Update the properties of a digital product.
|
2801
2338
|
Collections: https://egeria-project.org/concepts/collection
|
2802
2339
|
|
@@ -2860,37 +2397,8 @@ class CollectionManager(Client2):
|
|
2860
2397
|
}
|
2861
2398
|
"""
|
2862
2399
|
|
2863
|
-
|
2864
|
-
|
2865
|
-
if body.properties.class_ == "DigitalProductProperties":
|
2866
|
-
validated_body = body
|
2867
|
-
else:
|
2868
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
2869
|
-
{"reason" : "unexpected property class name"})
|
2870
|
-
|
2871
|
-
elif isinstance(body, dict):
|
2872
|
-
if body.get("properties", {}).get("class", "") == "DigitalProductProperties":
|
2873
|
-
validated_body = self._update_element_request_adapter.validate_python(body)
|
2874
|
-
else:
|
2875
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
2876
|
-
{"reason" : "unexpected property class name"})
|
2877
|
-
else:
|
2878
|
-
raise TypeError("Invalid parameter type")
|
2879
|
-
|
2880
|
-
except ValidationError as e:
|
2881
|
-
logger.error(f"Validation error: {e}")
|
2882
|
-
raise ValidationError(e)
|
2883
|
-
|
2884
|
-
merge_update_s = str(merge_update).lower()
|
2885
|
-
|
2886
|
-
url = (f"{self.collection_command_root}/{collection_guid}/update?"
|
2887
|
-
f"replaceAllProperties={merge_update_s}")
|
2888
|
-
|
2889
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
2890
|
-
|
2891
|
-
await self._async_make_request("POST", url, json_body)
|
2892
|
-
|
2893
|
-
logger.info(f"Successfully updated {collection_guid} with {json_body}")
|
2400
|
+
url = (f"{self.collection_command_root}/{collection_guid}/update")
|
2401
|
+
await self._async_update_element_request_body(url, "DigitalProductProperties", body )
|
2894
2402
|
|
2895
2403
|
|
2896
2404
|
@dynamic_catch
|
@@ -2963,15 +2471,19 @@ class CollectionManager(Client2):
|
|
2963
2471
|
|
2964
2472
|
|
2965
2473
|
@dynamic_catch
|
2966
|
-
async def _async_update_collection_status(self, collection_guid: str,
|
2474
|
+
async def _async_update_collection_status(self, collection_guid: str, status: str = None,
|
2475
|
+
body: dict | UpdateStatusRequestBody = None):
|
2967
2476
|
"""Update the status of a collection. Async version.
|
2968
2477
|
|
2969
2478
|
Parameters
|
2970
2479
|
----------
|
2971
2480
|
collection_guid: str
|
2972
2481
|
The guid of the collection to update.
|
2973
|
-
|
2974
|
-
|
2482
|
+
status: str, optional
|
2483
|
+
The new lifecycle status for the collection. Ignored, if the body is provided.
|
2484
|
+
body: dict | UpdateStatusRequestBody, optional
|
2485
|
+
A structure representing the details of the collection to create. If supplied, these details
|
2486
|
+
supersede the status parameter provided.
|
2975
2487
|
|
2976
2488
|
Returns
|
2977
2489
|
-------
|
@@ -2999,31 +2511,24 @@ class CollectionManager(Client2):
|
|
2999
2511
|
"forDuplicateProcessing": false
|
3000
2512
|
}
|
3001
2513
|
"""
|
3002
|
-
try:
|
3003
|
-
if isinstance(body, UpdateStatusRequestBody):
|
3004
|
-
validated_body = body
|
3005
|
-
elif isinstance(body, dict):
|
3006
|
-
validated_body = self._update_status_request_adapter.validate_python(body)
|
3007
|
-
|
3008
|
-
except ValidationError as e:
|
3009
|
-
logger.error(f"Validation error: {e}")
|
3010
|
-
raise ValidationError(e)
|
3011
2514
|
|
3012
2515
|
url = f"{self.collection_command_root}/{collection_guid}/update-status"
|
3013
|
-
|
3014
|
-
await self._async_make_request("POST", url, json_body)
|
3015
|
-
logger.info(f"Successfully updated {collection_guid} with {json_body}")
|
2516
|
+
await self._async_update_status_request(url, status, body)
|
3016
2517
|
|
3017
2518
|
@dynamic_catch
|
3018
|
-
def update_collection_status(self, collection_guid: str,
|
2519
|
+
def update_collection_status(self, collection_guid: str, status: str = None,
|
2520
|
+
body: dict | UpdateStatusRequestBody = None):
|
3019
2521
|
"""Update the status of a DigitalProduct collection.
|
3020
2522
|
|
3021
2523
|
Parameters
|
3022
2524
|
----------
|
3023
2525
|
collection_guid: str
|
3024
2526
|
The guid of the collection to update.
|
3025
|
-
|
3026
|
-
|
2527
|
+
status: str, optional
|
2528
|
+
The new lifecycle status for the digital product. Ignored, if the body is provided.
|
2529
|
+
body: dict | UpdateStatusRequestBody, optional
|
2530
|
+
A structure representing the details of the collection to create. If supplied, these details
|
2531
|
+
supersede the status parameter provided.
|
3027
2532
|
|
3028
2533
|
Returns
|
3029
2534
|
-------
|
@@ -3052,19 +2557,23 @@ class CollectionManager(Client2):
|
|
3052
2557
|
}
|
3053
2558
|
"""
|
3054
2559
|
loop = asyncio.get_event_loop()
|
3055
|
-
loop.run_until_complete(self._async_update_collection_status(collection_guid, body))
|
2560
|
+
loop.run_until_complete(self._async_update_collection_status(collection_guid, status, body))
|
3056
2561
|
|
3057
2562
|
|
3058
2563
|
@dynamic_catch
|
3059
|
-
def update_digital_product_status(self, digital_product_guid: str,
|
2564
|
+
def update_digital_product_status(self, digital_product_guid: str, status: str = None,
|
2565
|
+
body: dict | UpdateStatusRequestBody = None):
|
3060
2566
|
"""Update the status of a DigitalProduct collection.
|
3061
2567
|
|
3062
2568
|
Parameters
|
3063
2569
|
----------
|
3064
2570
|
digital_product_guid: str
|
3065
|
-
The guid of the
|
3066
|
-
|
3067
|
-
|
2571
|
+
The guid of the collection to update.
|
2572
|
+
status: str, optional
|
2573
|
+
The new lifecycle status for the digital product. Ignored, if the body is provided.
|
2574
|
+
body: dict | UpdateStatusRequestBody, optional
|
2575
|
+
A structure representing the details of the collection to create. If supplied, these details
|
2576
|
+
supersede the status parameter provided.
|
3068
2577
|
|
3069
2578
|
Returns
|
3070
2579
|
-------
|
@@ -3093,7 +2602,7 @@ class CollectionManager(Client2):
|
|
3093
2602
|
}
|
3094
2603
|
"""
|
3095
2604
|
loop = asyncio.get_event_loop()
|
3096
|
-
loop.run_until_complete(self._async_update_collection_status(digital_product_guid, body))
|
2605
|
+
loop.run_until_complete(self._async_update_collection_status(digital_product_guid, status, body))
|
3097
2606
|
|
3098
2607
|
|
3099
2608
|
@dynamic_catch
|
@@ -3144,28 +2653,11 @@ class CollectionManager(Client2):
|
|
3144
2653
|
}
|
3145
2654
|
}
|
3146
2655
|
"""
|
3147
|
-
try:
|
3148
|
-
if isinstance(body, NewRelationshipRequestBody):
|
3149
|
-
validated_body = body
|
3150
|
-
elif isinstance(body, dict):
|
3151
|
-
validated_body = self._new_relationship_request_adapter.validate_python(body)
|
3152
|
-
else:
|
3153
|
-
validated_body = None
|
3154
|
-
|
3155
|
-
except ValidationError as e:
|
3156
|
-
logger.error(f"Validation error: {e}")
|
3157
|
-
raise ValidationError(e)
|
3158
|
-
|
3159
|
-
|
3160
2656
|
url = (
|
3161
2657
|
f"{self.platform_url}/servers/"
|
3162
2658
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/digital-products/"
|
3163
2659
|
f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/attach")
|
3164
|
-
|
3165
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3166
|
-
await self._async_make_request("POST", url, json_body)
|
3167
|
-
else:
|
3168
|
-
await self._async_make_request("POST", url)
|
2660
|
+
await self._async_new_relationship_request(url, "InformationSupplyChainLinkProperties", body)
|
3169
2661
|
logger.info(f"Linked {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
|
3170
2662
|
|
3171
2663
|
|
@@ -3264,30 +2756,13 @@ class CollectionManager(Client2):
|
|
3264
2756
|
}
|
3265
2757
|
|
3266
2758
|
"""
|
3267
|
-
try:
|
3268
|
-
if isinstance(body, DeleteRequestBody):
|
3269
|
-
validated_body = body
|
3270
|
-
elif isinstance(body, dict):
|
3271
|
-
validated_body = self._delete_request_adapter.validate_python(body)
|
3272
|
-
else:
|
3273
|
-
validated_body = None
|
3274
|
-
|
3275
|
-
except ValidationError as e:
|
3276
|
-
logger.error(f"Validation error: {e}")
|
3277
|
-
raise ValidationError(e)
|
3278
|
-
|
3279
2759
|
|
3280
2760
|
url = (
|
3281
2761
|
f"{self.platform_url}/servers/"
|
3282
2762
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/digital-products/"
|
3283
2763
|
f"{upstream_digital_prod_guid}/product-dependencies/{downstream_digital_prod_guid}/detach")
|
3284
|
-
|
3285
|
-
|
3286
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3287
|
-
await self._async_make_request("POST", url, json_body)
|
3288
|
-
else:
|
3289
|
-
await self._async_make_request("POST", url)
|
3290
|
-
logger.info(f"Detched digital product dependency {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
|
2764
|
+
await self._async_delete_request(url, body)
|
2765
|
+
logger.info(f"Detached digital product dependency {upstream_digital_prod_guid} -> {downstream_digital_prod_guid}")
|
3291
2766
|
|
3292
2767
|
|
3293
2768
|
def detach_digital_product_dependency(self, upstream_digital_prod_guid: str, downstream_digital_prod_guid: str,
|
@@ -3383,30 +2858,12 @@ class CollectionManager(Client2):
|
|
3383
2858
|
}
|
3384
2859
|
|
3385
2860
|
"""
|
3386
|
-
try:
|
3387
|
-
if isinstance(body, NewRelationshipRequestBody):
|
3388
|
-
validated_body = body
|
3389
|
-
elif isinstance(body, dict):
|
3390
|
-
validated_body = self._new_relationship_request_adapter.validate_python(body)
|
3391
|
-
else:
|
3392
|
-
validated_body = None
|
3393
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3394
|
-
{"reason": "unexpected body type"})
|
3395
|
-
except ValidationError as e:
|
3396
|
-
logger.error(f"Validation error: {e}")
|
3397
|
-
raise ValidationError(e)
|
3398
|
-
|
3399
2861
|
url = (
|
3400
2862
|
f"{self.platform_url}/servers/"
|
3401
2863
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/digital"
|
3402
2864
|
f"-products/"
|
3403
2865
|
f"{digital_prod_guid}/product-managers/{digital_prod_manager_guid}/attach")
|
3404
|
-
|
3405
|
-
if validated_body:
|
3406
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3407
|
-
await self._async_make_request("POST", url, json_body)
|
3408
|
-
else:
|
3409
|
-
await self._async_make_request("POST", url)
|
2866
|
+
await self._async_new_relationship_request(url, "AssignmentScopeProperties",body)
|
3410
2867
|
logger.info(f"Attached digital product manager {digital_prod_guid} -> {digital_prod_manager_guid}")
|
3411
2868
|
|
3412
2869
|
|
@@ -3500,31 +2957,12 @@ class CollectionManager(Client2):
|
|
3500
2957
|
}
|
3501
2958
|
|
3502
2959
|
"""
|
3503
|
-
try:
|
3504
|
-
if isinstance(body, DeleteRequestBody):
|
3505
|
-
validated_body = body
|
3506
|
-
elif isinstance(body, dict):
|
3507
|
-
validated_body = self._delete_request_adapter.validate_python(body)
|
3508
|
-
else:
|
3509
|
-
validated_body = None
|
3510
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3511
|
-
{"reason": "unexpected body type"})
|
3512
|
-
except ValidationError as e:
|
3513
|
-
logger.error(f"Validation error: {e}")
|
3514
|
-
raise ValidationError(e)
|
3515
|
-
|
3516
|
-
|
3517
2960
|
url = (
|
3518
2961
|
f"{self.platform_url}/servers/"
|
3519
2962
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/digital-products/"
|
3520
2963
|
f"{digital_prod_guid}/product-dependencies/{digital_prod_manager_guid}/detach")
|
3521
|
-
|
3522
|
-
|
3523
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3524
|
-
await self._async_make_request("POST", url, json_body)
|
3525
|
-
else:
|
3526
|
-
await self._async_make_request("POST", url)
|
3527
|
-
logger.info(f"Detched digital product manager {digital_prod_guid} -> {digital_prod_manager_guid}")
|
2964
|
+
await self._async_delete_request(url, body)
|
2965
|
+
logger.info(f"Detached digital product manager {digital_prod_guid} -> {digital_prod_manager_guid}")
|
3528
2966
|
|
3529
2967
|
@dynamic_catch
|
3530
2968
|
def detach_product_manager(self, digital_prod_guid: str, digital_prod_manager_guid: str,
|
@@ -3569,174 +3007,21 @@ class CollectionManager(Client2):
|
|
3569
3007
|
"""
|
3570
3008
|
loop = asyncio.get_event_loop()
|
3571
3009
|
loop.run_until_complete(
|
3572
|
-
self._async_detach_product_manager(digital_prod_guid, digital_prod_manager_guid,
|
3573
|
-
body))
|
3574
|
-
|
3575
|
-
|
3576
|
-
#
|
3577
|
-
|
3578
|
-
@dynamic_catch
|
3579
|
-
async def _async_create_agreement(self, body: dict | NewElementRequestBody) -> str:
|
3580
|
-
""" Create a new collection that represents an agreement.
|
3581
|
-
Async version.
|
3582
|
-
|
3583
|
-
Parameters
|
3584
|
-
----------
|
3585
|
-
body: dict | NewElementRequestBody
|
3586
|
-
A structure representing the details of the agreement to create.
|
3587
|
-
|
3588
|
-
Returns
|
3589
|
-
-------
|
3590
|
-
str - the guid of the created collection
|
3591
|
-
|
3592
|
-
Raises
|
3593
|
-
------
|
3594
|
-
PyegeriaException
|
3595
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
3596
|
-
ValidationError
|
3597
|
-
Raised by the pydantic validator if the body does not conform to the NewElementRequestBody.
|
3598
|
-
NotAuthorizedException
|
3599
|
-
The principle specified by the user_id does not have authorization for the requested action
|
3600
|
-
|
3601
|
-
Notes
|
3602
|
-
-----
|
3603
|
-
Note: the three dates: introductionDate, nextVersionDate and withdrawDate must
|
3604
|
-
be valid dates if specified, otherwise you will get a 400 error response.
|
3605
|
-
|
3606
|
-
JSON Structure looks like:
|
3607
|
-
{
|
3608
|
-
"class" : "NewElementRequestBody",
|
3609
|
-
"isOwnAnchor" : true,
|
3610
|
-
"anchorScopeGUID" : "optional GUID of search scope",
|
3611
|
-
"parentGUID" : "xxx",
|
3612
|
-
"parentRelationshipTypeName" : "CollectionMembership",
|
3613
|
-
"parentAtEnd1": true,
|
3614
|
-
"properties": {
|
3615
|
-
"class" : "AgreementProperties",
|
3616
|
-
"qualifiedName": "Agreement::Add agreement name here",
|
3617
|
-
"name" : "display name",
|
3618
|
-
"description" : "Add description of the agreement here",
|
3619
|
-
"identifier" : "Add agreement identifier here",
|
3620
|
-
"additionalProperties": {
|
3621
|
-
"property1Name" : "property1Value",
|
3622
|
-
"property2Name" : "property2Value"
|
3623
|
-
}
|
3624
|
-
},
|
3625
|
-
"externalSourceGUID": "add guid here",
|
3626
|
-
"externalSourceName": "add qualified name here",
|
3627
|
-
"effectiveTime" : "{{$isoTimestamp}}",
|
3628
|
-
"forLineage" : false,
|
3629
|
-
"forDuplicateProcessing" : false,
|
3630
|
-
"initialStatus" : "ACTIVE"
|
3631
|
-
}
|
3632
|
-
|
3633
|
-
The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED, APPROVED_CONCEPT,
|
3634
|
-
UNDER_DEVELOPMENT, DEVELOPMENT_COMPLETE, APPROVED_FOR_DEPLOYMENT, ACTIVE, DISABLED, DEPRECATED,
|
3635
|
-
OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
3636
|
-
default to ACTIVE.
|
3637
|
-
"""
|
3638
|
-
try:
|
3639
|
-
if isinstance(body, NewElementRequestBody):
|
3640
|
-
if body.properties.class_ == "AgreementProperties":
|
3641
|
-
validated_body = body
|
3642
|
-
else:
|
3643
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3644
|
-
{"reason": "unexpected property class name"})
|
3645
|
-
|
3646
|
-
elif isinstance(body, dict):
|
3647
|
-
if body.get("properties", {}).get("class", "") == "AgreementProperties":
|
3648
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
3649
|
-
else:
|
3650
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3651
|
-
{"reason": "unexpected property class name"})
|
3652
|
-
|
3653
|
-
else:
|
3654
|
-
raise TypeError("Invalid parameter type")
|
3655
|
-
|
3656
|
-
except ValidationError as e:
|
3657
|
-
logger.error(f"Validation error: {e}")
|
3658
|
-
raise ValidationError(e)
|
3659
|
-
|
3660
|
-
url = f"{self.collection_command_root}"
|
3661
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3662
|
-
logger.info(json_body)
|
3663
|
-
resp = await self._async_make_request("POST", url, json_body, is_json=True)
|
3664
|
-
logger.info(f"Create collection with GUID: {resp.json().get('guid')}")
|
3665
|
-
return resp.json().get("guid", NO_GUID_RETURNED)
|
3666
|
-
|
3667
|
-
@dynamic_catch
|
3668
|
-
def create_agreement(self, body: dict | NewElementRequestBody = None) -> str:
|
3669
|
-
""" Create a new collection that represents an agreement..
|
3670
|
-
|
3671
|
-
Parameters
|
3672
|
-
----------
|
3673
|
-
body: dict | NewElementRequestBody
|
3674
|
-
A structure representing the details of the agreement to create.
|
3675
|
-
|
3676
|
-
Returns
|
3677
|
-
-------
|
3678
|
-
str - the guid of the created collection
|
3679
|
-
|
3680
|
-
Raises
|
3681
|
-
------
|
3682
|
-
PyegeriaException
|
3683
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
3684
|
-
ValidationError
|
3685
|
-
Raised by the pydantic validator if the body does not conform to the NewElementRequestBody.
|
3686
|
-
NotAuthorizedException
|
3687
|
-
The principle specified by the user_id does not have authorization for the requested action
|
3688
|
-
|
3689
|
-
Notes
|
3690
|
-
-----
|
3691
|
-
Note: the three dates: introductionDate, nextVersionDate and withdrawDate must
|
3692
|
-
be valid dates if specified, otherwise you will get a 400 error response.
|
3693
|
-
|
3694
|
-
JSON Structure looks like:
|
3695
|
-
{
|
3696
|
-
"class" : "NewElementRequestBody",
|
3697
|
-
"isOwnAnchor" : true,
|
3698
|
-
"anchorScopeGUID" : "optional GUID of search scope",
|
3699
|
-
"parentGUID" : "xxx",
|
3700
|
-
"parentRelationshipTypeName" : "CollectionMembership",
|
3701
|
-
"parentAtEnd1": true,
|
3702
|
-
"properties": {
|
3703
|
-
"class" : "AgreementProperties",
|
3704
|
-
"qualifiedName": "Agreement::Add agreement name here",
|
3705
|
-
"name" : "display name",
|
3706
|
-
"description" : "Add description of the agreement here",
|
3707
|
-
"identifier" : "Add agreement identifier here",
|
3708
|
-
"additionalProperties": {
|
3709
|
-
"property1Name" : "property1Value",
|
3710
|
-
"property2Name" : "property2Value"
|
3711
|
-
}
|
3712
|
-
},
|
3713
|
-
"externalSourceGUID": "add guid here",
|
3714
|
-
"externalSourceName": "add qualified name here",
|
3715
|
-
"effectiveTime" : "{{$isoTimestamp}}",
|
3716
|
-
"forLineage" : false,
|
3717
|
-
"forDuplicateProcessing" : false,
|
3718
|
-
"initialStatus" : "ACTIVE"
|
3719
|
-
}
|
3720
|
-
|
3721
|
-
The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED, APPROVED_CONCEPT,
|
3722
|
-
UNDER_DEVELOPMENT, DEVELOPMENT_COMPLETE, APPROVED_FOR_DEPLOYMENT, ACTIVE, DISABLED, DEPRECATED,
|
3723
|
-
OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
3724
|
-
default to ACTIVE.
|
3725
|
-
"""
|
3010
|
+
self._async_detach_product_manager(digital_prod_guid, digital_prod_manager_guid,
|
3011
|
+
body))
|
3726
3012
|
|
3727
|
-
return asyncio.get_event_loop().run_until_complete(
|
3728
|
-
self._async_create_agreement(body))
|
3729
3013
|
|
3014
|
+
#
|
3730
3015
|
|
3731
3016
|
@dynamic_catch
|
3732
|
-
async def
|
3733
|
-
""" Create a new collection that represents
|
3017
|
+
async def _async_create_agreement(self, body: dict | NewElementRequestBody) -> str:
|
3018
|
+
""" Create a new collection that represents an agreement.
|
3734
3019
|
Async version.
|
3735
3020
|
|
3736
3021
|
Parameters
|
3737
3022
|
----------
|
3738
3023
|
body: dict | NewElementRequestBody
|
3739
|
-
A structure representing the details of the
|
3024
|
+
A structure representing the details of the agreement to create.
|
3740
3025
|
|
3741
3026
|
Returns
|
3742
3027
|
-------
|
@@ -3769,19 +3054,18 @@ class CollectionManager(Client2):
|
|
3769
3054
|
"qualifiedName": "Agreement::Add agreement name here",
|
3770
3055
|
"name" : "display name",
|
3771
3056
|
"description" : "Add description of the agreement here",
|
3772
|
-
"userDefinedStatus" : "NEW",
|
3773
3057
|
"identifier" : "Add agreement identifier here",
|
3774
3058
|
"additionalProperties": {
|
3775
3059
|
"property1Name" : "property1Value",
|
3776
3060
|
"property2Name" : "property2Value"
|
3777
3061
|
}
|
3778
3062
|
},
|
3779
|
-
"initialStatus" : "ACTIVE",
|
3780
3063
|
"externalSourceGUID": "add guid here",
|
3781
3064
|
"externalSourceName": "add qualified name here",
|
3782
3065
|
"effectiveTime" : "{{$isoTimestamp}}",
|
3783
3066
|
"forLineage" : false,
|
3784
|
-
"forDuplicateProcessing" : false
|
3067
|
+
"forDuplicateProcessing" : false,
|
3068
|
+
"initialStatus" : "ACTIVE"
|
3785
3069
|
}
|
3786
3070
|
|
3787
3071
|
The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED, APPROVED_CONCEPT,
|
@@ -3789,43 +3073,17 @@ class CollectionManager(Client2):
|
|
3789
3073
|
OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
3790
3074
|
default to ACTIVE.
|
3791
3075
|
"""
|
3792
|
-
|
3793
|
-
|
3794
|
-
if body.properties.class_ == "AgreementProperties":
|
3795
|
-
validated_body = body
|
3796
|
-
else:
|
3797
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3798
|
-
{"reason": "unexpected property class name"})
|
3799
|
-
|
3800
|
-
elif isinstance(body, dict):
|
3801
|
-
if body.get("properties", {}).get("class", "") == "AgreementProperties":
|
3802
|
-
validated_body = self._new_element_request_adapter.validate_python(body)
|
3803
|
-
else:
|
3804
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
3805
|
-
{"reason": "unexpected property class name"})
|
3806
|
-
|
3807
|
-
else:
|
3808
|
-
raise TypeError("Invalid parameter type")
|
3809
|
-
|
3810
|
-
except ValidationError as e:
|
3811
|
-
logger.error(f"Validation error: {e}")
|
3812
|
-
raise ValidationError(e)
|
3813
|
-
|
3814
|
-
url = f"{self.collection_command_root}/data-sharing-agreement"
|
3815
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3816
|
-
logger.info(json_body)
|
3817
|
-
resp = await self._async_make_request("POST", url, json_body, is_json=True)
|
3818
|
-
logger.info(f"Create collection with GUID: {resp.json().get('guid')}")
|
3819
|
-
return resp.json().get("guid", NO_GUID_RETURNED)
|
3076
|
+
url = f"{self.collection_command_root}"
|
3077
|
+
return await self._async_create_element_body_request(url, "AgreementProperties", body)
|
3820
3078
|
|
3821
3079
|
@dynamic_catch
|
3822
|
-
def
|
3823
|
-
""" Create a new collection that represents
|
3080
|
+
def create_agreement(self, body: dict | NewElementRequestBody = None) -> str:
|
3081
|
+
""" Create a new collection that represents an agreement..
|
3824
3082
|
|
3825
3083
|
Parameters
|
3826
3084
|
----------
|
3827
3085
|
body: dict | NewElementRequestBody
|
3828
|
-
A structure representing the details of the
|
3086
|
+
A structure representing the details of the agreement to create.
|
3829
3087
|
|
3830
3088
|
Returns
|
3831
3089
|
-------
|
@@ -3854,19 +3112,11 @@ class CollectionManager(Client2):
|
|
3854
3112
|
"parentRelationshipTypeName" : "CollectionMembership",
|
3855
3113
|
"parentAtEnd1": true,
|
3856
3114
|
"properties": {
|
3857
|
-
"class" : "
|
3858
|
-
"qualifiedName": "
|
3859
|
-
"name" : "
|
3860
|
-
"description" : "Add description of
|
3861
|
-
"identifier" : "Add
|
3862
|
-
"productName" : "Add product name here",
|
3863
|
-
"category" : "Periodic Delta",
|
3864
|
-
"maturity" : "Add valid value here",
|
3865
|
-
"serviceLife" : "Add the estimated lifetime of the product",
|
3866
|
-
"introductionDate" : "date",
|
3867
|
-
"nextVersionDate": "date",
|
3868
|
-
"withdrawDate": "date",
|
3869
|
-
"currentVersion": "V0.1",
|
3115
|
+
"class" : "AgreementProperties",
|
3116
|
+
"qualifiedName": "Agreement::Add agreement name here",
|
3117
|
+
"name" : "display name",
|
3118
|
+
"description" : "Add description of the agreement here",
|
3119
|
+
"identifier" : "Add agreement identifier here",
|
3870
3120
|
"additionalProperties": {
|
3871
3121
|
"property1Name" : "property1Value",
|
3872
3122
|
"property2Name" : "property2Value"
|
@@ -3887,12 +3137,148 @@ class CollectionManager(Client2):
|
|
3887
3137
|
"""
|
3888
3138
|
|
3889
3139
|
return asyncio.get_event_loop().run_until_complete(
|
3890
|
-
self.
|
3140
|
+
self._async_create_agreement(body))
|
3891
3141
|
|
3142
|
+
#
|
3143
|
+
# @dynamic_catch
|
3144
|
+
# async def _async_create_data_sharing_agreement(self, body: dict | NewElementRequestBody) -> str:
|
3145
|
+
# """ Create a new collection that represents a data sharing agreement.
|
3146
|
+
# Async version.
|
3147
|
+
#
|
3148
|
+
# Parameters
|
3149
|
+
# ----------
|
3150
|
+
# body: dict | NewElementRequestBody
|
3151
|
+
# A structure representing the details of the data sharing agreement to create.
|
3152
|
+
#
|
3153
|
+
# Returns
|
3154
|
+
# -------
|
3155
|
+
# str - the guid of the created collection
|
3156
|
+
#
|
3157
|
+
# Raises
|
3158
|
+
# ------
|
3159
|
+
# PyegeriaException
|
3160
|
+
# If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
3161
|
+
# ValidationError
|
3162
|
+
# Raised by the pydantic validator if the body does not conform to the NewElementRequestBody.
|
3163
|
+
# NotAuthorizedException
|
3164
|
+
# The principle specified by the user_id does not have authorization for the requested action
|
3165
|
+
#
|
3166
|
+
# Notes
|
3167
|
+
# -----
|
3168
|
+
# Note: the three dates: introductionDate, nextVersionDate and withdrawDate must
|
3169
|
+
# be valid dates if specified, otherwise you will get a 400 error response.
|
3170
|
+
#
|
3171
|
+
# JSON Structure looks like:
|
3172
|
+
# {
|
3173
|
+
# "class" : "NewElementRequestBody",
|
3174
|
+
# "isOwnAnchor" : true,
|
3175
|
+
# "anchorScopeGUID" : "optional GUID of search scope",
|
3176
|
+
# "parentGUID" : "xxx",
|
3177
|
+
# "parentRelationshipTypeName" : "CollectionMembership",
|
3178
|
+
# "parentAtEnd1": true,
|
3179
|
+
# "properties": {
|
3180
|
+
# "class" : "AgreementProperties",
|
3181
|
+
# "qualifiedName": "Agreement::Add agreement name here",
|
3182
|
+
# "name" : "display name",
|
3183
|
+
# "description" : "Add description of the agreement here",
|
3184
|
+
# "userDefinedStatus" : "NEW",
|
3185
|
+
# "identifier" : "Add agreement identifier here",
|
3186
|
+
# "additionalProperties": {
|
3187
|
+
# "property1Name" : "property1Value",
|
3188
|
+
# "property2Name" : "property2Value"
|
3189
|
+
# }
|
3190
|
+
# },
|
3191
|
+
# "initialStatus" : "ACTIVE",
|
3192
|
+
# "externalSourceGUID": "add guid here",
|
3193
|
+
# "externalSourceName": "add qualified name here",
|
3194
|
+
# "effectiveTime" : "{{$isoTimestamp}}",
|
3195
|
+
# "forLineage" : false,
|
3196
|
+
# "forDuplicateProcessing" : false
|
3197
|
+
# }
|
3198
|
+
#
|
3199
|
+
# The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED, APPROVED_CONCEPT,
|
3200
|
+
# UNDER_DEVELOPMENT, DEVELOPMENT_COMPLETE, APPROVED_FOR_DEPLOYMENT, ACTIVE, DISABLED, DEPRECATED,
|
3201
|
+
# OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
3202
|
+
# default to ACTIVE.
|
3203
|
+
# """
|
3204
|
+
#
|
3205
|
+
# url = f"{self.collection_command_root}/data-sharing-agreement"
|
3206
|
+
# return await self._async_create_element_body_request(url, "AgreementProperties", body)
|
3207
|
+
#
|
3208
|
+
# @dynamic_catch
|
3209
|
+
# def create_data_sharing_agreement(self, body: dict | NewElementRequestBody = None) -> str:
|
3210
|
+
# """ Create a new collection that represents a digital product.
|
3211
|
+
#
|
3212
|
+
# Parameters
|
3213
|
+
# ----------
|
3214
|
+
# body: dict | NewElementRequestBody
|
3215
|
+
# A structure representing the details of the digital product to create.
|
3216
|
+
#
|
3217
|
+
# Returns
|
3218
|
+
# -------
|
3219
|
+
# str - the guid of the created collection
|
3220
|
+
#
|
3221
|
+
# Raises
|
3222
|
+
# ------
|
3223
|
+
# PyegeriaException
|
3224
|
+
# If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
3225
|
+
# ValidationError
|
3226
|
+
# Raised by the pydantic validator if the body does not conform to the NewElementRequestBody.
|
3227
|
+
# NotAuthorizedException
|
3228
|
+
# The principle specified by the user_id does not have authorization for the requested action
|
3229
|
+
#
|
3230
|
+
# Notes
|
3231
|
+
# -----
|
3232
|
+
# Note: the three dates: introductionDate, nextVersionDate and withdrawDate must
|
3233
|
+
# be valid dates if specified, otherwise you will get a 400 error response.
|
3234
|
+
#
|
3235
|
+
# JSON Structure looks like:
|
3236
|
+
# {
|
3237
|
+
# "class" : "NewElementRequestBody",
|
3238
|
+
# "isOwnAnchor" : true,
|
3239
|
+
# "anchorScopeGUID" : "optional GUID of search scope",
|
3240
|
+
# "parentGUID" : "xxx",
|
3241
|
+
# "parentRelationshipTypeName" : "CollectionMembership",
|
3242
|
+
# "parentAtEnd1": true,
|
3243
|
+
# "properties": {
|
3244
|
+
# "class" : "DigitalProductProperties",
|
3245
|
+
# "qualifiedName": "DigitalProduct::Add product name here",
|
3246
|
+
# "name" : "Product contents",
|
3247
|
+
# "description" : "Add description of product and its expected usage here",
|
3248
|
+
# "identifier" : "Add product identifier here",
|
3249
|
+
# "productName" : "Add product name here",
|
3250
|
+
# "category" : "Periodic Delta",
|
3251
|
+
# "maturity" : "Add valid value here",
|
3252
|
+
# "serviceLife" : "Add the estimated lifetime of the product",
|
3253
|
+
# "introductionDate" : "date",
|
3254
|
+
# "nextVersionDate": "date",
|
3255
|
+
# "withdrawDate": "date",
|
3256
|
+
# "currentVersion": "V0.1",
|
3257
|
+
# "additionalProperties": {
|
3258
|
+
# "property1Name" : "property1Value",
|
3259
|
+
# "property2Name" : "property2Value"
|
3260
|
+
# }
|
3261
|
+
# },
|
3262
|
+
# "externalSourceGUID": "add guid here",
|
3263
|
+
# "externalSourceName": "add qualified name here",
|
3264
|
+
# "effectiveTime" : "{{$isoTimestamp}}",
|
3265
|
+
# "forLineage" : false,
|
3266
|
+
# "forDuplicateProcessing" : false,
|
3267
|
+
# "initialStatus" : "ACTIVE"
|
3268
|
+
# }
|
3269
|
+
#
|
3270
|
+
# The valid values for initialStatus are: DRAFT, PREPARED, PROPOSED, APPROVED, REJECTED, APPROVED_CONCEPT,
|
3271
|
+
# UNDER_DEVELOPMENT, DEVELOPMENT_COMPLETE, APPROVED_FOR_DEPLOYMENT, ACTIVE, DISABLED, DEPRECATED,
|
3272
|
+
# OTHER. If using OTHER, set the userDefinedStatus with the status value you want. If not specified, will
|
3273
|
+
# default to ACTIVE.
|
3274
|
+
# """
|
3275
|
+
#
|
3276
|
+
# return asyncio.get_event_loop().run_until_complete(
|
3277
|
+
# self._async_create_data_sharing_agreement(body))
|
3278
|
+
#
|
3892
3279
|
|
3893
3280
|
@dynamic_catch
|
3894
|
-
async def _async_update_agreement(self, agreement_guid: str, body: dict | UpdateElementRequestBody
|
3895
|
-
merge_update: bool = True) -> None:
|
3281
|
+
async def _async_update_agreement(self, agreement_guid: str, body: dict | UpdateElementRequestBody) -> None:
|
3896
3282
|
""" Update the properties of an agreement.
|
3897
3283
|
Collections: https://egeria-project.org/concepts/collection
|
3898
3284
|
|
@@ -3945,43 +3331,11 @@ class CollectionManager(Client2):
|
|
3945
3331
|
"forDuplicateProcessing" : false
|
3946
3332
|
}
|
3947
3333
|
"""
|
3948
|
-
|
3949
|
-
|
3950
|
-
if isinstance(body, NewElementRequestBody):
|
3951
|
-
if body.properties.class_ == "AgreementProperties":
|
3952
|
-
validated_body = body
|
3953
|
-
else:
|
3954
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
3955
|
-
{"reason" : "unexpected property class name"})
|
3956
|
-
|
3957
|
-
elif isinstance(body, dict):
|
3958
|
-
if body.get("properties", {}).get("class", "") == "AgreementProperties":
|
3959
|
-
validated_body = self._update_element_request_adapter.validate_python(body)
|
3960
|
-
else:
|
3961
|
-
raise PyegeriaInvalidParameterException(additional_info =
|
3962
|
-
{"reason" : "unexpected property class name"})
|
3963
|
-
else:
|
3964
|
-
raise TypeError("Invalid parameter type")
|
3965
|
-
|
3966
|
-
except ValidationError as e:
|
3967
|
-
logger.error(f"Validation error: {e}")
|
3968
|
-
raise ValidationError(e)
|
3969
|
-
|
3970
|
-
merge_update_s = str(merge_update).lower()
|
3971
|
-
|
3972
|
-
url = (f"{self.collection_command_root}/{agreement_guid}/update?"
|
3973
|
-
f"replaceAllProperties={merge_update_s}")
|
3974
|
-
|
3975
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
3976
|
-
|
3977
|
-
await self._async_make_request("POST", url, json_body)
|
3978
|
-
|
3979
|
-
logger.info(f"Successfully updated {agreement_guid} with {json_body}")
|
3980
|
-
|
3334
|
+
url = (f"{self.collection_command_root}/{agreement_guid}/update")
|
3335
|
+
await self._async_update_element_body_request(url, AGREEMENT_PROPERTIES_LIST,body)
|
3981
3336
|
|
3982
3337
|
@dynamic_catch
|
3983
|
-
def update_agreement(self, agreement_guid: str, body: dict | UpdateElementRequestBody
|
3984
|
-
merge_update: bool = True) -> None:
|
3338
|
+
def update_agreement(self, agreement_guid: str, body: dict | UpdateElementRequestBody) -> None:
|
3985
3339
|
""" Update the properties of an agreement.
|
3986
3340
|
Collections: https://egeria-project.org/concepts/collection
|
3987
3341
|
|
@@ -4035,68 +3389,20 @@ class CollectionManager(Client2):
|
|
4035
3389
|
"""
|
4036
3390
|
|
4037
3391
|
return asyncio.get_event_loop().run_until_complete(
|
4038
|
-
self._async_update_agreement(agreement_guid, body
|
4039
|
-
|
4040
|
-
|
4041
|
-
@dynamic_catch
|
4042
|
-
async def _async_update_agreement_status(self, agreement_guid: str, body: dict | UpdateStatusRequestBody):
|
4043
|
-
"""Update the status of an agreement. Async version.
|
4044
|
-
|
4045
|
-
Parameters
|
4046
|
-
----------
|
4047
|
-
agreement_guid: str
|
4048
|
-
The guid of the collection to update.
|
4049
|
-
body: dict | UpdateStatusRequestBody
|
4050
|
-
A structure representing the details of the collection to create.
|
4051
|
-
|
4052
|
-
Returns
|
4053
|
-
-------
|
4054
|
-
Nothing
|
4055
|
-
|
4056
|
-
Raises
|
4057
|
-
------
|
4058
|
-
InvalidParameterException
|
4059
|
-
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
4060
|
-
PropertyServerException
|
4061
|
-
Raised by the server when an issue arises in processing a valid request
|
4062
|
-
NotAuthorizedException
|
4063
|
-
The principle specified by the user_id does not have authorization for the requested action
|
3392
|
+
self._async_update_agreement(agreement_guid, body))
|
4064
3393
|
|
4065
|
-
Notes
|
4066
|
-
-----
|
4067
|
-
JSON Structure looks like:
|
4068
|
-
{
|
4069
|
-
"class": "UpdateStatusRequestBody",
|
4070
|
-
"status": "APPROVED",
|
4071
|
-
"externalSourceGUID": "add guid here",
|
4072
|
-
"externalSourceName": "add qualified name here",
|
4073
|
-
"effectiveTime": "{{$isoTimestamp}}",
|
4074
|
-
"forLineage": false,
|
4075
|
-
"forDuplicateProcessing": false
|
4076
|
-
}
|
4077
|
-
"""
|
4078
|
-
try:
|
4079
|
-
if isinstance(body, UpdateStatusRequestBody):
|
4080
|
-
validated_body = body
|
4081
|
-
elif isinstance(body, dict):
|
4082
|
-
validated_body = self._update_status_request_adapter.validate_python(body)
|
4083
|
-
|
4084
|
-
except ValidationError as e:
|
4085
|
-
logger.error(f"Validation error: {e}")
|
4086
|
-
raise ValidationError(e)
|
4087
3394
|
|
4088
|
-
url = f"{self.collection_command_root}/{agreement_guid}/update-status"
|
4089
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
4090
|
-
await self._async_make_request("POST", url, json_body)
|
4091
|
-
logger.info(f"Successfully updated {agreement_guid} with {json_body}")
|
4092
3395
|
|
4093
3396
|
@dynamic_catch
|
4094
|
-
def update_agreement_status(self, agreement_guid: str,
|
3397
|
+
def update_agreement_status(self, agreement_guid: str, status: str = None,
|
3398
|
+
body: dict | UpdateStatusRequestBody = None):
|
4095
3399
|
"""Update the status of an agreement.
|
4096
3400
|
Parameters
|
4097
3401
|
----------
|
4098
3402
|
agreement_guid: str
|
4099
3403
|
The guid of the collection to update.
|
3404
|
+
status: str, optional
|
3405
|
+
The new lifecycle status for the collection. Ignored, if the body is provided.
|
4100
3406
|
body: dict | UpdateStatusRequestBody
|
4101
3407
|
A structure representing the details of the collection to create.
|
4102
3408
|
|
@@ -4127,7 +3433,7 @@ class CollectionManager(Client2):
|
|
4127
3433
|
}
|
4128
3434
|
"""
|
4129
3435
|
loop = asyncio.get_event_loop()
|
4130
|
-
loop.run_until_complete(self._async_update_collection_status(agreement_guid, body))
|
3436
|
+
loop.run_until_complete(self._async_update_collection_status(agreement_guid, status,body))
|
4131
3437
|
|
4132
3438
|
|
4133
3439
|
|
@@ -4180,37 +3486,11 @@ class CollectionManager(Client2):
|
|
4180
3486
|
}
|
4181
3487
|
|
4182
3488
|
"""
|
4183
|
-
try:
|
4184
|
-
if isinstance(body, NewRelationshipRequestBody):
|
4185
|
-
if body.properties.class_ == "AgreementActorProperties":
|
4186
|
-
validated_body = body
|
4187
|
-
else:
|
4188
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
4189
|
-
{"reason": "unexpected property class name"})
|
4190
|
-
|
4191
|
-
elif isinstance(body, dict):
|
4192
|
-
if body.get("properties", {}).get("class", "") == "AgreementActorProperties":
|
4193
|
-
validated_body = self._new_relationship_request_adapter.validate_python(body)
|
4194
|
-
else:
|
4195
|
-
raise PyegeriaInvalidParameterException(additional_info=
|
4196
|
-
{"reason": "unexpected property class name"})
|
4197
|
-
else:
|
4198
|
-
validated_body = None
|
4199
|
-
|
4200
|
-
except ValidationError as e:
|
4201
|
-
logger.error(f"Validation error: {e}")
|
4202
|
-
raise ValidationError(e)
|
4203
|
-
|
4204
3489
|
url = (
|
4205
3490
|
f"{self.platform_url}/servers/"
|
4206
3491
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/agreements/"
|
4207
3492
|
f"{agreement_guid}/agreement-actors/{actor_guid}/attach")
|
4208
|
-
|
4209
|
-
if validated_body:
|
4210
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
4211
|
-
await self._async_make_request("POST", url, json_body)
|
4212
|
-
else:
|
4213
|
-
await self._async_make_request("POST", url)
|
3493
|
+
await self._async_new_relationship_request(url, "AgreementActorProperties",body)
|
4214
3494
|
logger.info(f"Attached digital product manager {agreement_guid} -> {actor_guid}")
|
4215
3495
|
|
4216
3496
|
|
@@ -4309,28 +3589,11 @@ class CollectionManager(Client2):
|
|
4309
3589
|
|
4310
3590
|
"""
|
4311
3591
|
|
4312
|
-
try:
|
4313
|
-
if isinstance(body, DeleteRequestBody):
|
4314
|
-
validated_body = body
|
4315
|
-
elif isinstance(body, dict):
|
4316
|
-
validated_body = self._delete_request_adapter.validate_python(body)
|
4317
|
-
else:
|
4318
|
-
validated_body = None
|
4319
|
-
|
4320
|
-
except ValidationError as e:
|
4321
|
-
logger.error(f"Validation error: {e}")
|
4322
|
-
raise ValidationError(e)
|
4323
|
-
|
4324
3592
|
url = (
|
4325
3593
|
f"{self.platform_url}/servers/"
|
4326
3594
|
f"{self.view_server}/api/open-metadata/collection-manager/collections/agreements/"
|
4327
3595
|
f"{agreement_guid}/agreement-actors/{actor_guid}/detach")
|
4328
|
-
|
4329
|
-
if validated_body:
|
4330
|
-
json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
|
4331
|
-
await self._async_make_request("POST", url, json_body)
|
4332
|
-
else:
|
4333
|
-
await self._async_make_request("POST", url)
|
3596
|
+
self._async_delete_request(url, body)
|
4334
3597
|
logger.info(f"Detached digital product manager {agreement_guid} -> {actor_guid}")
|
4335
3598
|
|
4336
3599
|
|
@@ -4447,29 +3710,11 @@ class CollectionManager(Client2):
|
|
4447
3710
|
}
|
4448
3711
|
|
4449
3712
|
"""
|
4450
|
-
|
4451
|
-
|
4452
|
-
|
4453
|
-
|
4454
|
-
|
4455
|
-
# validated_body = (**body)
|
4456
|
-
# except ValidationError as e:
|
4457
|
-
# logger.error(f"Validation error: {e}")
|
4458
|
-
# raise PyegeriaInvalidParameterException(f"Invalid body: {e}")
|
4459
|
-
# elif body is None:
|
4460
|
-
# validated_body = (
|
4461
|
-
#
|
4462
|
-
# )
|
4463
|
-
# # else:
|
4464
|
-
# raise PyegeriaInvalidParameterException(f"Invalid body type: {type(body)}")
|
4465
|
-
# url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/"
|
4466
|
-
# f"agreements/{agreement_guid}/agreement-items/{agreement_item_guid}/attach")
|
4467
|
-
#
|
4468
|
-
# if body:
|
4469
|
-
# await self._async_make_request("POST", url, body)
|
4470
|
-
# else:
|
4471
|
-
# await self._async_make_request("POST", url)
|
4472
|
-
# logger.info(f"Attached agreement item {agreement_item_guid} to {agreement_guid}")
|
3713
|
+
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/"
|
3714
|
+
f"agreements/{agreement_guid}/agreement-items/{agreement_item_guid}/attach")
|
3715
|
+
|
3716
|
+
await self._async_new_relationship_request(url, "AgreementItemProperties", body)
|
3717
|
+
logger.info(f"Attached agreement item {agreement_item_guid} to {agreement_guid}")
|
4473
3718
|
|
4474
3719
|
|
4475
3720
|
def link_agreement_item(self, agreement_guid: str, agreement_item_guid: str, body: dict = None) -> None:
|
@@ -4537,7 +3782,7 @@ class CollectionManager(Client2):
|
|
4537
3782
|
|
4538
3783
|
@dynamic_catch
|
4539
3784
|
async def _async_detach_agreement_item(self, agreement_guid: str, agreement_item_guid: str,
|
4540
|
-
body: dict = None) -> None:
|
3785
|
+
body: dict | DeleteRequestBody = None) -> None:
|
4541
3786
|
"""Detach an agreement item from an agreement. Request body is optional. Async version.
|
4542
3787
|
|
4543
3788
|
Parameters
|
@@ -4546,8 +3791,8 @@ class CollectionManager(Client2):
|
|
4546
3791
|
The guid of the agreement to link.
|
4547
3792
|
agreement_item_guid: str
|
4548
3793
|
The guid of the element to attach.
|
4549
|
-
body: dict, optional, default = None
|
4550
|
-
A
|
3794
|
+
body: dict | DeleteRequestBody, optional, default = None
|
3795
|
+
A structure representing the details of the relationship.
|
4551
3796
|
|
4552
3797
|
Returns
|
4553
3798
|
-------
|
@@ -4565,25 +3810,20 @@ class CollectionManager(Client2):
|
|
4565
3810
|
Notes
|
4566
3811
|
_____
|
4567
3812
|
{
|
4568
|
-
"class"
|
3813
|
+
"class": "DeleteRequestBody",
|
4569
3814
|
"externalSourceGUID": "add guid here",
|
4570
3815
|
"externalSourceName": "add qualified name here",
|
4571
|
-
"effectiveTime"
|
4572
|
-
"forLineage"
|
4573
|
-
"forDuplicateProcessing"
|
3816
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
3817
|
+
"forLineage": false,
|
3818
|
+
"forDuplicateProcessing": false
|
4574
3819
|
}
|
4575
3820
|
|
4576
3821
|
"""
|
4577
|
-
|
4578
3822
|
url = (
|
4579
3823
|
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
4580
3824
|
f"/agreements"
|
4581
3825
|
f"{agreement_guid}/agreement-items/{agreement_item_guid}/detach")
|
4582
|
-
|
4583
|
-
if body:
|
4584
|
-
await self._async_make_request("POST", url, body)
|
4585
|
-
else:
|
4586
|
-
await self._async_make_request("POST", url)
|
3826
|
+
await self._async_delete_request(url, body)
|
4587
3827
|
logger.info(f"Detached agreement item {agreement_item_guid} from {agreement_guid}")
|
4588
3828
|
|
4589
3829
|
|
@@ -4629,7 +3869,8 @@ class CollectionManager(Client2):
|
|
4629
3869
|
|
4630
3870
|
|
4631
3871
|
@dynamic_catch
|
4632
|
-
async def _async_link_contract(self, agreement_guid: str, external_ref_guid: str,
|
3872
|
+
async def _async_link_contract(self, agreement_guid: str, external_ref_guid: str,
|
3873
|
+
body: dict | NewRelationshipRequestBody = None) -> None:
|
4633
3874
|
""" Attach an agreement to an external reference element that describes the location of the contract
|
4634
3875
|
documents.
|
4635
3876
|
Request body is optional. Async version.
|
@@ -4640,8 +3881,8 @@ class CollectionManager(Client2):
|
|
4640
3881
|
The guid of the agreement to update.
|
4641
3882
|
external_ref_guid: str
|
4642
3883
|
The guid of the external reference to attach.
|
4643
|
-
body: dict, optional, default = None
|
4644
|
-
A
|
3884
|
+
body: dict | NewRelationshipRequestBody, optional, default = None
|
3885
|
+
A structure representing the details of the relationship.
|
4645
3886
|
|
4646
3887
|
Returns
|
4647
3888
|
-------
|
@@ -4678,17 +3919,12 @@ class CollectionManager(Client2):
|
|
4678
3919
|
}
|
4679
3920
|
|
4680
3921
|
"""
|
4681
|
-
|
4682
3922
|
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/"
|
4683
3923
|
f"agreements/{agreement_guid}/contract-links/{external_ref_guid}/attach")
|
3924
|
+
await self._async_new_relationship_request(url, "ContractLinkProperties", body)
|
3925
|
+
logger.info(f"Attached agreement {agreement_guid} to contract {external_ref_guid}")
|
4684
3926
|
|
4685
|
-
|
4686
|
-
await self._async_make_request("POST", url, body)
|
4687
|
-
else:
|
4688
|
-
await self._async_make_request("POST", url)
|
4689
|
-
logger.info(f"Attached agreemenbt {agreement_guid} to contract {external_ref_guid}")
|
4690
|
-
|
4691
|
-
|
3927
|
+
@dynamic_catch
|
4692
3928
|
def link_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
|
4693
3929
|
""" Attach an agreement to an external reference element that describes the location of the contract
|
4694
3930
|
documents.
|
@@ -4783,16 +4019,11 @@ class CollectionManager(Client2):
|
|
4783
4019
|
|
4784
4020
|
url = (
|
4785
4021
|
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
4786
|
-
f"/agreements"
|
4787
|
-
|
4788
|
-
|
4789
|
-
if body:
|
4790
|
-
await self._async_make_request("POST", url, body)
|
4791
|
-
else:
|
4792
|
-
await self._async_make_request("POST", url)
|
4022
|
+
f"/agreements/{agreement_guid}/contract-links/{external_ref_guid}/detach")
|
4023
|
+
await self._async_delete_request(url, body)
|
4793
4024
|
logger.info(f"Detached contract: {external_ref_guid} from {agreement_guid}")
|
4794
4025
|
|
4795
|
-
|
4026
|
+
@dynamic_catch
|
4796
4027
|
def detach_contract(self, agreement_guid: str, external_ref_guid: str, body: dict = None) -> None:
|
4797
4028
|
"""Detach an external reference to a contract, from an agreement. Request body is optional.
|
4798
4029
|
|
@@ -4839,13 +4070,13 @@ class CollectionManager(Client2):
|
|
4839
4070
|
|
4840
4071
|
|
4841
4072
|
@dynamic_catch
|
4842
|
-
async def _async_create_digital_subscription(self, body: dict) -> str:
|
4073
|
+
async def _async_create_digital_subscription(self, body: dict | NewElementRequestBody) -> str:
|
4843
4074
|
"""Create a new collection that represents a type of agreement called a digital_subscription. Async version.
|
4844
4075
|
|
4845
4076
|
Parameters
|
4846
4077
|
----------
|
4847
|
-
body: dict
|
4848
|
-
A
|
4078
|
+
body | NewElementRequewstBody: dict
|
4079
|
+
A structure representing the details of the collection to create.
|
4849
4080
|
|
4850
4081
|
Returns
|
4851
4082
|
-------
|
@@ -4937,13 +4168,8 @@ class CollectionManager(Client2):
|
|
4937
4168
|
"forDuplicateProcessing" : false
|
4938
4169
|
}
|
4939
4170
|
"""
|
4940
|
-
|
4941
4171
|
url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
4942
|
-
|
4943
|
-
resp = await self._async_make_request("POST", url, body_slimmer(body))
|
4944
|
-
guid = resp.json().get('guid', NO_GUID_RETURNED)
|
4945
|
-
logger.info(f"Create collection with GUID: {guid}")
|
4946
|
-
return guid
|
4172
|
+
return await self._async_create_element_body_request(url, "DigitalSubscriptionProperties", body)
|
4947
4173
|
|
4948
4174
|
|
4949
4175
|
def create_digital_subscription(self, body: dict) -> str:
|
@@ -5019,19 +4245,16 @@ class CollectionManager(Client2):
|
|
5019
4245
|
|
5020
4246
|
|
5021
4247
|
@dynamic_catch
|
5022
|
-
async def _async_update_digital_subscription(self, digital_subscription_guid: str,
|
5023
|
-
|
4248
|
+
async def _async_update_digital_subscription(self, digital_subscription_guid: str,
|
4249
|
+
body: dict | UpdateElementRequestBody) -> None:
|
5024
4250
|
"""Update the properties of the digital_subscription collection. Async version.
|
5025
4251
|
|
5026
4252
|
Parameters
|
5027
4253
|
----------
|
5028
4254
|
digital_subscription_guid: str
|
5029
4255
|
The guid of the digital_subscription to update.
|
5030
|
-
body: dict
|
5031
|
-
A
|
5032
|
-
replace_all_props: bool, optional, defaults to False
|
5033
|
-
Whether to replace all properties in the collection.
|
5034
|
-
|
4256
|
+
body: dict | UpdateElementRequestBody
|
4257
|
+
A structure representing the details of the collection to create.
|
5035
4258
|
|
5036
4259
|
Returns
|
5037
4260
|
-------
|
@@ -5075,17 +4298,13 @@ class CollectionManager(Client2):
|
|
5075
4298
|
"forDuplicateProcessing" : false
|
5076
4299
|
}
|
5077
4300
|
"""
|
5078
|
-
|
5079
|
-
replace_all_props_s = str(replace_all_props).lower()
|
5080
4301
|
url = (f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections/"
|
5081
|
-
f"{digital_subscription_guid}/update
|
5082
|
-
|
5083
|
-
await self._async_make_request("POST", url, body)
|
4302
|
+
f"{digital_subscription_guid}/update")
|
4303
|
+
await self._async_update_element_body_request(url,["DigitalSubscriptionProperties"], body )
|
5084
4304
|
logger.info(f"Updated digital subscription {digital_subscription_guid}")
|
5085
4305
|
|
5086
|
-
|
5087
|
-
def update_digital_subscription(self, digital_subscription_guid: str, body: dict,
|
5088
|
-
replace_all_props: bool = False, ):
|
4306
|
+
@dynamic_catch
|
4307
|
+
def update_digital_subscription(self, digital_subscription_guid: str, body: dict,):
|
5089
4308
|
"""Update the properties of the DigitalProduct classification attached to a collection.
|
5090
4309
|
|
5091
4310
|
Parameters
|
@@ -5138,19 +4357,22 @@ class CollectionManager(Client2):
|
|
5138
4357
|
"""
|
5139
4358
|
loop = asyncio.get_event_loop()
|
5140
4359
|
loop.run_until_complete(
|
5141
|
-
self._async_update_digital_subscription(digital_subscription_guid, body
|
4360
|
+
self._async_update_digital_subscription(digital_subscription_guid, body))
|
5142
4361
|
|
5143
4362
|
|
5144
4363
|
@dynamic_catch
|
5145
|
-
async def _async_update_digital_subscription_status(self, digital_subscription_guid: str,
|
5146
|
-
|
4364
|
+
async def _async_update_digital_subscription_status(self, digital_subscription_guid: str, status: str = None,
|
4365
|
+
body: dict | UpdateStatusRequestBody = None)-> None:
|
4366
|
+
"""Update the status of a digital_subscription collection. Async version.
|
5147
4367
|
|
5148
4368
|
Parameters
|
5149
4369
|
----------
|
5150
4370
|
digital_subscription_guid: str
|
5151
4371
|
The guid of the digital product collection to update.
|
5152
|
-
|
5153
|
-
|
4372
|
+
status: str, optional
|
4373
|
+
The new status of the digital_subscription collection. Will be used only if body is not provided.
|
4374
|
+
body: dict | UpdateStatusRequestBody, optional, defaults to None
|
4375
|
+
A structure representing the details of the collection to create.
|
5154
4376
|
|
5155
4377
|
Returns
|
5156
4378
|
-------
|
@@ -5168,27 +4390,26 @@ class CollectionManager(Client2):
|
|
5168
4390
|
Notes
|
5169
4391
|
-----
|
5170
4392
|
JSON Structure looks like:
|
5171
|
-
|
5172
|
-
|
5173
|
-
|
5174
|
-
|
5175
|
-
|
5176
|
-
|
5177
|
-
|
5178
|
-
|
5179
|
-
|
4393
|
+
{
|
4394
|
+
"class": "UpdateStatusRequestBody",
|
4395
|
+
"status": "APPROVED",
|
4396
|
+
"externalSourceGUID": "add guid here",
|
4397
|
+
"externalSourceName": "add qualified name here",
|
4398
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
4399
|
+
"forLineage": false,
|
4400
|
+
"forDuplicateProcessing": false
|
4401
|
+
}
|
5180
4402
|
"""
|
5181
|
-
|
5182
4403
|
url = (
|
5183
4404
|
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
5184
4405
|
f"/agreements/"
|
5185
4406
|
f"{digital_subscription_guid}/update-status")
|
5186
|
-
|
5187
|
-
await self._async_make_request("POST", url, body)
|
4407
|
+
await self._async_update_status_request(url, status, body)
|
5188
4408
|
logger.info(f"Updated status for DigitalProduct {digital_subscription_guid}")
|
5189
4409
|
|
5190
|
-
|
5191
|
-
def update_digital_subscription_status(self, digital_subscription_guid: str,
|
4410
|
+
@dynamic_catch
|
4411
|
+
def update_digital_subscription_status(self, digital_subscription_guid: str,
|
4412
|
+
body: dict | UpdateStatusRequestBody = None,):
|
5192
4413
|
"""Update the status of an digital_subscription collection. Async version.
|
5193
4414
|
|
5194
4415
|
Parameters
|
@@ -5230,7 +4451,8 @@ class CollectionManager(Client2):
|
|
5230
4451
|
|
5231
4452
|
|
5232
4453
|
@dynamic_catch
|
5233
|
-
async def _async_link_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4454
|
+
async def _async_link_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4455
|
+
body: dict | NewRelationshipRequestBody = None)-> None:
|
5234
4456
|
""" Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
|
5235
4457
|
products, team or business capabilities to be the subscriber. The subscription is an element of type
|
5236
4458
|
DigitalSubscription.
|
@@ -5242,8 +4464,8 @@ class CollectionManager(Client2):
|
|
5242
4464
|
The unique identifier of the subscriber.
|
5243
4465
|
subscription_guid: str
|
5244
4466
|
The identifier of the subscription.
|
5245
|
-
body: dict, optional, default = None
|
5246
|
-
A
|
4467
|
+
body: dict | NewRelationshipRequestBody, optional, default = None
|
4468
|
+
A structure representing the details of the relationship.
|
5247
4469
|
|
5248
4470
|
Returns
|
5249
4471
|
-------
|
@@ -5262,7 +4484,7 @@ class CollectionManager(Client2):
|
|
5262
4484
|
-----
|
5263
4485
|
JSON Structure looks like:
|
5264
4486
|
{
|
5265
|
-
"class" : "
|
4487
|
+
"class" : "NewRelationshipRequestBody",
|
5266
4488
|
"externalSourceGUID": "add guid here",
|
5267
4489
|
"externalSourceName": "add qualified name here",
|
5268
4490
|
"effectiveTime" : "{{$isoTimestamp}}",
|
@@ -5276,19 +4498,16 @@ class CollectionManager(Client2):
|
|
5276
4498
|
}
|
5277
4499
|
}
|
5278
4500
|
"""
|
5279
|
-
|
5280
4501
|
url = (
|
5281
4502
|
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
5282
4503
|
f"/subscribers/"
|
5283
4504
|
f"{subscriber_guid}/subscriptions/{subscription_guid}/attach")
|
5284
|
-
|
5285
|
-
await self._async_make_request("POST", url, body)
|
5286
|
-
else:
|
5287
|
-
await self._async_make_request("POST", url)
|
4505
|
+
await self._async_new_relationship_request(url, "DigitalSubscriberProperties", body)
|
5288
4506
|
logger.info(f"Linking subscriber {subscriber_guid} to subscription {subscription_guid}")
|
5289
4507
|
|
5290
|
-
|
5291
|
-
def link_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4508
|
+
@dynamic_catch
|
4509
|
+
def link_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4510
|
+
body: dict | NewRelationshipRequestBody = None):
|
5292
4511
|
""" Attach a subscriber to a subscription. The subscriber is of type 'Referenceable' to allow digital
|
5293
4512
|
products, team or business capabilities to be the subscriber. The subscription is an element of type
|
5294
4513
|
DigitalSubscription.
|
@@ -5339,7 +4558,8 @@ class CollectionManager(Client2):
|
|
5339
4558
|
|
5340
4559
|
|
5341
4560
|
@dynamic_catch
|
5342
|
-
async def _async_detach_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4561
|
+
async def _async_detach_subscriber(self, subscriber_guid: str, subscription_guid: str,
|
4562
|
+
body: dict | DeleteRequestBody = None) -> None:
|
5343
4563
|
""" Detach a subscriber from a subscription Request body is optional. Async version.
|
5344
4564
|
|
5345
4565
|
Parameters
|
@@ -5348,8 +4568,8 @@ class CollectionManager(Client2):
|
|
5348
4568
|
The unique identifier of the subscriber.
|
5349
4569
|
subscription_guid: str
|
5350
4570
|
The unique identifier of the subscription.
|
5351
|
-
body: dict, optional, default = None
|
5352
|
-
A
|
4571
|
+
body: dict | DeleteRequestBody, optional, default = None
|
4572
|
+
A structure representing the details of the relationship.
|
5353
4573
|
|
5354
4574
|
Returns
|
5355
4575
|
-------
|
@@ -5376,19 +4596,15 @@ class CollectionManager(Client2):
|
|
5376
4596
|
"forDuplicateProcessing": false
|
5377
4597
|
}
|
5378
4598
|
"""
|
5379
|
-
|
5380
4599
|
url = (
|
5381
4600
|
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/collection-manager/collections"
|
5382
4601
|
f"/agreements/"
|
5383
4602
|
f"{subscriber_guid}/agreement-actors/{subscription_guid}/detach")
|
5384
|
-
|
5385
|
-
await self._async_make_request("POST", url, body)
|
5386
|
-
else:
|
5387
|
-
await self._async_make_request("POST", url)
|
4603
|
+
await self._async_delete_request(url, body)
|
5388
4604
|
logger.info(f"Detached subscriber {subscriber_guid} from subscription {subscription_guid}")
|
5389
4605
|
|
5390
4606
|
|
5391
|
-
def detach_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict = None):
|
4607
|
+
def detach_subscriber(self, subscriber_guid: str, subscription_guid: str, body: dict | DeleteRequestBody= None):
|
5392
4608
|
""" Detach a subscriber from a subscription. Request body is optional.
|
5393
4609
|
|
5394
4610
|
Parameters
|
@@ -5434,8 +4650,8 @@ class CollectionManager(Client2):
|
|
5434
4650
|
|
5435
4651
|
|
5436
4652
|
@dynamic_catch
|
5437
|
-
async def _async_attach_collection(self, parent_guid: str, collection_guid: str,
|
5438
|
-
|
4653
|
+
async def _async_attach_collection(self, parent_guid: str, collection_guid: str,
|
4654
|
+
body: dict | NewRelationshipRequestBody= None):
|
5439
4655
|
""" Connect an existing collection to an element using the ResourceList relationship (0019).
|
5440
4656
|
Async version.
|
5441
4657
|
|
@@ -5445,10 +4661,8 @@ class CollectionManager(Client2):
|
|
5445
4661
|
The unique identifier of the parent to attach to.
|
5446
4662
|
collection_guid: str
|
5447
4663
|
The identifier of the collection being attached.
|
5448
|
-
body: dict, optional, default = None
|
5449
|
-
A
|
5450
|
-
make_anchor: bool, optional, default = False
|
5451
|
-
Indicates if the collection should be anchored to the element.
|
4664
|
+
body: dict | NewRelationshipRequestBody, optional, default = None
|
4665
|
+
A structure representing the details of the relationship.
|
5452
4666
|
|
5453
4667
|
Returns
|
5454
4668
|
-------
|
@@ -5468,7 +4682,7 @@ class CollectionManager(Client2):
|
|
5468
4682
|
JSON Structure looks like:
|
5469
4683
|
|
5470
4684
|
{
|
5471
|
-
"class" : "
|
4685
|
+
"class" : "NewRelationshipRequestBody",
|
5472
4686
|
"properties": {
|
5473
4687
|
"class": "ResourceListProperties",
|
5474
4688
|
"resourceUse": "Add valid value here",
|
@@ -5491,16 +4705,13 @@ class CollectionManager(Client2):
|
|
5491
4705
|
url = (
|
5492
4706
|
f"{self.platform_url}/servers/"
|
5493
4707
|
f"{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
|
5494
|
-
f"{parent_guid}/collections/{collection_guid}/attach
|
5495
|
-
|
5496
|
-
await self._async_make_request("POST", url, body)
|
5497
|
-
else:
|
5498
|
-
await self._async_make_request("POST", url)
|
4708
|
+
f"{parent_guid}/collections/{collection_guid}/attach")
|
4709
|
+
await self._async_new_relationship_request(url, "ResourceListProperties", body)
|
5499
4710
|
logger.info(f"Attached {collection_guid} to {parent_guid}")
|
5500
4711
|
|
5501
|
-
|
5502
|
-
def attach_collection(self, parent_guid: str, collection_guid: str,
|
5503
|
-
|
4712
|
+
@dynamic_catch
|
4713
|
+
def attach_collection(self, parent_guid: str, collection_guid: str,
|
4714
|
+
body: dict | NewRelationshipRequestBody = None):
|
5504
4715
|
""" Connect an existing collection to an element using the ResourceList relationship (0019).
|
5505
4716
|
|
5506
4717
|
Parameters
|
@@ -5551,11 +4762,12 @@ class CollectionManager(Client2):
|
|
5551
4762
|
}
|
5552
4763
|
"""
|
5553
4764
|
loop = asyncio.get_event_loop()
|
5554
|
-
loop.run_until_complete(self._async_attach_collection(parent_guid, collection_guid, body
|
4765
|
+
loop.run_until_complete(self._async_attach_collection(parent_guid, collection_guid, body))
|
5555
4766
|
|
5556
4767
|
|
5557
4768
|
@dynamic_catch
|
5558
|
-
async def _async_detach_collection(self, parent_guid: str, collection_guid: str,
|
4769
|
+
async def _async_detach_collection(self, parent_guid: str, collection_guid: str,
|
4770
|
+
body: dict | DeleteRequestBody = None):
|
5559
4771
|
""" Detach an existing collection from an element. If the collection is anchored to the element,
|
5560
4772
|
it is delete.
|
5561
4773
|
Async version.
|
@@ -5566,8 +4778,8 @@ class CollectionManager(Client2):
|
|
5566
4778
|
The unique identifier of the parent to detach from.
|
5567
4779
|
collection_guid: str
|
5568
4780
|
The identifier of the collection being detached.
|
5569
|
-
body: dict, optional, default = None
|
5570
|
-
A
|
4781
|
+
body: dict | DeleteRequestBody, optional, default = None
|
4782
|
+
A structure representing the details of the relationship.
|
5571
4783
|
|
5572
4784
|
|
5573
4785
|
Returns
|
@@ -5587,27 +4799,25 @@ class CollectionManager(Client2):
|
|
5587
4799
|
-----
|
5588
4800
|
JSON Structure looks like:
|
5589
4801
|
{
|
5590
|
-
"class": "
|
4802
|
+
"class": "DeleteRequestBody",
|
5591
4803
|
"externalSourceGUID": "add guid here",
|
5592
4804
|
"externalSourceName": "add qualified name here",
|
5593
4805
|
"effectiveTime": "{{$isoTimestamp}}",
|
5594
4806
|
"forLineage": false,
|
5595
4807
|
"forDuplicateProcessing": false
|
5596
4808
|
}
|
5597
|
-
"""
|
5598
4809
|
|
4810
|
+
"""
|
5599
4811
|
url = (
|
5600
4812
|
f"{self.platform_url}/servers/"
|
5601
4813
|
f"{self.view_server}/api/open-metadata/collection-manager/metadata-elements/"
|
5602
4814
|
f"{parent_guid}/collections/{collection_guid}/detach")
|
5603
|
-
|
5604
|
-
await self._async_make_request("POST", url, body)
|
5605
|
-
else:
|
5606
|
-
await self._async_make_request("POST", url)
|
4815
|
+
await self._async_delete_request(url, body)
|
5607
4816
|
logger.info(f"Detached collection {collection_guid} from {parent_guid}")
|
5608
4817
|
|
5609
4818
|
|
5610
|
-
def detach_collection(self, parent_guid: str, collection_guid: str,
|
4819
|
+
def detach_collection(self, parent_guid: str, collection_guid: str,
|
4820
|
+
body: dict | DeleteRequestBody = None):
|
5611
4821
|
""" Detach an existing collection from an element. If the collection is anchored to the element,
|
5612
4822
|
it is delete.
|
5613
4823
|
|
@@ -5650,7 +4860,7 @@ class CollectionManager(Client2):
|
|
5650
4860
|
|
5651
4861
|
|
5652
4862
|
@dynamic_catch
|
5653
|
-
async def _async_delete_collection(self, collection_guid: str, body: dict = None,
|
4863
|
+
async def _async_delete_collection(self, collection_guid: str, body: dict | DeleteRequestBody= None,
|
5654
4864
|
cascade: bool = False) -> None:
|
5655
4865
|
"""Delete a collection. It is detected from all parent elements. If members are anchored to the collection
|
5656
4866
|
then they are also deleted. Async version
|
@@ -5659,13 +4869,13 @@ class CollectionManager(Client2):
|
|
5659
4869
|
Parameters
|
5660
4870
|
----------
|
5661
4871
|
collection_guid: str
|
5662
|
-
The guid of the collection to
|
4872
|
+
The guid of the collection to delete.
|
5663
4873
|
|
5664
4874
|
cascade: bool, optional, defaults to True
|
5665
4875
|
If true, a cascade delete is performed.
|
5666
4876
|
|
5667
|
-
body: dict, optional, default = None
|
5668
|
-
A
|
4877
|
+
body: dict | DeleteRequestBody, optional, default = None
|
4878
|
+
A structure representing the details of the relationship.
|
5669
4879
|
|
5670
4880
|
Returns
|
5671
4881
|
-------
|
@@ -5684,38 +4894,35 @@ class CollectionManager(Client2):
|
|
5684
4894
|
_____
|
5685
4895
|
JSON Structure looks like:
|
5686
4896
|
{
|
5687
|
-
"class"
|
4897
|
+
"class": "DeleteRequestBody",
|
5688
4898
|
"externalSourceGUID": "add guid here",
|
5689
4899
|
"externalSourceName": "add qualified name here",
|
5690
|
-
"effectiveTime"
|
5691
|
-
"forLineage"
|
5692
|
-
"forDuplicateProcessing"
|
4900
|
+
"effectiveTime": "{{$isoTimestamp}}",
|
4901
|
+
"forLineage": false,
|
4902
|
+
"forDuplicateProcessing": false
|
5693
4903
|
}
|
5694
4904
|
|
5695
4905
|
|
5696
4906
|
"""
|
5697
|
-
|
5698
|
-
url
|
5699
|
-
if body is None:
|
5700
|
-
body = {"class": "NullRequestBody"}
|
5701
|
-
|
5702
|
-
await self._async_make_request("POST", url, body)
|
4907
|
+
url = f"{self.collection_command_root}/{collection_guid}/delete"
|
4908
|
+
await self._async_delete_request(url, body, cascade)
|
5703
4909
|
logger.info(f"Deleted collection {collection_guid} with cascade {cascade}")
|
5704
4910
|
|
5705
4911
|
|
5706
|
-
def delete_collection(self, collection_guid: str, body: dict
|
5707
|
-
|
4912
|
+
def delete_collection(self, collection_guid: str, body: dict | DeleteRequestBody = None,
|
4913
|
+
cascade: bool = False) -> None:
|
4914
|
+
"""Delete a collection. It is deleted from all parent elements. If members are anchored to the collection
|
5708
4915
|
then they are also deleted.
|
5709
4916
|
|
5710
4917
|
Parameters
|
5711
4918
|
----------
|
5712
4919
|
collection_guid: str
|
5713
|
-
The guid of the collection to
|
4920
|
+
The guid of the collection to delete.
|
5714
4921
|
|
5715
4922
|
cascade: bool, optional, defaults to True
|
5716
4923
|
If true, a cascade delete is performed.
|
5717
4924
|
|
5718
|
-
body: dict, optional, default = None
|
4925
|
+
body: dict DeleteRequestBodyt, optional, default = None
|
5719
4926
|
A dict representing the details of the relationship.
|
5720
4927
|
|
5721
4928
|
Returns
|
@@ -5734,14 +4941,7 @@ class CollectionManager(Client2):
|
|
5734
4941
|
Notes
|
5735
4942
|
_____
|
5736
4943
|
JSON Structure looks like:
|
5737
|
-
|
5738
|
-
"class" : "MetadataSourceRequestBody",
|
5739
|
-
"externalSourceGUID": "add guid here",
|
5740
|
-
"externalSourceName": "add qualified name here",
|
5741
|
-
"effectiveTime" : "{{$isoTimestamp}}",
|
5742
|
-
"forLineage" : false,
|
5743
|
-
"forDuplicateProcessing" : false
|
5744
|
-
}
|
4944
|
+
|
5745
4945
|
|
5746
4946
|
|
5747
4947
|
"""
|
@@ -5750,7 +4950,8 @@ class CollectionManager(Client2):
|
|
5750
4950
|
|
5751
4951
|
|
5752
4952
|
@dynamic_catch
|
5753
|
-
async def _async_add_to_collection(self, collection_guid: str, element_guid: str,
|
4953
|
+
async def _async_add_to_collection(self, collection_guid: str, element_guid: str,
|
4954
|
+
body: dict | NewRelationshipRequestBody = None, ) -> None:
|
5754
4955
|
"""Add an element to a collection. The request body is optional. Async version.
|
5755
4956
|
|
5756
4957
|
Parameters
|
@@ -5759,12 +4960,9 @@ class CollectionManager(Client2):
|
|
5759
4960
|
identity of the collection to return members for.
|
5760
4961
|
element_guid: str
|
5761
4962
|
Effective time of the query. If not specified will default to any time.
|
5762
|
-
body: dict, optional, defaults to None
|
4963
|
+
body: dict NewRelationshipRequestBody, optional, defaults to None
|
5763
4964
|
The body of the request to add to the collection. See notes.
|
5764
4965
|
|
5765
|
-
The name of the server to use.
|
5766
|
-
|
5767
|
-
|
5768
4966
|
Returns
|
5769
4967
|
-------
|
5770
4968
|
None
|
@@ -5782,7 +4980,7 @@ class CollectionManager(Client2):
|
|
5782
4980
|
Notes
|
5783
4981
|
-----
|
5784
4982
|
Example body:
|
5785
|
-
{ "class": "
|
4983
|
+
{ "class": "NewRelationshipRequestBody",
|
5786
4984
|
"properties" : {
|
5787
4985
|
"class" : "CollectionMembershipProperties",
|
5788
4986
|
"membershipRationale": "xxx",
|
@@ -5809,12 +5007,12 @@ class CollectionManager(Client2):
|
|
5809
5007
|
|
5810
5008
|
url = (f"{self.collection_command_root}/{collection_guid}/members/"
|
5811
5009
|
f"{element_guid}/attach")
|
5812
|
-
|
5813
|
-
await self._async_make_request("POST", url, body_s)
|
5010
|
+
await self._async_new_relationship_request(url, "CollectionMembershipProperties", body)
|
5814
5011
|
logger.info(f"Added {element_guid} to {collection_guid}")
|
5815
5012
|
|
5816
5013
|
|
5817
|
-
def add_to_collection(self, collection_guid: str, element_guid: str,
|
5014
|
+
def add_to_collection(self, collection_guid: str, element_guid: str,
|
5015
|
+
body: dict | NewRelationshipRequestBody= None, ) -> None:
|
5818
5016
|
"""Add an element to a collection. The request body is optional.
|
5819
5017
|
|
5820
5018
|
Parameters
|
@@ -5875,8 +5073,8 @@ class CollectionManager(Client2):
|
|
5875
5073
|
|
5876
5074
|
|
5877
5075
|
@dynamic_catch
|
5878
|
-
async def
|
5879
|
-
|
5076
|
+
async def _async_update_collection_membership_prop(self, collection_guid: str, element_guid: str, body: dict = None,
|
5077
|
+
) -> None:
|
5880
5078
|
"""Update an element's membership to a collection. Async version.
|
5881
5079
|
|
5882
5080
|
Parameters
|
@@ -5934,16 +5132,15 @@ class CollectionManager(Client2):
|
|
5934
5132
|
}
|
5935
5133
|
"""
|
5936
5134
|
|
5937
|
-
replace_all_props_s = str(replace_all_props).lower()
|
5938
5135
|
url = (f"{self.collection_command_root}/{collection_guid}/members/"
|
5939
|
-
f"{element_guid}/update
|
5940
|
-
|
5941
|
-
await self._async_make_request("POST", url, body_s)
|
5136
|
+
f"{element_guid}/update")
|
5137
|
+
await self._async_update_relationship_request(url, "CollectionMembershipProperties", body )
|
5942
5138
|
logger.info(f"Updated membership for collection {collection_guid}")
|
5943
5139
|
|
5944
5140
|
|
5945
|
-
def
|
5946
|
-
|
5141
|
+
def update_collection_membership_prop(self, collection_guid: str, element_guid: str,
|
5142
|
+
body: dict | UpdateRelationshipRequestBody= None,
|
5143
|
+
) -> None:
|
5947
5144
|
"""Update an element's membership to a collection.
|
5948
5145
|
|
5949
5146
|
Parameters
|
@@ -6002,12 +5199,12 @@ class CollectionManager(Client2):
|
|
6002
5199
|
"""
|
6003
5200
|
loop = asyncio.get_event_loop()
|
6004
5201
|
loop.run_until_complete(
|
6005
|
-
self._async_update_collection_membership(collection_guid, element_guid, body
|
5202
|
+
self._async_update_collection_membership(collection_guid, element_guid, body))
|
6006
5203
|
|
6007
5204
|
|
6008
5205
|
@dynamic_catch
|
6009
5206
|
async def _async_remove_from_collection(self, collection_guid: str, element_guid: str,
|
6010
|
-
body: dict = None) -> None:
|
5207
|
+
body: dict | DeleteRequestBody = None) -> None:
|
6011
5208
|
"""Remove an element from a collection. Async version.
|
6012
5209
|
|
6013
5210
|
Parameters
|
@@ -6016,7 +5213,7 @@ class CollectionManager(Client2):
|
|
6016
5213
|
identity of the collection to return members for.
|
6017
5214
|
element_guid: str
|
6018
5215
|
Effective time of the query. If not specified will default to any time.
|
6019
|
-
body: dict, optional, defaults to None
|
5216
|
+
body: dict | DeleteRequestBody, optional, defaults to None
|
6020
5217
|
The body of the request to add to the collection. See notes.
|
6021
5218
|
|
6022
5219
|
Returns
|
@@ -6036,7 +5233,7 @@ class CollectionManager(Client2):
|
|
6036
5233
|
Notes
|
6037
5234
|
-----
|
6038
5235
|
{
|
6039
|
-
"class" : "
|
5236
|
+
"class" : "DeleteRequestBody",
|
6040
5237
|
"externalSourceGUID": "add guid here",
|
6041
5238
|
"externalSourceName": "add qualified name here",
|
6042
5239
|
"effectiveTime" : "{{$isoTimestamp}}",
|
@@ -6048,13 +5245,12 @@ class CollectionManager(Client2):
|
|
6048
5245
|
|
6049
5246
|
url = (f"{self.collection_command_root}/{collection_guid}/members/"
|
6050
5247
|
f"{element_guid}/detach")
|
6051
|
-
|
6052
|
-
body = {"class": "NullRequestBody"}
|
6053
|
-
await self._async_make_request("POST", url, body)
|
5248
|
+
await self._async_delete_collection(url, body)
|
6054
5249
|
logger.info(f"Removed member {element_guid} from collection {collection_guid}")
|
6055
5250
|
|
6056
5251
|
|
6057
|
-
def remove_from_collection(self, collection_guid: str, element_guid: str,
|
5252
|
+
def remove_from_collection(self, collection_guid: str, element_guid: str,
|
5253
|
+
body: dict | DeleteRequestBody= None) -> None:
|
6058
5254
|
"""Remove an element from a collection. Async version.
|
6059
5255
|
|
6060
5256
|
Parameters
|
@@ -6182,46 +5378,113 @@ class CollectionManager(Client2):
|
|
6182
5378
|
self._async_get_member_list(collection_guid, collection_name, collection_qname))
|
6183
5379
|
return resp
|
6184
5380
|
|
6185
|
-
|
6186
|
-
|
5381
|
+
def _extract_digital_product_properties(self, element: dict, guid: str, output_format: str) -> dict:
|
5382
|
+
props = element["properties"]
|
5383
|
+
digital_prod = DigitalProductProperties.model_validate(props)
|
5384
|
+
added_props = get_defined_field_values(digital_prod)
|
5385
|
+
|
5386
|
+
used_by_digital_products = element.get("usedByDigitalProducts", "")
|
5387
|
+
if isinstance(used_by_digital_products, (list | dict)):
|
5388
|
+
used_by_digital_products_list = ""
|
5389
|
+
for prod in used_by_digital_products:
|
5390
|
+
used_by_digital_products_list += f"{prod["relatedElement"]["properties"]["qualifiedName"]}, "
|
5391
|
+
added_props["used_by_digital_products"] = used_by_digital_products_list[:-2]
|
5392
|
+
|
5393
|
+
uses_digital_products = element.get("usesDigitalProducts", "")
|
5394
|
+
if isinstance(uses_digital_products, (list | dict)):
|
5395
|
+
uses_digital_products_list = ""
|
5396
|
+
for prod in uses_digital_products:
|
5397
|
+
uses_digital_products_list += f"{prod["relatedElement"]["properties"]["qualifiedName"]}, "
|
5398
|
+
added_props["uses_digital_products"] = uses_digital_products_list[:-2]
|
5399
|
+
|
5400
|
+
return added_props
|
5401
|
+
|
5402
|
+
def _extract_agreement_properties(self, element: dict, guid: str, output_format: str) -> dict:
|
5403
|
+
props = element["properties"]
|
5404
|
+
# agreement = Collections.model_validate(props)
|
5405
|
+
# added_props = get_defined_field_values(agreement)
|
5406
|
+
|
5407
|
+
added_props = {}
|
5408
|
+
agreement_items = element.get("agreementItems", "")
|
5409
|
+
if isinstance(agreement_items, (list | dict)):
|
5410
|
+
agreement_items_list = ""
|
5411
|
+
for item in agreement_items:
|
5412
|
+
agreement_items_list += f"{item["relatedElement"]["properties"]["qualifiedName"]}, "
|
5413
|
+
added_props["agreementItems"] = agreement_items_list[:-2]
|
5414
|
+
|
5415
|
+
return added_props
|
5416
|
+
|
5417
|
+
def _extract_collection_properties(self, element: dict, columns_struct: dict) -> dict:
|
6187
5418
|
"""
|
6188
|
-
Extract common properties from a collection element.
|
5419
|
+
Extract common properties from a collection element and populate into the provided columns_struct.
|
6189
5420
|
|
6190
5421
|
Args:
|
6191
5422
|
element (dict): The collection element
|
5423
|
+
columns_struct (dict): The columns structure to populate
|
6192
5424
|
|
6193
5425
|
Returns:
|
6194
|
-
dict:
|
5426
|
+
dict: columns_struct with column 'value' fields populated
|
6195
5427
|
"""
|
6196
|
-
|
6197
|
-
|
5428
|
+
# First, populate from element.properties using the utility
|
5429
|
+
col_data = populate_columns_from_properties(element, columns_struct)
|
5430
|
+
|
5431
|
+
columns_list = col_data.get("formats", {}).get("columns", [])
|
5432
|
+
|
5433
|
+
# Populate header-derived values
|
5434
|
+
header_props = _extract_referenceable_properties(element)
|
5435
|
+
for column in columns_list:
|
5436
|
+
key = column.get('key')
|
5437
|
+
if key in header_props:
|
5438
|
+
column['value'] = header_props.get(key)
|
5439
|
+
elif isinstance(key, str) and key.lower() == 'guid':
|
5440
|
+
column['value'] = header_props.get('GUID')
|
5441
|
+
|
5442
|
+
# Derived/computed fields
|
5443
|
+
# collectionCategories are classifications
|
6198
5444
|
classification_names = ""
|
6199
|
-
|
6200
|
-
for classification in
|
5445
|
+
classifications = element.get('elementHeader', {}).get("collectionCategories", [])
|
5446
|
+
for classification in classifications:
|
6201
5447
|
classification_names += f"{classification['classificationName']}, "
|
6202
|
-
|
5448
|
+
if classification_names:
|
5449
|
+
for column in columns_list:
|
5450
|
+
if column.get('key') == 'classifications':
|
5451
|
+
column['value'] = classification_names[:-2]
|
5452
|
+
break
|
5453
|
+
|
5454
|
+
# Populate requested relationship-based columns generically from top-level keys
|
5455
|
+
col_data = get_required_relationships(element, col_data)
|
6203
5456
|
|
6204
|
-
|
5457
|
+
# Subject area classification
|
5458
|
+
subject_area = element.get('elementHeader', {}).get("subjectArea", "") or ""
|
5459
|
+
subj_val = ""
|
5460
|
+
if isinstance(subject_area, dict):
|
5461
|
+
subj_val = subject_area.get("classificationProperties", {}).get("subjectAreaName", "")
|
5462
|
+
for column in columns_list:
|
5463
|
+
if column.get('key') == 'subject_area':
|
5464
|
+
column['value'] = subj_val
|
5465
|
+
break
|
6205
5466
|
|
6206
|
-
|
6207
|
-
|
6208
|
-
|
6209
|
-
|
6210
|
-
|
6211
|
-
|
6212
|
-
|
6213
|
-
|
5467
|
+
# Mermaid graph
|
5468
|
+
mermaid_val = element.get('mermaidGraph', "") or ""
|
5469
|
+
for column in columns_list:
|
5470
|
+
if column.get('key') == 'mermaid':
|
5471
|
+
column['value'] = mermaid_val
|
5472
|
+
break
|
5473
|
+
|
5474
|
+
logger.trace(f"Extracted/Populated columns: {col_data}")
|
5475
|
+
|
5476
|
+
return col_data
|
6214
5477
|
|
6215
5478
|
|
6216
5479
|
def _generate_collection_output(self, elements: dict|list[dict], filter: Optional[str],
|
6217
|
-
|
5480
|
+
element_type_name: Optional[str], output_format: str = "DICT",
|
6218
5481
|
output_format_set: dict | str = None) -> str| list[dict]:
|
6219
5482
|
""" Generate output for collections in the specified format.
|
6220
5483
|
|
6221
5484
|
Args:
|
6222
5485
|
elements (Union[Dict, List[Dict]]): Dictionary or list of dictionaries containing data field elements
|
6223
5486
|
filter (Optional[str]): The search string used to find the elements
|
6224
|
-
|
5487
|
+
element_type_name (Optional[str]): The type of collection
|
6225
5488
|
output_format (str): The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
|
6226
5489
|
output_format_set (Optional[dict], optional): List of dictionaries containing column data. Defaults
|
6227
5490
|
to None.
|
@@ -6229,22 +5492,33 @@ class CollectionManager(Client2):
|
|
6229
5492
|
Returns:
|
6230
5493
|
Union[str, List[Dict]]: Formatted output as a string or list of dictionaries
|
6231
5494
|
"""
|
6232
|
-
if
|
5495
|
+
if element_type_name is None:
|
6233
5496
|
entity_type = "Collections"
|
6234
5497
|
else:
|
6235
|
-
entity_type =
|
5498
|
+
entity_type = element_type_name
|
6236
5499
|
# First see if the user has specified an output_format_set - either a label or a dict
|
5500
|
+
get_additional_props_func = None
|
6237
5501
|
if output_format_set:
|
6238
5502
|
if isinstance(output_format_set, str):
|
6239
5503
|
output_formats = select_output_format_set(output_format_set, output_format)
|
6240
|
-
|
5504
|
+
elif isinstance(output_format_set, dict):
|
6241
5505
|
output_formats = get_output_format_type_match(output_format_set, output_format)
|
6242
|
-
|
6243
|
-
|
6244
|
-
|
5506
|
+
|
5507
|
+
# If no output_format was set, then use the element_type_name to lookup the output format
|
5508
|
+
elif element_type_name:
|
5509
|
+
output_formats = select_output_format_set(element_type_name, output_format)
|
6245
5510
|
else:
|
6246
5511
|
# fallback to collections or entity type
|
6247
5512
|
output_formats = select_output_format_set(entity_type,output_format)
|
5513
|
+
if output_formats is None:
|
5514
|
+
output_formats = select_output_format_set("Default", output_format)
|
5515
|
+
|
5516
|
+
if output_formats:
|
5517
|
+
get_additional_props_name = output_formats.get("get_additional_props", {}).get("function", None)
|
5518
|
+
if isinstance(get_additional_props_name, str):
|
5519
|
+
class_name, method_name = get_additional_props_name.split(".")
|
5520
|
+
if hasattr(self, method_name):
|
5521
|
+
get_additional_props_func = getattr(self, method_name)
|
6248
5522
|
|
6249
5523
|
logger.trace(f"Executing generate_collection_output for {entity_type}: {output_formats}")
|
6250
5524
|
return generate_output(
|
@@ -6253,7 +5527,7 @@ class CollectionManager(Client2):
|
|
6253
5527
|
entity_type,
|
6254
5528
|
output_format,
|
6255
5529
|
self._extract_collection_properties,
|
6256
|
-
|
5530
|
+
get_additional_props_func,
|
6257
5531
|
output_formats,
|
6258
5532
|
)
|
6259
5533
|
|