pyegeria 5.4.0.24__py3-none-any.whl → 5.4.0.26__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. commands/cat/debug_log +7373 -1452
  2. commands/cat/dr_egeria_md.py +21 -4
  3. commands/cat/logs/pyegeria.log +4 -0
  4. md_processing/.DS_Store +0 -0
  5. md_processing/__init__.py +7 -3
  6. md_processing/data/commands.json +1683 -2801
  7. md_processing/dr_egeria_inbox/product.md +69 -20
  8. md_processing/dr_egeria_outbox/.obsidian/workspace.json +5 -5
  9. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +426 -0
  10. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +212 -0
  11. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +201 -0
  12. md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +209 -0
  13. md_processing/md_commands/governance_officer_commands.py +1 -73
  14. md_processing/md_commands/product_manager_commands.py +453 -211
  15. md_processing/md_processing_utils/common_md_proc_utils.py +60 -5
  16. md_processing/md_processing_utils/common_md_utils.py +21 -9
  17. md_processing/md_processing_utils/extraction_utils.py +2 -2
  18. md_processing/md_processing_utils/md_processing_constants.py +8 -7
  19. pyegeria/.DS_Store +0 -0
  20. pyegeria/__init__.py +4 -300
  21. pyegeria/_client_new.py +59 -11
  22. pyegeria/_output_formats.py +43 -0
  23. pyegeria/collection_manager.py +79 -14
  24. pyegeria/{data_designer_omvs.py → data_designer.py} +1171 -1675
  25. pyegeria/egeria_cat_client.py +2 -2
  26. pyegeria/egeria_client.py +4 -4
  27. pyegeria/egeria_tech_client.py +1 -1
  28. pyegeria/glossary_browser.py +1259 -0
  29. pyegeria/{glossary_manager_omvs.py → glossary_manager.py} +1181 -1099
  30. pyegeria/models.py +9 -3
  31. pyegeria/output_formatter.py +2 -1
  32. pyegeria/project_manager.py +1743 -0
  33. pyegeria/solution_architect_omvs.py +1 -1
  34. pyegeria/utils.py +4 -1
  35. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.26.dist-info}/METADATA +1 -1
  36. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.26.dist-info}/RECORD +39 -43
  37. commands/cat/debug_log.2025-08-15_09-14-07_444802.zip +0 -0
  38. commands/cat/debug_log.2025-08-16_10-21-59_388912.zip +0 -0
  39. md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  40. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +0 -2744
  41. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +0 -62
  42. md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +0 -444
  43. md_processing/dr_egeria_outbox/monday/processed-2025-08-17 21:04-product.md +0 -97
  44. pyegeria/collection_manager_omvs.py +0 -6541
  45. pyegeria/glossary_browser_omvs.py +0 -3840
  46. pyegeria/governance_officer_omvs.py +0 -2367
  47. pyegeria/project_manager_omvs.py +0 -1933
  48. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.26.dist-info}/LICENSE +0 -0
  49. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.26.dist-info}/WHEEL +0 -0
  50. {pyegeria-5.4.0.24.dist-info → pyegeria-5.4.0.26.dist-info}/entry_points.txt +0 -0
@@ -11,16 +11,27 @@ import asyncio
11
11
  import csv
12
12
  import os
13
13
  import time
14
- from datetime import datetime
15
- from typing import List
14
+ from typing import List, Annotated, Literal
16
15
 
17
- from pyegeria._client import Client
16
+ from loguru import logger
17
+ from pydantic import Field
18
+
19
+ from pyegeria._client_new import Client2
18
20
  from pyegeria._exceptions import InvalidParameterException
19
- from pyegeria._globals import NO_TERMS_FOUND
20
- from pyegeria._validators import validate_guid, validate_name
21
- from pyegeria.glossary_browser_omvs import GlossaryBrowser
21
+ from pyegeria._exceptions_new import PyegeriaInvalidParameterException
22
+ from pyegeria._globals import NO_GUID_RETURNED
23
+ from pyegeria._validators import validate_guid
24
+ from pyegeria.glossary_browser import GlossaryBrowser
25
+ from pyegeria.load_config import get_app_config
26
+ from pyegeria.models import (NewElementRequestBody,
27
+ ReferenceableProperties, UpdateElementRequestBody, DeleteRequestBody, TemplateRequestBody,
28
+ NewRelationshipRequestBody, UpdateRelationshipRequestBody, NewClassificationRequestBody)
22
29
  from pyegeria.utils import body_slimmer
23
30
 
31
+ app_settings = get_app_config()
32
+ EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
33
+
34
+
24
35
  def query_seperator(current_string):
25
36
  if current_string == "":
26
37
  return "?"
@@ -28,7 +39,8 @@ def query_seperator(current_string):
28
39
  return "&"
29
40
 
30
41
 
31
- "params are in the form of [(paramName, value), (param2Name, value)] if the value is not None, it will be added to the query string"
42
+ ("params are in the form of [(paramName, value), (param2Name, value)] if the value is not None, it will be added to "
43
+ "the query string")
32
44
 
33
45
 
34
46
  def query_string(params):
@@ -43,6 +55,23 @@ def base_path(client, view_server: str):
43
55
  return f"{client.platform_url}/servers/{view_server}/api/open-metadata/classification-manager"
44
56
 
45
57
 
58
+ class GlossaryProperties(ReferenceableProperties):
59
+ class_: Annotated[Literal["GlossaryProperties"], Field(alias="class")]
60
+ language: str = "English"
61
+ usage: str = None
62
+
63
+
64
+ class GlossaryTermProperties(ReferenceableProperties):
65
+ class_: Annotated[Literal["GlossaryTermProperties"], Field(alias="class")]
66
+ summary: str = None
67
+ description: str = None
68
+ abbreviation: str = None
69
+ examples: str = None
70
+ usage: str = None
71
+ user_defined_status: str = None
72
+ publishVersionIdentifier: str = None
73
+
74
+
46
75
  class GlossaryManager(GlossaryBrowser):
47
76
  """
48
77
  GlossaryManager is a class that extends the Client class. It provides methods to create and manage glossaries,
@@ -64,20 +93,20 @@ class GlossaryManager(GlossaryBrowser):
64
93
  """
65
94
 
66
95
  def __init__(
67
- self,
68
- view_server: str,
69
- platform_url: str,
70
- user_id: str,
71
- user_pwd: str = None,
72
- token: str = None,
73
- ):
96
+ self,
97
+ view_server: str,
98
+ platform_url: str,
99
+ user_id: str,
100
+ user_pwd: str = None,
101
+ token: str = None,
102
+ ):
74
103
  self.gl_mgr_command_root: str
75
104
  self.view_server = view_server
76
105
  self.platform_url = platform_url
77
106
  self.user_id = user_id
78
107
  self.user_pwd = user_pwd
79
108
 
80
- Client.__init__(self, view_server, platform_url, user_id, user_pwd, token)
109
+ Client2.__init__(self, view_server, platform_url, user_id, user_pwd, token)
81
110
 
82
111
  #
83
112
  # Get Valid Values for Enumerations
@@ -88,13 +117,19 @@ class GlossaryManager(GlossaryBrowser):
88
117
  recognized_term_status = self.get_glossary_term_statuses()
89
118
  return status in recognized_term_status
90
119
 
120
+ #
121
+ # Glossaries
122
+ #
123
+
91
124
  async def _async_create_glossary(
92
- self,
93
- display_name: str,
94
- description: str,
95
- language: str = "English",
96
- usage: str = None,
97
- ) -> str:
125
+ self,
126
+ display_name: str,
127
+ description: str,
128
+ language: str = "English",
129
+ usage: str = None,
130
+ initial_classifications: list = None,
131
+ body: dict | NewElementRequestBody = None,
132
+ ) -> str:
98
133
  """Create a new glossary. Async version.
99
134
 
100
135
  Parameters
@@ -117,27 +152,53 @@ class GlossaryManager(GlossaryBrowser):
117
152
  """
118
153
 
119
154
  url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries"
120
- body = {
121
- "class": "ReferenceableRequestBody",
122
- "elementProperties": {
123
- "class": "GlossaryProperties",
124
- "qualifiedName": self.__create_qualified_name__("Glossary", display_name),
125
- "displayName": display_name,
126
- "description": description,
127
- "language": language,
128
- "usage": usage,
129
- },
130
- }
131
- response = await self._async_make_request("POST", url, body_slimmer(body))
132
- return response.json().get("guid", None)
155
+ if body:
156
+ validated_body = self.validate_new_element_request(body, "GlossaryProperties")
157
+ elif (body is None) and (display_name is not None):
158
+ pre = initial_classifications[0] if initial_classifications is not None else "Glossary"
159
+ qualified_name = self.__create_qualified_name__(pre, display_name, EGERIA_LOCAL_QUALIFIER)
160
+ if initial_classifications:
161
+ initial_classifications_dict = {}
162
+ for c in initial_classifications:
163
+ initial_classifications_dict = initial_classifications_dict | {
164
+ c: {"class": "ClassificationProperties"}
165
+ }
166
+
167
+ else:
168
+ initial_classifications_dict = None
169
+
170
+ glossary_properties = GlossaryProperties(class_="GlossaryProperties",
171
+ qualified_name=qualified_name,
172
+ display_name=display_name,
173
+ description=description,
174
+ language=language,
175
+ usage=usage
176
+ )
177
+ body = {
178
+ "class": "NewElementRequestBody",
179
+ "isOwnAnchor": True,
180
+ "initialClassifications": initial_classifications_dict,
181
+ "properties": glossary_properties.model_dump()
182
+ }
183
+ validated_body = NewElementRequestBody.model_validate(body)
184
+ else:
185
+ raise PyegeriaInvalidParameterException(additional_info={"reason": "Invalid input parameters"})
186
+
187
+ json_body = validated_body.model_dump_json(indent=2, exclude_none=True)
188
+ logger.info(json_body)
189
+ resp = await self._async_make_request("POST", url, json_body, is_json=True)
190
+ logger.info(f"Create glossary with GUID: {resp.json().get('guid')}")
191
+ return resp.json().get("guid", NO_GUID_RETURNED)
133
192
 
134
193
  def create_glossary(
135
- self,
136
- display_name: str,
137
- description: str,
138
- language: str = "English",
139
- usage: str = None,
140
- ) -> str:
194
+ self,
195
+ display_name: str,
196
+ description: str,
197
+ language: str = "English",
198
+ usage: str = None,
199
+ initial_classifications: list = None,
200
+ body: dict | NewElementRequestBody = None
201
+ ) -> str:
141
202
  """Create a new glossary.
142
203
 
143
204
  Parameters
@@ -160,11 +221,13 @@ class GlossaryManager(GlossaryBrowser):
160
221
  """
161
222
  loop = asyncio.get_event_loop()
162
223
  response = loop.run_until_complete(
163
- self._async_create_glossary(display_name, description, language, usage)
164
- )
224
+ self._async_create_glossary(display_name, description, language, usage,
225
+ initial_classifications, body)
226
+ )
165
227
  return response
166
228
 
167
- async def _async_delete_glossary(self, glossary_guid: str, cascade:bool = False) -> None:
229
+ async def _async_delete_glossary(self, glossary_guid: str, body: dict | DeleteRequestBody = None,
230
+ cascade: bool = False) -> None:
168
231
  """Delete glossary. Async version.
169
232
 
170
233
  Parameters
@@ -179,15 +242,16 @@ class GlossaryManager(GlossaryBrowser):
179
242
  None
180
243
 
181
244
  """
182
- cascade_str = str(cascade).lower()
245
+
183
246
  url = (
184
247
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
185
- f"{glossary_guid}/remove?cascadedDelete={cascade_str}"
248
+ f"{glossary_guid}/delete"
186
249
  )
187
250
 
188
- await self._async_make_request("POST", url)
251
+ await self._async_delete_request(url, body, cascade)
252
+ logger.info(f"Deleted collection {glossary_guid} with cascade {cascade}")
189
253
 
190
- def delete_glossary(self, glossary_guid: str, cascade: bool = False) -> None:
254
+ def delete_glossary(self, glossary_guid: str, body: dict | DeleteRequestBody = None, cascade: bool = False) -> None:
191
255
  """Delete a new glossary.
192
256
 
193
257
  Parameters
@@ -204,16 +268,13 @@ class GlossaryManager(GlossaryBrowser):
204
268
 
205
269
  """
206
270
  loop = asyncio.get_event_loop()
207
- loop.run_until_complete(self._async_delete_glossary(glossary_guid, cascade))
271
+ loop.run_until_complete(self._async_delete_glossary(glossary_guid, body, cascade))
208
272
 
209
273
  async def _async_update_glossary(
210
- self,
211
- glossary_guid: str,
212
- body: dict,
213
- is_merge_update: bool = True,
214
- for_lineage: bool = False,
215
- for_duplicate_processing: bool = False,
216
- ) -> None:
274
+ self,
275
+ glossary_guid: str,
276
+ body: dict | UpdateElementRequestBody
277
+ ) -> None:
217
278
  """Update Glossary.
218
279
 
219
280
  Async version.
@@ -224,14 +285,6 @@ class GlossaryManager(GlossaryBrowser):
224
285
  The ID of the glossary to update.
225
286
  body: dict
226
287
  A dict containing the properties to update.
227
- is_merge_update: bool, optional, default = True
228
- If true, then only those properties specified in the body will be updated. If false, then all the
229
- properties of the glossary will be replaced with those of the body.
230
- for_lineage: bool, optional, default = False
231
- Normally false. Used when we want to retrieve elements that have been delete but have a Memento entry.
232
- for_duplicate_processing: bool, optional, default = False
233
- Normally false. Set true when Egeria is told to skip deduplication because another system will do it.
234
-
235
288
 
236
289
  Returns
237
290
  -------
@@ -242,34 +295,21 @@ class GlossaryManager(GlossaryBrowser):
242
295
 
243
296
  Sample body:
244
297
 
245
- {
246
- "class" : "ReferenceableRequestBody",
247
- "elementProperties" :
248
- {
249
- "class" : "GlossaryProperties",
250
- "qualifiedName" : "MyGlossary",
251
- "displayName" : "My Glossary",
252
- "description" : "This is an example glossary"
253
- }
254
- }
255
298
  """
256
299
 
257
300
  url = (
258
301
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
259
- f"{glossary_guid}/update?isMergeUpdate={is_merge_update}&forLineage={for_lineage}&"
260
- f"forDuplicateProcessing={for_duplicate_processing}"
302
+ f"{glossary_guid}/update"
261
303
  )
262
304
 
263
- await self._async_make_request("POST", url, body_slimmer(body))
305
+ await self._async_update_element_body_request(url, ["GlossaryProperties"], body)
306
+ logger.info(f"Updated digital subscription {glossary_guid}")
264
307
 
265
308
  def update_glossary(
266
- self,
267
- glossary_guid: str,
268
- body: dict,
269
- is_merge_update: bool = True,
270
- for_lineage: bool = False,
271
- for_duplicate_processing: bool = False,
272
- ) -> None:
309
+ self,
310
+ glossary_guid: str,
311
+ body: dict | UpdateElementRequestBody
312
+ ) -> None:
273
313
  """Update Glossary.
274
314
 
275
315
  Parameters
@@ -296,475 +336,29 @@ class GlossaryManager(GlossaryBrowser):
296
336
 
297
337
  Sample body:
298
338
 
299
- {
300
- "class" : "ReferenceableRequestBody",
301
- "elementProperties" :
302
- {
303
- "class" : "GlossaryProperties",
304
- "qualifiedName" : "MyGlossary",
305
- "displayName" : "My Glossary",
306
- "description" : "This is an example glossary"
307
- }
308
- }
339
+
309
340
  """
310
341
  loop = asyncio.get_event_loop()
311
342
  loop.run_until_complete(
312
343
  self._async_update_glossary(
313
344
  glossary_guid,
314
- body,
315
- is_merge_update,
316
- for_lineage,
317
- for_duplicate_processing,
345
+ body
346
+ )
318
347
  )
319
- )
320
-
321
- #
322
- # Glossaries
323
- #
324
-
325
-
326
-
327
348
 
328
349
  #
329
- # Glossary Categories
330
- #
331
- async def _async_create_category(
332
- self,
333
- glossary_guid: str,
334
- display_name: str,
335
- description: str,
336
- is_root_category: bool = False,
337
- ) -> str:
338
- """Create a new category within the specified glossary. Async Version.
339
-
340
- Parameters
341
- ----------
342
- glossary_guid: str,
343
- Unique identifier for the glossary.
344
- display_name: str,
345
- Display name for the glossary category. Will be used as the base for a constructed unique qualified name.
346
- description: str,
347
- Description for the category.
348
- is_root_category: bool, [default=False], optional
349
- Is this category a root category?
350
-
351
-
352
- Returns
353
- -------
354
- A string with the GUID of the new category..
355
-
356
- Raises
357
- ------
358
-
359
- InvalidParameterException
360
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
361
- PropertyServerException
362
- Raised by the server when an issue arises in processing a valid request
363
- NotAuthorizedException
364
- The principle specified by the user_id does not have authorization for the requested action
365
- ConfigurationErrorException
366
- Raised when configuration parameters passed on earlier calls turn out to be
367
- invalid or make the new call invalid.
368
- """
369
-
370
- url = (
371
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
372
- f"{glossary_guid}/categories?isRootCategory={is_root_category}"
373
- )
374
- body = {
375
- "class": "ReferenceableRequestBody",
376
- "elementProperties": {
377
- "class": "GlossaryCategoryProperties",
378
- "qualifiedName": self.__create_qualified_name__("Category", display_name),
379
- "displayName": display_name,
380
- "description": description,
381
- },
382
- }
383
- response = await self._async_make_request("POST", url, body)
384
- return response.json().get("guid", None)
385
-
386
- def create_category(
387
- self,
388
- glossary_guid: str,
389
- display_name: str,
390
- description: str,
391
- is_root_category: bool = False,
392
- ) -> str:
393
- """Create a new category within the specified glossary.
394
-
395
- Parameters
396
- ----------
397
- glossary_guid: str,
398
- Unique identifier for the glossary.
399
- display_name: str,
400
- Display name for the glossary category. Will be used as the base for a constructed unique qualified name.
401
- description: str,
402
- Description for the category.
403
- is_root_category: bool, [default=False], optional
404
- Is this category a root category?
405
-
406
- Returns
407
- -------
408
- A string with the GUID of the new category..
409
-
410
- Raises
411
- ------
412
-
413
- InvalidParameterException
414
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
415
- PropertyServerException
416
- Raised by the server when an issue arises in processing a valid request
417
- NotAuthorizedException
418
- The principle specified by the user_id does not have authorization for the requested action
419
- ConfigurationErrorException
420
- Raised when configuration parameters passed on earlier calls turn out to be
421
- invalid or make the new call invalid.
422
- """
423
- loop = asyncio.get_event_loop()
424
- response = loop.run_until_complete(
425
- self._async_create_category(glossary_guid, display_name, description, is_root_category)
426
- )
427
- return response
428
-
429
- async def _async_update_category(
430
- self,
431
- category_guid: str,
432
- display_name: str,
433
- description: str,
434
- qualified_name: str = None,
435
- effective_time: str = None,
436
- update_description: str = None,
437
- is_merge_update: bool = True,
438
- ) :
439
- """Create a new category within the specified glossary. Async Version.
440
-
441
- Parameters
442
- ----------
443
- category_guid: str,
444
- Unique identifier for the glossary.
445
- display_name: str,
446
- Display name for the glossary category. Will be used as the base for a constructed unique qualified name.
447
- description: str,
448
- Description for the category.
449
- qualified_name: str, [default=None], optional
450
- Unique identifier for the glossary category. Must be specified if not a merge update.
451
- effective_time: datetime, [default=None], optional
452
- Time when the category becomes effective.
453
- update_description: str, [default=None], optional
454
- Description of the update to the category.
455
- is_merge_update: bool, [default=True], optional
456
- Should this be a merge or a replace?
457
-
458
-
459
- Returns
460
- -------
461
- None
462
-
463
- Raises
464
- ------
465
-
466
- InvalidParameterException
467
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
468
- PropertyServerException
469
- Raised by the server when an issue arises in processing a valid request
470
- NotAuthorizedException
471
- The principle specified by the user_id does not have authorization for the requested action
472
- ConfigurationErrorException
473
- Raised when configuration parameters passed on earlier calls turn out to be
474
- invalid or make the new call invalid.
475
- """
476
- if (not is_merge_update and qualified_name is None):
477
- raise ValueError('qualified_name must be specified for a replace update')
478
- url = (
479
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
480
- f"categories/{category_guid}/update?isMergeUpdate={is_merge_update}"
481
- )
482
- body = {
483
- "class": "ReferenceableUpdateRequestBody",
484
- "effectiveTime": effective_time,
485
- "updateDescription": update_description,
486
- "elementProperties": {
487
- "class": "GlossaryCategoryProperties",
488
- "qualifiedName": qualified_name ,
489
- "displayName": display_name,
490
- "description": description
491
- },
492
- }
493
- response = await self._async_make_request("POST", url, body_slimmer(body))
494
- return response.json().get("guid", None)
495
-
496
- def update_category(
497
- self,
498
- glossary_guid: str,
499
- display_name: str,
500
- description: str,
501
- qualified_name: str = None,
502
- effective_time: str = None,
503
- update_description: str = None,
504
- is_merge_update: bool = True,
505
- ) -> str:
506
- """Create a new category within the specified glossary.
507
-
508
- Parameters
509
- ----------
510
- glossary_guid: str,
511
- Unique identifier for the glossary.
512
- display_name: str,
513
- Display name for the glossary category. Will be used as the base for a constructed unique qualified name.
514
- description: str,
515
- Description for the category.
516
- qualified_name: str, [default=None], optional
517
- Unique identifier for the glossary category. Must be specified if not a merge update.
518
- effective_time: datetime, [default=None], optional
519
- Time when the category becomes effective.
520
- update_description: str, [default=None], optional
521
- Description of the update to the category.
522
- is_merge_update: bool, [default=True], optional
523
- Should this be a merge or a replace?
524
-
525
-
526
- Returns
527
- -------
528
- None
529
-
530
- Raises
531
- ------
532
-
533
- InvalidParameterException
534
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
535
- PropertyServerException
536
- Raised by the server when an issue arises in processing a valid request
537
- NotAuthorizedException
538
- The principle specified by the user_id does not have authorization for the requested action
539
- ConfigurationErrorException
540
- Raised when configuration parameters passed on earlier calls turn out to be
541
- invalid or make the new call invalid.
542
- """
543
- loop = asyncio.get_event_loop()
544
- response = loop.run_until_complete(
545
- self._async_update_category(glossary_guid, display_name, description,
546
- qualified_name, effective_time, update_description, is_merge_update)
547
- )
548
- return response
549
-
550
-
551
- async def _async_delete_category(
552
- self,
553
- category_guid: str,
554
- ) -> None:
555
- """Delete a category. Async Version.
556
-
557
- Parameters
558
- ----------
559
- category_guid: str,
560
- Unique identifier for the category.
561
-
562
- Returns
563
- -------
564
- None
565
-
566
- Raises
567
- ------
568
-
569
- InvalidParameterException
570
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
571
- PropertyServerException
572
- Raised by the server when an issue arises in processing a valid request
573
- NotAuthorizedException
574
- The principle specified by the user_id does not have authorization for the requested action
575
- ConfigurationErrorException
576
- Raised when configuration parameters passed on earlier calls turn out to be
577
- invalid or make the new call invalid.
578
- """
579
-
580
- url = (
581
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
582
- f"categories/{category_guid}/remove"
583
- )
584
-
585
- await self._async_make_request("POST", url)
586
-
587
-
588
- def delete_category(
589
- self,
590
- category_guid: str,
591
- ) -> None:
592
- """Delete a category.
593
-
594
- Parameters
595
- ----------
596
- category_guid: str,
597
- Unique identifier for the category.
598
-
599
- Returns
600
- -------
601
- None
602
-
603
- Raises
604
- ------
605
-
606
- InvalidParameterException
607
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
608
- PropertyServerException
609
- Raised by the server when an issue arises in processing a valid request
610
- NotAuthorizedException
611
- The principle specified by the user_id does not have authorization for the requested action
612
- ConfigurationErrorException
613
- Raised when configuration parameters passed on earlier calls turn out to be
614
- invalid or make the new call invalid.
615
- """
616
- loop = asyncio.get_event_loop()
617
- loop.run_until_complete(
618
- self._async_delete_category(category_guid)
619
- )
620
-
621
- async def _async_set_parent_category(
622
- self,
623
- parent_category_guid: str, child_category_guid: str) -> None:
624
- """Set parent category Async Version.
625
-
626
- Parameters
627
- ----------
628
- parent_category_guid: str,
629
- Unique identifier for the parent category.
630
- child_category_guid: str,
631
- Unique identifier for the child category.
632
-
633
- Returns
634
- -------
635
- None
636
-
637
- Raises
638
- ------
639
-
640
- InvalidParameterException
641
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
642
- PropertyServerException
643
- Raised by the server when an issue arises in processing a valid request
644
- NotAuthorizedException
645
- The principle specified by the user_id does not have authorization for the requested action
646
- ConfigurationErrorException
647
- Raised when configuration parameters passed on earlier calls turn out to be
648
- invalid or make the new call invalid.
649
- """
650
-
651
- url = (
652
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
653
- f"categories/{parent_category_guid}/subcategories/{child_category_guid}"
654
- )
655
-
656
- await self._async_make_request("POST", url)
657
-
658
- def set_parent_category(self, parent_category_guid: str, child_category_guid: str) -> None:
659
- """Set parent category
660
-
661
- Parameters
662
- ----------
663
- parent_category_guid: str,
664
- Unique identifier for the parent category.
665
- child_category_guid: str,
666
- Unique identifier for the child category.
667
-
668
- Returns
669
- -------
670
- None
671
-
672
- Raises
673
- ------
674
-
675
- InvalidParameterException
676
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
677
- PropertyServerException
678
- Raised by the server when an issue arises in processing a valid request
679
- NotAuthorizedException
680
- The principle specified by the user_id does not have authorization for the requested action
681
- ConfigurationErrorException
682
- Raised when configuration parameters passed on earlier calls turn out to be
683
- invalid or make the new call invalid.
684
- """
685
-
686
- loop = asyncio.get_event_loop()
687
- loop.run_until_complete(
688
- self._async_set_parent_category(parent_category_guid,child_category_guid)
689
- )
690
-
691
- async def _async_remove_parent_category(
692
- self,
693
- parent_category_guid: str, child_category_guid: str) -> None:
694
- """Remove parent category relationship. Async Version.
695
-
696
- Parameters
697
- ----------
698
- parent_category_guid: str,
699
- Unique identifier for the parent category.
700
- child_category_guid: str,
701
- Unique identifier for the child category.
702
-
703
- Returns
704
- -------
705
- None
706
-
707
- Raises
708
- ------
709
-
710
- InvalidParameterException
711
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
712
- PropertyServerException
713
- Raised by the server when an issue arises in processing a valid request
714
- NotAuthorizedException
715
- The principle specified by the user_id does not have authorization for the requested action
716
- ConfigurationErrorException
717
- Raised when configuration parameters passed on earlier calls turn out to be
718
- invalid or make the new call invalid.
719
- """
720
-
721
- url = (
722
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
723
- f"categories/{parent_category_guid}/subcategories/{child_category_guid}/remove"
724
- )
725
-
726
- await self._async_make_request("POST", url)
727
-
728
- def remove_parent_category(self, parent_category_guid: str, child_category_guid: str) -> None:
729
- """Remove parent category relationship.
730
-
731
- Parameters
732
- ----------
733
- parent_category_guid: str,
734
- Unique identifier for the parent category.
735
- child_category_guid: str,
736
- Unique identifier for the child category.
350
+ # add glossary classifications? is-canonical, is editing, is staging, is taxonomy?
351
+ # Not all show up in UML
737
352
 
738
- Returns
739
- -------
740
- None
741
-
742
- Raises
743
- ------
744
-
745
- InvalidParameterException
746
- If the client passes incorrect parameters on the request - such as bad URLs or invalid values
747
- PropertyServerException
748
- Raised by the server when an issue arises in processing a valid request
749
- NotAuthorizedException
750
- The principle specified by the user_id does not have authorization for the requested action
751
- ConfigurationErrorException
752
- Raised when configuration parameters passed on earlier calls turn out to be
753
- invalid or make the new call invalid.
754
- """
755
353
 
756
- loop = asyncio.get_event_loop()
757
- loop.run_until_complete(
758
- self._async_remove_parent_category(parent_category_guid, child_category_guid)
759
- )
760
354
 
761
355
  #
762
356
  # Terms
763
357
  #
764
- async def _async_create_controlled_glossary_term(
765
- self, glossary_guid: str, body: dict
766
- ) -> str:
767
- """Create a term for a controlled glossary.
358
+ async def _async_create_glossary_term(
359
+ self, body: dict | NewElementRequestBody
360
+ ) -> str:
361
+ """Create a term for a glossary.
768
362
  See also: https://egeria-project.org/types/3/0385-Controlled-Glossary-Development/?h=controlled
769
363
  The request body also supports the specification of an effective time for the query.
770
364
 
@@ -772,10 +366,8 @@ class GlossaryManager(GlossaryBrowser):
772
366
 
773
367
  Parameters
774
368
  ----------
775
- glossary_guid : str
776
- Unique identifier for the glossary category to retrieve terms from.
777
- body: dict
778
- The dictionary to create te controlled glossary term for. Example below.
369
+ body: dict | NewElementRequestBody
370
+ The dictionary to create glossary term for. Example below.
779
371
 
780
372
 
781
373
  Returns
@@ -796,19 +388,25 @@ class GlossaryManager(GlossaryBrowser):
796
388
 
797
389
  Sample body like:
798
390
  {
799
- "class" : "ReferenceableRequestBody",
800
- "elementProperties" :
391
+ "class" : "NewElementRequestBody",
392
+ "parentGUID" : "Glossary GUID here",
393
+ "isOwnAnchor" : true,
394
+ "anchorScopeGUID" : "Glossary GUID here",
395
+ "parentRelationshipTypeName" : "ParentGlossary",
396
+ "parentAtEnd1": true,
397
+ "properties" :
801
398
  {
802
399
  "class" : "GlossaryTermProperties",
803
- "qualifiedName" : "GlossaryTerm: term name : {$isoTimestamp}",
400
+ "qualifiedName" : "GlossaryTerm::term name",
804
401
  "displayName" : "term name",
805
402
  "aliases": []
806
403
  "summary" : "This is the short description.",
807
404
  "description" : "This is the long description of the term.",
808
- "abbreviation" : "GT",
405
+ "abbreviation" : "aabrev",
809
406
  "examples" : "Add examples and descriptions here.",
810
407
  "usage" : "This is how the concept described by the glossary term is used.",
811
- "publishVersionIdentifier" : "V1.0",
408
+ "versionIdentifier" : "V1.0",
409
+ "category" : "A user defined category",
812
410
  "additionalProperties" :
813
411
  {
814
412
  "propertyName1" : "xxxx",
@@ -820,30 +418,21 @@ class GlossaryManager(GlossaryBrowser):
820
418
 
821
419
  """
822
420
 
823
- validate_guid(glossary_guid)
824
- if self.__validate_term_status__(body["initialStatus"]) is False:
825
- raise InvalidParameterException("Bad status value")
826
-
827
421
  url = (
828
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
829
- f"{glossary_guid}/terms/new-controlled"
422
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms"
830
423
  )
424
+ return await self._async_create_element_body_request(url, "GlossaryTermProperties", body)
831
425
 
832
- response = await self._async_make_request("POST", url, body)
833
-
834
- return response.json().get("guid", "Term not created")
835
-
836
- def create_controlled_glossary_term(self, glossary_guid: str, body: dict) -> str:
426
+ def create_glossary_term(self, body: dict | NewElementRequestBody) -> str:
837
427
  """Create a term for a controlled glossary.
838
428
  See also: https://egeria-project.org/types/3/0385-Controlled-Glossary-Development/?h=controlled
839
429
  The request body also supports the specification of an effective time for the query.
840
430
 
841
431
  Parameters
842
432
  ----------
843
- glossary_guid : str
844
- Unique identifier for the glossary category to retrieve terms from.
433
+
845
434
  body: dict
846
- The dictionary to create te controlled glossary term for. Example below.
435
+ The dictionary to create glossary term for. Example below.
847
436
 
848
437
 
849
438
  Returns
@@ -863,20 +452,26 @@ class GlossaryManager(GlossaryBrowser):
863
452
  -----
864
453
 
865
454
  Sample body like:
866
- {
867
- "class" : "ReferenceableRequestBody",
868
- "elementProperties" :
455
+ {
456
+ "class" : "NewElementRequestBody",
457
+ "parentGUID" : "Glossary GUID here",
458
+ "isOwnAnchor" : true,
459
+ "anchorScopeGUID" : "Glossary GUID here",
460
+ "parentRelationshipTypeName" : "ParentGlossary",
461
+ "parentAtEnd1": true,
462
+ "properties" :
869
463
  {
870
464
  "class" : "GlossaryTermProperties",
871
- "qualifiedName" : "GlossaryTerm: term name : {$isoTimestamp}",
465
+ "qualifiedName" : "GlossaryTerm::term name",
872
466
  "displayName" : "term name",
873
467
  "aliases": []
874
468
  "summary" : "This is the short description.",
875
469
  "description" : "This is the long description of the term.",
876
- "abbreviation" : "GT",
470
+ "abbreviation" : "aabrev",
877
471
  "examples" : "Add examples and descriptions here.",
878
472
  "usage" : "This is how the concept described by the glossary term is used.",
879
- "publishVersionIdentifier" : "V1.0",
473
+ "versionIdentifier" : "V1.0",
474
+ "category" : "A user defined category",
880
475
  "additionalProperties" :
881
476
  {
882
477
  "propertyName1" : "xxxx",
@@ -889,19 +484,19 @@ class GlossaryManager(GlossaryBrowser):
889
484
  """
890
485
  loop = asyncio.get_event_loop()
891
486
  response = loop.run_until_complete(
892
- self._async_create_controlled_glossary_term(glossary_guid, body)
893
- )
487
+ self._async_create_glossary_term(body)
488
+ )
894
489
 
895
490
  return response
896
491
 
897
492
  def load_terms_from_csv_file(
898
- self,
899
- glossary_name: str,
900
- filename: str,
901
- file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
902
- upsert: bool = True,
903
- verbose: bool = True,
904
- ) -> List[dict] | None:
493
+ self,
494
+ glossary_name: str,
495
+ filename: str,
496
+ file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
497
+ upsert: bool = True,
498
+ verbose: bool = True,
499
+ ) -> List[dict] | None:
905
500
  """This method loads glossary terms into the specified glossary from the indicated file.
906
501
 
907
502
  Parameters
@@ -975,7 +570,7 @@ class GlossaryManager(GlossaryBrowser):
975
570
  "Usage",
976
571
  "Version Identifier",
977
572
  "Status",
978
- }
573
+ }
979
574
 
980
575
  if file_path:
981
576
  full_file_path = os.path.join(file_path, filename)
@@ -985,7 +580,7 @@ class GlossaryManager(GlossaryBrowser):
985
580
  if not os.path.isfile(full_file_path):
986
581
  raise FileNotFoundError(
987
582
  f"Did not find file with path {file_path} and name {filename}"
988
- )
583
+ )
989
584
  # process file
990
585
  with open(full_file_path, mode="r") as file:
991
586
  # Create a CSV reader object
@@ -1007,8 +602,8 @@ class GlossaryManager(GlossaryBrowser):
1007
602
  "qualified_name": "---",
1008
603
  "term_guid": "---",
1009
604
  "error": "missing or invalid term names - skipping",
1010
- }
1011
- )
605
+ }
606
+ )
1012
607
  continue
1013
608
  qualified_name = row.get("Qualified Name", None)
1014
609
  abbrev_in = row.get("Abbreviation", None)
@@ -1035,8 +630,8 @@ class GlossaryManager(GlossaryBrowser):
1035
630
  "qualified_name": "---",
1036
631
  "term_guid": "---",
1037
632
  "error": "invalid term status",
1038
- }
1039
- )
633
+ }
634
+ )
1040
635
  continue
1041
636
 
1042
637
  if upsert:
@@ -1045,7 +640,7 @@ class GlossaryManager(GlossaryBrowser):
1045
640
  if qualified_name:
1046
641
  term_stuff = self.get_terms_by_name(
1047
642
  qualified_name, glossary_guid
1048
- )
643
+ )
1049
644
  if type(term_stuff) is str:
1050
645
  # An existing term was not found with that qualified name
1051
646
  term_info.append(
@@ -1053,8 +648,8 @@ class GlossaryManager(GlossaryBrowser):
1053
648
  "term_name": term_name,
1054
649
  "qualified_name": qualified_name,
1055
650
  "error": "Matching term not found - skipping",
1056
- }
1057
- )
651
+ }
652
+ )
1058
653
  continue
1059
654
  elif len(term_stuff) > 1:
1060
655
  term_info.append(
@@ -1062,8 +657,8 @@ class GlossaryManager(GlossaryBrowser):
1062
657
  "term_name": term_name,
1063
658
  "qualified_name": qualified_name,
1064
659
  "error": "Multiple matching terms - skipping",
1065
- }
1066
- )
660
+ }
661
+ )
1067
662
  continue
1068
663
  else:
1069
664
  # An existing term was found - so update it! Get the existing values and overlay
@@ -1081,21 +676,21 @@ class GlossaryManager(GlossaryBrowser):
1081
676
  "examples": examples,
1082
677
  "usage": usage,
1083
678
  "publishVersionIdentifier": version,
1084
- },
679
+ },
1085
680
  "updateDescription": "Update from file import via upsert",
1086
- }
681
+ }
1087
682
  term_guid = term_stuff[0]["elementHeader"]["guid"]
1088
683
  self.update_term(
1089
684
  term_guid, body_slimmer(body), is_merge_update=True
1090
- )
685
+ )
1091
686
  term_info.append(
1092
687
  {
1093
688
  "term_name": term_name,
1094
689
  "qualified_name": qualified_name,
1095
690
  "term_guid": term_guid,
1096
691
  "updated": "the term was updated",
1097
- }
1098
- )
692
+ }
693
+ )
1099
694
  continue
1100
695
 
1101
696
  # Add the term
@@ -1113,32 +708,32 @@ class GlossaryManager(GlossaryBrowser):
1113
708
  "examples": examples,
1114
709
  "usage": usage,
1115
710
  "publishVersionIdentifier": version,
1116
- },
711
+ },
1117
712
  "initialStatus": status,
1118
- }
713
+ }
1119
714
 
1120
715
  # Add the term
1121
716
  term_guid = self.create_controlled_glossary_term(
1122
717
  glossary_guid, body_slimmer(body)
1123
- )
718
+ )
1124
719
  term_info.append(
1125
720
  {
1126
721
  "term_name": term_name,
1127
722
  "qualified_name": term_qualified_name,
1128
723
  "term_guid": term_guid,
1129
- }
1130
- )
724
+ }
725
+ )
1131
726
  if verbose:
1132
727
  return term_info
1133
728
  else:
1134
729
  return
1135
730
 
1136
731
  async def _async_export_glossary_to_csv(
1137
- self,
1138
- glossary_guid: str,
1139
- target_file: str,
1140
- file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
1141
- ) -> int:
732
+ self,
733
+ glossary_guid: str,
734
+ target_file: str,
735
+ file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
736
+ ) -> int:
1142
737
  """Export all the terms in a glossary to a CSV file. Async version
1143
738
 
1144
739
  Parameters:
@@ -1167,7 +762,7 @@ class GlossaryManager(GlossaryBrowser):
1167
762
  "Usage",
1168
763
  "Version Identifier",
1169
764
  "Status",
1170
- ]
765
+ ]
1171
766
  if file_path:
1172
767
  full_file_path = os.path.join(file_path, target_file)
1173
768
  else:
@@ -1187,7 +782,7 @@ class GlossaryManager(GlossaryBrowser):
1187
782
  usage = term["glossaryTermProperties"].get("usage", "---")
1188
783
  version = term["glossaryTermProperties"].get(
1189
784
  "publishVersionIdentifier", "---"
1190
- )
785
+ )
1191
786
  status = term["elementHeader"]["status"]
1192
787
 
1193
788
  csv_writer.writerow(
@@ -1201,18 +796,18 @@ class GlossaryManager(GlossaryBrowser):
1201
796
  "Usage": usage,
1202
797
  "Version Identifier": version,
1203
798
  "Status": status,
1204
- }
1205
- )
799
+ }
800
+ )
1206
801
 
1207
802
  count += 1
1208
803
  return count
1209
804
 
1210
805
  def export_glossary_to_csv(
1211
- self,
1212
- glossary_guid: str,
1213
- target_file: str,
1214
- file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
1215
- ) -> int:
806
+ self,
807
+ glossary_guid: str,
808
+ target_file: str,
809
+ file_path: str = os.environ.get("EGERIA_GLOSSARY_PATH", None),
810
+ ) -> int:
1216
811
  """Export all the terms in a glossary to a CSV file.
1217
812
 
1218
813
  Parameters:
@@ -1232,18 +827,19 @@ class GlossaryManager(GlossaryBrowser):
1232
827
  loop = asyncio.get_event_loop()
1233
828
  response = loop.run_until_complete(
1234
829
  self._async_export_glossary_to_csv(glossary_guid, target_file, file_path)
1235
- )
830
+ )
1236
831
 
1237
832
  return response
1238
833
 
1239
834
  async def _async_create_term_copy(
1240
- self,
1241
- glossary_guid: str,
1242
- glossary_term_guid: str,
1243
- new_display_name: str,
1244
- version_id: str,
1245
- term_status: str = "PROPOSED",
1246
- ) -> str:
835
+ self,
836
+ glossary_guid: str,
837
+ glossary_term_guid: str,
838
+ new_display_name: str,
839
+ version_id: str = None,
840
+ term_status: str = "PROPOSED",
841
+ body: dict | TemplateRequestBody = None,
842
+ ) -> str:
1247
843
  """Create a new term from an existing term.
1248
844
 
1249
845
  Async Version.
@@ -1254,7 +850,7 @@ class GlossaryManager(GlossaryBrowser):
1254
850
  Unique identifier for the glossary category to retrieve terms from.
1255
851
  glossary_term_guid: str
1256
852
  Unique identifier for the source glossary term.
1257
- new_display_named: str
853
+ new_display_name: str
1258
854
  The display name of the new term.
1259
855
  version_id: str
1260
856
  The version identifier of the new term.
@@ -1280,37 +876,66 @@ class GlossaryManager(GlossaryBrowser):
1280
876
 
1281
877
  """
1282
878
 
1283
- validate_guid(glossary_guid)
1284
- validate_guid(glossary_term_guid)
879
+ if isinstance(body, TemplateRequestBody):
880
+ validated_body = body
881
+
882
+ elif isinstance(body, dict):
883
+ validated_body = self._template_request_adapter.validate_python(body)
884
+ else:
885
+ qualified_name = self.__create_qualified_name__("Term", new_display_name, EGERIA_LOCAL_QUALIFIER)
886
+ body = {
887
+ "class" : "TemplateRequestBody",
888
+ "templateGUID": glossary_term_guid,
889
+ "replacementProperties": {
890
+ "class": "ElementProperties",
891
+ "propertyValueMap": {
892
+ "qualifiedName": {
893
+ "class": "PrimitiveTypePropertyValue",
894
+ "typeName": "string",
895
+ "primitiveValue": qualified_name,
896
+ },
897
+
898
+ "displayName": {
899
+ "class": "PrimitiveTypePropertyValue",
900
+ "typeName": "string",
901
+ "primitiveValue": new_display_name,
902
+ },
903
+
904
+ # "publishVersionIdentifier": {
905
+ # "class": "PrimitiveTypePropertyValue",
906
+ # "typeName": "string",
907
+ # "primitiveValue": version_id,
908
+ # },
909
+
910
+ }
911
+ },
912
+ "initialStatus": term_status,
913
+ }
914
+ validated_body = self._template_request_adapter.validate_python(body)
915
+
916
+ v_body = body_slimmer(validated_body.model_dump(exclude_none=True))
917
+ logger.info(v_body)
918
+
1285
919
 
1286
920
  url = (
1287
921
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1288
- f"{glossary_guid}/terms/from-template/{glossary_term_guid}"
922
+ f"terms/from-template/{glossary_term_guid}"
1289
923
  )
1290
924
 
1291
- body = {
1292
- "class": "GlossaryTemplateRequestBody",
1293
- "elementProperties": {
1294
- "class": "TemplateProperties",
1295
- "qualifiedName": f"Term-{new_display_name}-{time.asctime()}",
1296
- "displayName": new_display_name,
1297
- "versionIdentifier": version_id,
1298
- },
1299
- "glossaryTermStatus": term_status,
1300
- }
1301
-
1302
- response = await self._async_make_request("POST", url, body)
1303
-
1304
- return response.json().get("guid", "Term not created")
925
+ resp = await self._async_make_request("POST", url, v_body)
926
+ guid = resp.json().get("guid", NO_GUID_RETURNED)
927
+ logger.info(f"Create Term from template with GUID: {guid}")
928
+ return guid
1305
929
 
1306
930
  def create_term_copy(
1307
- self,
1308
- glossary_guid: str,
1309
- glossary_term_guid: str,
1310
- new_display_name: str,
1311
- version_id: str,
1312
- term_status: str = "PROPOSED",
1313
- ) -> str:
931
+ self,
932
+ glossary_guid: str,
933
+ glossary_term_guid: str,
934
+ new_display_name: str,
935
+ version_id: str = None,
936
+ term_status: str = "PROPOSED",
937
+ body: dict | TemplateRequestBody = None,
938
+ ) -> str:
1314
939
  """Create a new term from an existing term.
1315
940
 
1316
941
  Parameters
@@ -1319,7 +944,7 @@ class GlossaryManager(GlossaryBrowser):
1319
944
  Unique identifier for the glossary category to retrieve terms from.
1320
945
  glossary_term_guid: str
1321
946
  Unique identifier for the source glossary term.
1322
- new_display_named: str
947
+ new_display_name: str
1323
948
  The display name of the new term.
1324
949
  version_id: str
1325
950
  The version identifier of the new term.
@@ -1352,23 +977,26 @@ class GlossaryManager(GlossaryBrowser):
1352
977
  new_display_name,
1353
978
  version_id,
1354
979
  term_status,
980
+ body,
981
+ )
1355
982
  )
1356
- )
1357
983
 
1358
984
  return response
1359
985
 
1360
-
1361
- async def _async_add_term_to_category(
1362
- self, glossary_term_guid: str, glossary_category_guid: str
986
+ async def _async_update_term(
987
+ self,
988
+ glossary_term_guid: str,
989
+ body: dict | UpdateElementRequestBody,
1363
990
  ) -> None:
1364
- """Add the term to the specified category. Async Version.
991
+ """Update a term. Async version.
1365
992
 
1366
993
  Parameters
1367
994
  ----------
1368
- glossary_term_guid : str
1369
- Unique identifier for the glossary term to assign.
1370
- glossary_category_guid: str
1371
- Unique identifier for the category the term will be assigned to.
995
+ glossary_term_guid: str
996
+ Unique identifier for the source glossary term.
997
+ body: dict
998
+ Body containing information about the data field to add
999
+
1372
1000
 
1373
1001
  Returns
1374
1002
  -------
@@ -1382,39 +1010,44 @@ class GlossaryManager(GlossaryBrowser):
1382
1010
  Raised by the server when an issue arises in processing a valid request.
1383
1011
  NotAuthorizedException
1384
1012
  The principle specified by the user_id does not have authorization for the requested action.
1013
+ Notes
1014
+ -----
1385
1015
 
1386
1016
  """
1387
1017
 
1388
1018
  validate_guid(glossary_term_guid)
1389
- validate_guid(glossary_category_guid)
1390
1019
 
1391
1020
  url = (
1392
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1393
- f"categories/{glossary_category_guid}/terms/{glossary_term_guid}"
1021
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/"
1022
+ f"{glossary_term_guid}/"
1023
+ f"update"
1394
1024
  )
1395
- body = {
1396
- "class": "RelationshipRequestBody",
1397
- "properties": {
1398
- "class": "GlossaryTermCategorization"
1399
-
1400
- }
1401
- }
1025
+ await self._async_update_element_body_request(url, ["GlossaryTermProperties"], body)
1026
+ logger.info(f"Updated digital subscription {glossary_term_guid}")
1402
1027
 
1403
- await self._async_make_request("POST", url, body)
1028
+ def update_term(
1029
+ self,
1030
+ glossary_term_guid: str,
1031
+ body: dict | UpdateElementRequestBody,
1404
1032
 
1033
+ ) -> None:
1034
+ """Add the data field values classification to a glossary term
1405
1035
 
1406
- def add_term_to_category(self, glossary_term_guid: str, glossary_category_guid: str) -> None:
1407
- """Add the term to the specified category.
1036
+ Async Version.
1408
1037
 
1409
1038
  Parameters
1410
1039
  ----------
1411
- glossary_term_guid : str
1412
- Unique identifier for the glossary term to assign.
1413
- glossary_category_guid: str
1414
- Unique identifier for the category the term will be assigned to.
1040
+ glossary_term_guid: str
1041
+ Unique identifier for the source glossary term.
1042
+ body: dict
1043
+ Body containing information about the data field to add
1044
+ is_merge_update: bool, optional, default = True
1045
+ Whether the data field values should be merged with existing definition or replace it.
1046
+
1415
1047
 
1416
1048
  Returns
1417
1049
  -------
1050
+ None
1418
1051
 
1419
1052
  Raises
1420
1053
  ------
@@ -1424,24 +1057,48 @@ class GlossaryManager(GlossaryBrowser):
1424
1057
  Raised by the server when an issue arises in processing a valid request.
1425
1058
  NotAuthorizedException
1426
1059
  The principle specified by the user_id does not have authorization for the requested action.
1060
+ Notes
1061
+ -----
1062
+ An example body is:
1063
+
1064
+ {
1065
+ "class" : "ReferenceableRequestBody",
1066
+ "elementProperties" :
1067
+ {
1068
+ "class" : "GlossaryTermProperties",
1069
+ "description" : "This is the long description of the term. And this is some more text."
1070
+ },
1071
+ "updateDescription" : "Final updates based on in-house review comments."
1072
+ }
1427
1073
 
1428
1074
  """
1429
1075
  loop = asyncio.get_event_loop()
1430
1076
  loop.run_until_complete(
1431
- self._async_add_term_to_category(glossary_term_guid, glossary_category_guid)
1077
+ self._async_update_term(
1078
+ glossary_term_guid,
1079
+ body,
1080
+ )
1432
1081
  )
1433
1082
 
1434
- async def _async_remove_term_from_category(
1435
- self, glossary_term_guid: str, glossary_category_guid: str
1083
+
1084
+
1085
+
1086
+ async def _async_delete_term(
1087
+ self,
1088
+ term_guid: str,
1089
+ cascade: bool = False,
1090
+ body: dict | DeleteRequestBody = None
1436
1091
  ) -> None:
1437
- """Remove the term from the specified category. Async Version.
1092
+ """Delete the glossary terms associated with the specified glossary. Async version.
1438
1093
 
1439
1094
  Parameters
1440
1095
  ----------
1441
- glossary_term_guid : str
1442
- Unique identifier for the glossary term to assign.
1443
- glossary_category_guid: str
1444
- Unique identifier for the category the term will be assigned to.
1096
+ term_guid : str,
1097
+ The unique identifier for the term to delete.
1098
+ for_lineage: bool, opt, default = False
1099
+ Set true for lineage processing - generally false.
1100
+ for_duplicate_processing: bool, opt, default = False
1101
+ Set true if duplicate processing handled externally - generally set False.
1445
1102
 
1446
1103
  Returns
1447
1104
  -------
@@ -1455,31 +1112,74 @@ class GlossaryManager(GlossaryBrowser):
1455
1112
  Raised by the server when an issue arises in processing a valid request.
1456
1113
  NotAuthorizedException
1457
1114
  The principle specified by the user_id does not have authorization for the requested action.
1458
-
1115
+ Notes
1116
+ -----
1459
1117
  """
1460
1118
 
1461
- validate_guid(glossary_term_guid)
1462
- validate_guid(glossary_category_guid)
1119
+ validate_guid(term_guid)
1463
1120
 
1464
1121
  url = (
1465
1122
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1466
- f"categories/{glossary_category_guid}/terms/{glossary_term_guid}/remove"
1123
+ f"terms/{term_guid}/delete"
1467
1124
  )
1468
- await self._async_make_request("POST", url)
1125
+ await self._async_delete_request(url, body, cascade)
1126
+ logger.info(f"Deleted collection {term_guid} with cascade {cascade}")
1127
+
1128
+
1129
+ def delete_term(
1130
+ self,
1131
+ term_guid: str,
1132
+ cascade: bool = False,
1133
+ body: dict | DeleteRequestBody = None
1134
+ ) -> None:
1135
+ """Delete the glossary terms associated with the specified glossary.
1136
+
1137
+ Parameters
1138
+ ----------
1139
+ term_guid : str,
1140
+ The unique identifier for the term to delete.
1141
+ for_lineage: bool, opt, default = False
1142
+ Set true for lineage processing - generally false.
1143
+ for_duplicate_processing: bool, opt, default = False
1144
+ Set true if duplicate processing handled externally - generally set False.
1145
+
1146
+ Returns
1147
+ -------
1148
+ None
1469
1149
 
1150
+ Raises
1151
+ ------
1152
+ InvalidParameterException
1153
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
1154
+ PropertyServerException
1155
+ Raised by the server when an issue arises in processing a valid request.
1156
+ NotAuthorizedException
1157
+ The principle specified by the user_id does not have authorization for the requested action.
1158
+ Notes
1159
+ -----
1160
+ """
1161
+ loop = asyncio.get_event_loop()
1162
+ loop.run_until_complete(
1163
+ self._async_delete_term(term_guid, cascade, body)
1164
+ )
1470
1165
 
1471
- def remove_term_from_category(self, glossary_term_guid: str, glossary_category_guid: str) -> None:
1472
- """Remove the term from the specified category.
1166
+ async def _async_move_term(
1167
+ self,
1168
+ term_guid: str,
1169
+ glossary_guid: str,
1170
+ body: dict | DeleteRequestBody = None
1171
+ ) -> None:
1172
+ """Move the glossary terms to the specified glossary. Async version.
1473
1173
 
1474
1174
  Parameters
1475
1175
  ----------
1476
- glossary_term_guid : str
1477
- Unique identifier for the glossary term to assign.
1478
- glossary_category_guid: str
1479
- Unique identifier for the category the term will be assigned to.
1176
+ term_guid : str,
1177
+ The unique identifier for the term to delete.
1178
+
1480
1179
 
1481
1180
  Returns
1482
1181
  -------
1182
+ None
1483
1183
 
1484
1184
  Raises
1485
1185
  ------
@@ -1489,16 +1189,63 @@ class GlossaryManager(GlossaryBrowser):
1489
1189
  Raised by the server when an issue arises in processing a valid request.
1490
1190
  NotAuthorizedException
1491
1191
  The principle specified by the user_id does not have authorization for the requested action.
1192
+ Notes
1193
+ -----
1194
+ """
1195
+
1196
+ validate_guid(term_guid)
1197
+
1198
+ url = (
1199
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1200
+ f"terms/{term_guid}/move-to/{glossary_guid}"
1201
+ )
1202
+ await self._async_delete_request(url, body)
1203
+ logger.info(f"Moved collection {term_guid} to glossary {glossary_guid}")
1204
+
1492
1205
 
1206
+ def move_term(
1207
+ self,
1208
+ term_guid: str,
1209
+ glossary_guid: str,
1210
+ body: dict | DeleteRequestBody = None
1211
+ ) -> None:
1212
+ """Move the glossary terms to the specified glossary.
1213
+
1214
+ Parameters
1215
+ ----------
1216
+ term_guid : str,
1217
+ The unique identifier for the term to delete.
1218
+
1219
+
1220
+ Returns
1221
+ -------
1222
+ None
1223
+
1224
+ Raises
1225
+ ------
1226
+ InvalidParameterException
1227
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
1228
+ PropertyServerException
1229
+ Raised by the server when an issue arises in processing a valid request.
1230
+ NotAuthorizedException
1231
+ The principle specified by the user_id does not have authorization for the requested action.
1232
+ Notes
1233
+ -----
1493
1234
  """
1494
1235
  loop = asyncio.get_event_loop()
1495
1236
  loop.run_until_complete(
1496
- self._async_remove_term_from_category(glossary_term_guid, glossary_category_guid)
1237
+ self._async_move_term(term_guid, glossary_guid, body)
1497
1238
  )
1498
1239
 
1499
- async def _async_add_relationship_between_terms(
1500
- self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict = None,
1501
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1240
+
1241
+
1242
+ #
1243
+ # To work with categories, use the collection manager
1244
+ #
1245
+
1246
+ async def _async_add_is_abstract_concepts(
1247
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1248
+ ) -> None:
1502
1249
  """Add a relationship between terms. Async Version.
1503
1250
 
1504
1251
  Parameters
@@ -1511,10 +1258,7 @@ class GlossaryManager(GlossaryBrowser):
1511
1258
  Type of relationship to add.
1512
1259
  body: dict, optional, default = None
1513
1260
  Further optional details for the relationship.
1514
- for_lineage: bool, default is set by server
1515
- - determines if elements classified as Memento should be returned - normally false
1516
- for_duplicate_processing: bool, default is set by server
1517
- - Normally false. Set true when the caller is part of a deduplication function
1261
+
1518
1262
 
1519
1263
  Returns
1520
1264
  -------
@@ -1534,16 +1278,11 @@ class GlossaryManager(GlossaryBrowser):
1534
1278
  Body is currently required but can be empty except for class. Basic structure is:
1535
1279
 
1536
1280
  {
1537
- "class" : "RelationshipRequestBody",
1281
+ "class" : "NewClassificationRequestBody",
1538
1282
  "effectiveTime" : {{@isoTimestamp}},
1539
1283
  "properties" : {
1540
1284
  "class" : "GlossaryTermRelationship",
1541
- "expression" : "",
1542
- "confidence" : 0,
1543
- "description" : "",
1544
- "status" : "",
1545
- "steward" : "",
1546
- "source" : "",
1285
+
1547
1286
  "effectiveFrom" : "{{@isoTimestamp}}",
1548
1287
  "effectiveTo" : "{{@isoTimestamp}}",
1549
1288
  "extendedProperties" : {
@@ -1552,33 +1291,27 @@ class GlossaryManager(GlossaryBrowser):
1552
1291
  }
1553
1292
  """
1554
1293
 
1555
- validate_guid(term1_guid)
1556
- validate_guid(term2_guid)
1557
-
1558
- if body is None:
1559
- body = {"class": "RelationshipRequestBody",
1560
- "properties":
1561
- {"class": "GlossaryTermRelationship",}
1562
- }
1563
-
1564
- possible_query_params = query_string(
1565
- [
1566
- ("forLineage", for_lineage),
1567
- ("forDuplicateProcessing", for_duplicate_processing),
1568
- ]
1569
- )
1570
-
1571
1294
  url = (
1572
1295
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1573
- f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}{possible_query_params}"
1296
+ f"terms/{term_guid}/is-abstract-concept"
1574
1297
  )
1298
+ if body is None:
1299
+ body = {
1300
+ "class": "NewClassificationRequestBody",
1301
+ "properties":
1302
+ {
1303
+ "class": "AbstractConceptProperties"
1304
+ }
1305
+ }
1575
1306
 
1576
- await self._async_make_request("POST", url, body_slimmer(body))
1307
+ await self._async_new_classification_request(url, "AbstractConceptProperties",body)
1308
+ logger.info(f"Added AbstractConcept classification to {term_guid}")
1577
1309
 
1578
1310
 
1579
- def add_relationship_between_terms(
1580
- self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict = None,
1581
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1311
+
1312
+ def add_is_abstract_concept(
1313
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1314
+ ) -> None:
1582
1315
  """Add a relationship between terms.
1583
1316
 
1584
1317
  Parameters
@@ -1591,10 +1324,6 @@ class GlossaryManager(GlossaryBrowser):
1591
1324
  Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1592
1325
  body: dict, optional, default = None
1593
1326
  Further optional details for the relationship.
1594
- for_lineage: bool, default is set by server
1595
- - determines if elements classified as Memento should be returned - normally false
1596
- for_duplicate_processing: bool, default is set by server
1597
- - Normally false. Set true when the caller is part of a deduplication function
1598
1327
 
1599
1328
  Returns
1600
1329
  -------
@@ -1614,7 +1343,7 @@ class GlossaryManager(GlossaryBrowser):
1614
1343
  Body is currently required but can be empty except for class. Basic structure is:
1615
1344
 
1616
1345
  {
1617
- "class" : "RelationshipRequestBody",
1346
+ "class" : "NewRelationshipRequestBody",
1618
1347
  "effectiveTime" : {{@isoTimestamp}},
1619
1348
  "properties" : {
1620
1349
  "class" : "GlossaryTermRelationship",
@@ -1633,16 +1362,13 @@ class GlossaryManager(GlossaryBrowser):
1633
1362
  """
1634
1363
  loop = asyncio.get_event_loop()
1635
1364
  loop.run_until_complete(
1636
- self._async_add_relationship_between_terms(term1_guid, term2_guid, relationship_type,
1637
- body, for_lineage, for_duplicate_processing)
1365
+ self._async_add_is_abstract_concepts(term_guid, body)
1638
1366
  )
1639
1367
 
1640
-
1641
- async def _async_update_relationship_between_terms(
1642
- self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict = None,
1643
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1644
-
1645
- """Update a relationship between terms. Async Version.
1368
+ async def _async_remove_is_abstract_concepts(
1369
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1370
+ ) -> None:
1371
+ """Add a relationship between terms. Async Version.
1646
1372
 
1647
1373
  Parameters
1648
1374
  ----------
@@ -1651,13 +1377,10 @@ class GlossaryManager(GlossaryBrowser):
1651
1377
  term2_guid : str
1652
1378
  Unique identifier of the second glossary term in relationship.
1653
1379
  relationship_type: str
1654
- Type of relationship to update.
1380
+ Type of relationship to add.
1655
1381
  body: dict, optional, default = None
1656
1382
  Further optional details for the relationship.
1657
- for_lineage: bool, default is set by server
1658
- - determines if elements classified as Memento should be returned - normally false
1659
- for_duplicate_processing: bool, default is set by server
1660
- - Normally false. Set true when the caller is part of a deduplication function
1383
+
1661
1384
 
1662
1385
  Returns
1663
1386
  -------
@@ -1677,49 +1400,30 @@ class GlossaryManager(GlossaryBrowser):
1677
1400
  Body is currently required but can be empty except for class. Basic structure is:
1678
1401
 
1679
1402
  {
1680
- "class" : "RelationshipRequestBody",
1681
- "effectiveTime" : {{@isoTimestamp}},
1682
- "properties" : {
1683
- "class" : "GlossaryTermRelationship",
1684
- "expression" : "",
1685
- "confidence" : 0,
1686
- "description" : "",
1687
- "status" : "",
1688
- "steward" : "",
1689
- "source" : "",
1690
- "effectiveFrom" : "{{@isoTimestamp}}",
1691
- "effectiveTo" : "{{@isoTimestamp}}",
1692
- "extendedProperties" : {
1693
- }
1694
- }
1695
- }
1696
- """
1403
+ "class" : "NewClassificationRequestBody",
1404
+ "effectiveTime" : {{@isoTimestamp}},
1405
+ "properties" : {
1406
+ "class" : "GlossaryTermRelationship",
1697
1407
 
1698
- validate_guid(term1_guid)
1699
- validate_guid(term2_guid)
1700
-
1701
- possible_query_params = query_string(
1702
- [
1703
- ("forLineage", for_lineage),
1704
- ("forDuplicateProcessing", for_duplicate_processing),
1705
- ]
1706
- )
1707
-
1708
- if body is None:
1709
- body = {"properties": {"class": "RelationshipRequestBody"}}
1408
+ "effectiveFrom" : "{{@isoTimestamp}}",
1409
+ "effectiveTo" : "{{@isoTimestamp}}",
1410
+ "extendedProperties" : {
1411
+ }
1412
+ }
1413
+ }
1414
+ """
1710
1415
 
1711
1416
  url = (
1712
1417
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1713
- f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/update{possible_query_params}"
1418
+ f"terms/{term_guid}/is-abstract-concept/remove"
1714
1419
  )
1420
+ await self._async_delete_request(url, body)
1421
+ logger.info(f"Removed AbstractConcept classification to {term_guid}")
1715
1422
 
1716
- await self._async_make_request("POST", url, body_slimmer(body))
1717
-
1718
-
1719
- def update_relationship_between_terms(
1720
- self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict,
1721
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1722
- """Update a relationship between terms.
1423
+ def remove_is_abstract_concept(
1424
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1425
+ ) -> None:
1426
+ """Add a relationship between terms.
1723
1427
 
1724
1428
  Parameters
1725
1429
  ----------
@@ -1728,13 +1432,9 @@ class GlossaryManager(GlossaryBrowser):
1728
1432
  term2_guid : str
1729
1433
  Unique identifier of the second glossary term in relationship.
1730
1434
  relationship_type: str
1731
- Type of relationship to update. A list of relationship types can be found using get_term_relationship_types().
1732
- body: dict
1733
- Details of the relationship to update.
1734
- for_lineage: bool, default is set by server
1735
- - determines if elements classified as Memento should be returned - normally false
1736
- for_duplicate_processing: bool, default is set by server
1737
- - Normally false. Set true when the caller is part of a deduplication function
1435
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1436
+ body: dict, optional, default = None
1437
+ Further optional details for the relationship.
1738
1438
 
1739
1439
  Returns
1740
1440
  -------
@@ -1753,8 +1453,8 @@ class GlossaryManager(GlossaryBrowser):
1753
1453
  ----
1754
1454
  Body is currently required but can be empty except for class. Basic structure is:
1755
1455
 
1756
- {
1757
- "class" : "RelationshipRequestBody",
1456
+ {
1457
+ "class" : "NewRelationshipRequestBody",
1758
1458
  "effectiveTime" : {{@isoTimestamp}},
1759
1459
  "properties" : {
1760
1460
  "class" : "GlossaryTermRelationship",
@@ -1773,14 +1473,14 @@ class GlossaryManager(GlossaryBrowser):
1773
1473
  """
1774
1474
  loop = asyncio.get_event_loop()
1775
1475
  loop.run_until_complete(
1776
- self._async_update_relationship_between_terms(term1_guid, term2_guid, relationship_type,
1777
- body,for_lineage,for_duplicate_processing)
1476
+ self._async_remove_is_abstract_concepts(term_guid, body)
1778
1477
  )
1779
1478
 
1780
- async def _async_remove_relationship_between_terms(
1781
- self, term1_guid: str, term2_guid: str, relationship_type: str, effective_time: str = None,
1782
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1783
- """Remove a relationship between terms. Async Version.
1479
+
1480
+ async def _async_add_is_context_definition(
1481
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1482
+ ) -> None:
1483
+ """Add a relationship between terms. Async Version.
1784
1484
 
1785
1485
  Parameters
1786
1486
  ----------
@@ -1790,12 +1490,9 @@ class GlossaryManager(GlossaryBrowser):
1790
1490
  Unique identifier of the second glossary term in relationship.
1791
1491
  relationship_type: str
1792
1492
  Type of relationship to add.
1793
- effective_time: str, optional, default = None
1794
- Effective time to remove the relationship.
1795
- for_lineage: bool, default is set by server
1796
- - determines if elements classified as Memento should be returned - normally false
1797
- for_duplicate_processing: bool, default is set by server
1798
- - Normally false. Set true when the caller is part of a deduplication function
1493
+ body: dict, optional, default = None
1494
+ Further optional details for the relationship.
1495
+
1799
1496
 
1800
1497
  Returns
1801
1498
  -------
@@ -1810,37 +1507,46 @@ class GlossaryManager(GlossaryBrowser):
1810
1507
  NotAuthorizedException
1811
1508
  The principle specified by the user_id does not have authorization for the requested action.
1812
1509
 
1510
+ Notes
1511
+ ----
1512
+ Body is currently required but can be empty except for class. Basic structure is:
1813
1513
 
1814
- """
1815
-
1816
- validate_guid(term1_guid)
1817
- validate_guid(term2_guid)
1818
-
1819
- possible_query_params = query_string(
1820
- [
1821
- ("forLineage", for_lineage),
1822
- ("forDuplicateProcessing", for_duplicate_processing),
1823
- ]
1824
- )
1514
+ {
1515
+ "class" : "NewClassificationRequestBody",
1516
+ "effectiveTime" : {{@isoTimestamp}},
1517
+ "properties" : {
1518
+ "class" : "GlossaryTermRelationship",
1825
1519
 
1826
- body = {"properties": {
1827
- "class": "EffectiveTimeQueryRequestBody",
1828
- "effectiveTime": effective_time
1829
- }
1520
+ "effectiveFrom" : "{{@isoTimestamp}}",
1521
+ "effectiveTo" : "{{@isoTimestamp}}",
1522
+ "extendedProperties" : {
1523
+ }
1524
+ }
1830
1525
  }
1526
+ """
1831
1527
 
1832
1528
  url = (
1833
1529
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1834
- f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/remove{possible_query_params}"
1530
+ f"terms/{term_guid}/is-context-definition"
1835
1531
  )
1532
+ if body is None:
1533
+ body = {
1534
+ "class": "NewClassificationRequestBody",
1535
+ "properties":
1536
+ {
1537
+ "class": "ContextDefinitionProperties"
1538
+ }
1539
+ }
1836
1540
 
1837
- await self._async_make_request("POST", url, body_slimmer(body))
1541
+ await self._async_new_classification_request(url, "ContextDefinitionProperties",body)
1542
+ logger.info(f"Added AbstractConcept classification to {term_guid}")
1838
1543
 
1839
1544
 
1840
- def remove_relationship_between_terms(
1841
- self, term1_guid: str, term2_guid: str, relationship_type: str, effective_time: str = None,
1842
- for_lineage: bool = False, for_duplicate_processing: bool = False) -> None:
1843
- """Remove a relationship between terms.
1545
+
1546
+ def add_is_context_definition(
1547
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1548
+ ) -> None:
1549
+ """Add a relationship between terms.
1844
1550
 
1845
1551
  Parameters
1846
1552
  ----------
@@ -1849,13 +1555,9 @@ class GlossaryManager(GlossaryBrowser):
1849
1555
  term2_guid : str
1850
1556
  Unique identifier of the second glossary term in relationship.
1851
1557
  relationship_type: str
1852
- Type of relationship to remove. A list of relationship types can be found using get_term_relationship_types().
1853
- effective_time: str, optional, default = None
1854
- Effective time to remove the relationship.
1855
- for_lineage: bool, default is set by server
1856
- - determines if elements classified as Memento should be returned - normally false
1857
- for_duplicate_processing: bool, default is set by server
1858
- - Normally false. Set true when the caller is part of a deduplication function
1558
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1559
+ body: dict, optional, default = None
1560
+ Further optional details for the relationship.
1859
1561
 
1860
1562
  Returns
1861
1563
  -------
@@ -1870,30 +1572,48 @@ class GlossaryManager(GlossaryBrowser):
1870
1572
  NotAuthorizedException
1871
1573
  The principle specified by the user_id does not have authorization for the requested action.
1872
1574
 
1575
+ Notes
1576
+ ----
1577
+ Body is currently required but can be empty except for class. Basic structure is:
1578
+
1579
+ {
1580
+ "class" : "NewRelationshipRequestBody",
1581
+ "effectiveTime" : {{@isoTimestamp}},
1582
+ "properties" : {
1583
+ "class" : "GlossaryTermRelationship",
1584
+ "expression" : "",
1585
+ "confidence" : 0,
1586
+ "description" : "",
1587
+ "status" : "",
1588
+ "steward" : "",
1589
+ "source" : "",
1590
+ "effectiveFrom" : "{{@isoTimestamp}}",
1591
+ "effectiveTo" : "{{@isoTimestamp}}",
1592
+ "extendedProperties" : {
1593
+ }
1594
+ }
1595
+ }
1873
1596
  """
1874
1597
  loop = asyncio.get_event_loop()
1875
1598
  loop.run_until_complete(
1876
- self._async_remove_relationship_between_terms(term1_guid, term2_guid, relationship_type,
1877
- effective_time, for_lineage, for_duplicate_processing)
1599
+ self._async_add_is_context_definition(term_guid, body)
1878
1600
  )
1879
1601
 
1880
-
1881
-
1882
- async def _async_add_confidentiality_to_term(
1883
- self,
1884
- glossary_term_guid: str,
1885
- confidentiality_level: int,
1886
- ) -> None:
1887
- """Add the confidentiality classification to a glossary term
1888
-
1889
- Async Version.
1602
+ async def _async_remove_is_context_definition(
1603
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1604
+ ) -> None:
1605
+ """Add a relationship between terms. Async Version.
1890
1606
 
1891
1607
  Parameters
1892
1608
  ----------
1893
- glossary_term_guid: str
1894
- Unique identifier for the source glossary term.
1895
- confidentiality_level: int
1896
- The level of confidentiality to classify the term with.
1609
+ term1_guid : str
1610
+ Unique identifier of the first glossary term in relationship.
1611
+ term2_guid : str
1612
+ Unique identifier of the second glossary term in relationship.
1613
+ relationship_type: str
1614
+ Type of relationship to add.
1615
+ body: dict, optional, default = None
1616
+ Further optional details for the relationship.
1897
1617
 
1898
1618
 
1899
1619
  Returns
@@ -1908,45 +1628,47 @@ class GlossaryManager(GlossaryBrowser):
1908
1628
  Raised by the server when an issue arises in processing a valid request.
1909
1629
  NotAuthorizedException
1910
1630
  The principle specified by the user_id does not have authorization for the requested action.
1631
+
1911
1632
  Notes
1912
- -----
1913
- See https://egeria-project.org/types/4/0421-Governance-Classification-Levels/?h=confidential#governance-classification-levels
1914
- for a list of default confidentiality levels.
1633
+ ----
1634
+ Body is currently required but can be empty except for class. Basic structure is:
1915
1635
 
1916
- """
1636
+ {
1637
+ "class" : "NewClassificationRequestBody",
1638
+ "effectiveTime" : {{@isoTimestamp}},
1639
+ "properties" : {
1640
+ "class" : "GlossaryTermRelationship",
1917
1641
 
1918
- validate_guid(glossary_term_guid)
1642
+ "effectiveFrom" : "{{@isoTimestamp}}",
1643
+ "effectiveTo" : "{{@isoTimestamp}}",
1644
+ "extendedProperties" : {
1645
+ }
1646
+ }
1647
+ }
1648
+ """
1919
1649
 
1920
1650
  url = (
1921
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/elements/"
1922
- f"{glossary_term_guid}/confidentiality"
1651
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1652
+ f"terms/{term_guid}/is-context-definition/remove"
1923
1653
  )
1654
+ await self._async_delete_request(url, body)
1655
+ logger.info(f"Removed ContextDefinition classification to {term_guid}")
1924
1656
 
1925
- body = {
1926
- "class": "ClassificationRequestBody",
1927
- "properties": {
1928
- "class": "GovernanceClassificationProperties",
1929
- "levelIdentifier": confidentiality_level,
1930
- },
1931
- }
1932
-
1933
- await self._async_make_request("POST", url, body)
1934
- return
1935
-
1936
- def add_confidentiality_to_term(
1937
- self,
1938
- glossary_term_guid: str,
1939
- confidentiality_level: int,
1940
- ) -> str:
1941
- """Add the confidentiality classification to a glossary term
1657
+ def remove_is_context_definition(
1658
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1659
+ ) -> None:
1660
+ """Add a relationship between terms.
1942
1661
 
1943
1662
  Parameters
1944
1663
  ----------
1945
- glossary_term_guid: str
1946
- Unique identifier for the source glossary term.
1947
- confidentiality_level: int
1948
- The level of confidentiality to classify the term with.
1949
-
1664
+ term1_guid : str
1665
+ Unique identifier of the first glossary term in relationship.
1666
+ term2_guid : str
1667
+ Unique identifier of the second glossary term in relationship.
1668
+ relationship_type: str
1669
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1670
+ body: dict, optional, default = None
1671
+ Further optional details for the relationship.
1950
1672
 
1951
1673
  Returns
1952
1674
  -------
@@ -1960,34 +1682,50 @@ class GlossaryManager(GlossaryBrowser):
1960
1682
  Raised by the server when an issue arises in processing a valid request.
1961
1683
  NotAuthorizedException
1962
1684
  The principle specified by the user_id does not have authorization for the requested action.
1685
+
1963
1686
  Notes
1964
- -----
1965
- See https://egeria-project.org/types/4/0421-Governance-Classification-Levels/?h=confidential#governance-classification-levels
1966
- for a list of default confidentiality levels.
1687
+ ----
1688
+ Body is currently required but can be empty except for class. Basic structure is:
1967
1689
 
1690
+ {
1691
+ "class" : "NewRelationshipRequestBody",
1692
+ "effectiveTime" : {{@isoTimestamp}},
1693
+ "properties" : {
1694
+ "class" : "GlossaryTermRelationship",
1695
+ "expression" : "",
1696
+ "confidence" : 0,
1697
+ "description" : "",
1698
+ "status" : "",
1699
+ "steward" : "",
1700
+ "source" : "",
1701
+ "effectiveFrom" : "{{@isoTimestamp}}",
1702
+ "effectiveTo" : "{{@isoTimestamp}}",
1703
+ "extendedProperties" : {
1704
+ }
1705
+ }
1706
+ }
1968
1707
  """
1969
1708
  loop = asyncio.get_event_loop()
1970
- response = loop.run_until_complete(
1971
- self._async_add_confidentiality_to_term(
1972
- glossary_term_guid, confidentiality_level
1709
+ loop.run_until_complete(
1710
+ self._async_remove_is_context_definition(term_guid, body)
1973
1711
  )
1974
- )
1975
-
1976
- return
1977
1712
 
1978
- async def _async_add_subject_area_to_term(
1979
- self, glossary_term_guid: str, subject_area: str
1980
- ) -> None:
1981
- """Add the confidentiality classification to a glossary term
1982
1713
 
1983
- Async Version.
1714
+ async def _async_add_is_data_value(
1715
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1716
+ ) -> None:
1717
+ """Add a relationship between terms. Async Version.
1984
1718
 
1985
1719
  Parameters
1986
1720
  ----------
1987
- glossary_term_guid: str
1988
- Unique identifier for the source glossary term.
1989
- subject_area: str
1990
- The subject area to classify the term with.
1721
+ term1_guid : str
1722
+ Unique identifier of the first glossary term in relationship.
1723
+ term2_guid : str
1724
+ Unique identifier of the second glossary term in relationship.
1725
+ relationship_type: str
1726
+ Type of relationship to add.
1727
+ body: dict, optional, default = None
1728
+ Further optional details for the relationship.
1991
1729
 
1992
1730
 
1993
1731
  Returns
@@ -2002,43 +1740,58 @@ class GlossaryManager(GlossaryBrowser):
2002
1740
  Raised by the server when an issue arises in processing a valid request.
2003
1741
  NotAuthorizedException
2004
1742
  The principle specified by the user_id does not have authorization for the requested action.
1743
+
2005
1744
  Notes
2006
- -----
2007
- See https://egeria-project.org/types/4/0421-Governance-Classification-Levels/?h=confidential#governance-classification-levels
2008
- for a list of default confidentiality levels.
1745
+ ----
1746
+ Body is currently required but can be empty except for class. Basic structure is:
2009
1747
 
2010
- """
1748
+ {
1749
+ "class" : "NewClassificationRequestBody",
1750
+ "effectiveTime" : {{@isoTimestamp}},
1751
+ "properties" : {
1752
+ "class" : "GlossaryTermRelationship",
2011
1753
 
2012
- validate_guid(glossary_term_guid)
1754
+ "effectiveFrom" : "{{@isoTimestamp}}",
1755
+ "effectiveTo" : "{{@isoTimestamp}}",
1756
+ "extendedProperties" : {
1757
+ }
1758
+ }
1759
+ }
1760
+ """
2013
1761
 
2014
1762
  url = (
2015
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/elements/"
2016
- f"{glossary_term_guid}/subject-area-member"
1763
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1764
+ f"terms/{term_guid}/is-data-value"
2017
1765
  )
1766
+ if body is None:
1767
+ body = {
1768
+ "class": "NewClassificationRequestBody",
1769
+ "properties":
1770
+ {
1771
+ "class": "DataValueProperties"
1772
+ }
1773
+ }
2018
1774
 
2019
- body = {
2020
- "class": "ClassificationRequestBody",
2021
- "properties": {
2022
- "class": "SubjectAreaMemberProperties",
2023
- "subjectAreaName": subject_area,
2024
- },
2025
- }
1775
+ await self._async_new_classification_request(url, "DataValueProperties",body)
1776
+ logger.info(f"Added DataValue classification to {term_guid}")
2026
1777
 
2027
- await self._async_make_request("POST", url, body)
2028
- return
2029
1778
 
2030
- def add_subject_area_to_term(
2031
- self, glossary_term_guid: str, subject_area: str
2032
- ) -> None:
2033
- """Add the confidentiality classification to a glossary term
1779
+
1780
+ def add_is_data_value(
1781
+ self, term_guid: str, body: dict | NewClassificationRequestBody = None,
1782
+ ) -> None:
1783
+ """Add a relationship between terms.
2034
1784
 
2035
1785
  Parameters
2036
1786
  ----------
2037
- glossary_term_guid: str
2038
- Unique identifier for the source glossary term.
2039
- subject_area: str
2040
- The subject area to classify the term with.
2041
-
1787
+ term1_guid : str
1788
+ Unique identifier of the first glossary term in relationship.
1789
+ term2_guid : str
1790
+ Unique identifier of the second glossary term in relationship.
1791
+ relationship_type: str
1792
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1793
+ body: dict, optional, default = None
1794
+ Further optional details for the relationship.
2042
1795
 
2043
1796
  Returns
2044
1797
  -------
@@ -2052,39 +1805,49 @@ class GlossaryManager(GlossaryBrowser):
2052
1805
  Raised by the server when an issue arises in processing a valid request.
2053
1806
  NotAuthorizedException
2054
1807
  The principle specified by the user_id does not have authorization for the requested action.
1808
+
2055
1809
  Notes
2056
- -----
2057
- See https://egeria-project.org/types/4/0421-Governance-Classification-Levels/?h=confidential#governance-classification-levels
2058
- for a list of default confidentiality levels.
1810
+ ----
1811
+ Body is currently required but can be empty except for class. Basic structure is:
2059
1812
 
1813
+ {
1814
+ "class" : "NewRelationshipRequestBody",
1815
+ "effectiveTime" : {{@isoTimestamp}},
1816
+ "properties" : {
1817
+ "class" : "GlossaryTermRelationship",
1818
+ "expression" : "",
1819
+ "confidence" : 0,
1820
+ "description" : "",
1821
+ "status" : "",
1822
+ "steward" : "",
1823
+ "source" : "",
1824
+ "effectiveFrom" : "{{@isoTimestamp}}",
1825
+ "effectiveTo" : "{{@isoTimestamp}}",
1826
+ "extendedProperties" : {
1827
+ }
1828
+ }
1829
+ }
2060
1830
  """
2061
1831
  loop = asyncio.get_event_loop()
2062
- response = loop.run_until_complete(
2063
- self._async_add_subject_area_to_term(glossary_term_guid, subject_area)
2064
- )
2065
-
2066
- return
1832
+ loop.run_until_complete(
1833
+ self._async_add_is_data_value(term_guid, body)
1834
+ )
2067
1835
 
2068
- async def _async_update_term(
2069
- self,
2070
- glossary_term_guid: str,
2071
- body: dict,
2072
- is_merge_update: bool = False,
2073
- for_lineage: bool = False,
2074
- for_duplicate_processig: bool = False,
2075
- ) -> None:
2076
- """Add the data field values classification to a glossary term
2077
-
2078
- Async Version.
1836
+ async def _async_remove_is_data_value(
1837
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1838
+ ) -> None:
1839
+ """Add a relationship between terms. Async Version.
2079
1840
 
2080
1841
  Parameters
2081
1842
  ----------
2082
- glossary_term_guid: str
2083
- Unique identifier for the source glossary term.
2084
- body: dict
2085
- Body containing information about the data field to add
2086
- is_merge_update: bool, optional, default = True
2087
- Whether the data field values should be merged with existing definition or replace it.
1843
+ term1_guid : str
1844
+ Unique identifier of the first glossary term in relationship.
1845
+ term2_guid : str
1846
+ Unique identifier of the second glossary term in relationship.
1847
+ relationship_type: str
1848
+ Type of relationship to add.
1849
+ body: dict, optional, default = None
1850
+ Further optional details for the relationship.
2088
1851
 
2089
1852
 
2090
1853
  Returns
@@ -2099,56 +1862,170 @@ class GlossaryManager(GlossaryBrowser):
2099
1862
  Raised by the server when an issue arises in processing a valid request.
2100
1863
  NotAuthorizedException
2101
1864
  The principle specified by the user_id does not have authorization for the requested action.
1865
+
2102
1866
  Notes
2103
- -----
2104
- An example body is:
1867
+ ----
1868
+ Body is currently required but can be empty except for class. Basic structure is:
1869
+
1870
+ {
1871
+ "class" : "NewClassificationRequestBody",
1872
+ "effectiveTime" : {{@isoTimestamp}},
1873
+ "properties" : {
1874
+ "class" : "GlossaryTermRelationship",
1875
+
1876
+ "effectiveFrom" : "{{@isoTimestamp}}",
1877
+ "effectiveTo" : "{{@isoTimestamp}}",
1878
+ "extendedProperties" : {
1879
+ }
1880
+ }
1881
+ }
1882
+ """
1883
+
1884
+ url = (
1885
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
1886
+ f"terms/{term_guid}/is-data-value/remove"
1887
+ )
1888
+ await self._async_delete_request(url, body)
1889
+ logger.info(f"Removed DataValue classification to {term_guid}")
1890
+
1891
+ def remove_is_data_value(
1892
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
1893
+ ) -> None:
1894
+ """Add a relationship between terms.
1895
+
1896
+ Parameters
1897
+ ----------
1898
+ term1_guid : str
1899
+ Unique identifier of the first glossary term in relationship.
1900
+ term2_guid : str
1901
+ Unique identifier of the second glossary term in relationship.
1902
+ relationship_type: str
1903
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
1904
+ body: dict, optional, default = None
1905
+ Further optional details for the relationship.
1906
+
1907
+ Returns
1908
+ -------
1909
+ None
1910
+
1911
+ Raises
1912
+ ------
1913
+ InvalidParameterException
1914
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
1915
+ PropertyServerException
1916
+ Raised by the server when an issue arises in processing a valid request.
1917
+ NotAuthorizedException
1918
+ The principle specified by the user_id does not have authorization for the requested action.
1919
+
1920
+ Notes
1921
+ ----
1922
+ Body is currently required but can be empty except for class. Basic structure is:
2105
1923
 
2106
1924
  {
2107
- "class" : "ReferenceableRequestBody",
2108
- "elementProperties" :
2109
- {
2110
- "class" : "GlossaryTermProperties",
2111
- "description" : "This is the long description of the term. And this is some more text."
2112
- },
2113
- "updateDescription" : "Final updates based on in-house review comments."
1925
+ "class" : "NewRelationshipRequestBody",
1926
+ "effectiveTime" : {{@isoTimestamp}},
1927
+ "properties" : {
1928
+ "class" : "GlossaryTermRelationship",
1929
+ "expression" : "",
1930
+ "confidence" : 0,
1931
+ "description" : "",
1932
+ "status" : "",
1933
+ "steward" : "",
1934
+ "source" : "",
1935
+ "effectiveFrom" : "{{@isoTimestamp}}",
1936
+ "effectiveTo" : "{{@isoTimestamp}}",
1937
+ "extendedProperties" : {
1938
+ }
1939
+ }
2114
1940
  }
1941
+ """
1942
+ loop = asyncio.get_event_loop()
1943
+ loop.run_until_complete(
1944
+ self._async_remove_is_data_value(term_guid, body)
1945
+ )
1946
+
1947
+
1948
+ async def _async_add_activity_description(
1949
+ self, term_guid: str, activity_type: int = None, body: dict | NewClassificationRequestBody = None,
1950
+ ) -> None:
1951
+ """Add a relationship between terms. Async Version.
1952
+
1953
+ Parameters
1954
+ ----------
1955
+ term1_guid : str
1956
+ Unique identifier of the first glossary term in relationship.
1957
+ term2_guid : str
1958
+ Unique identifier of the second glossary term in relationship.
1959
+ relationship_type: str
1960
+ Type of relationship to add.
1961
+ body: dict, optional, default = None
1962
+ Further optional details for the relationship.
1963
+
1964
+
1965
+ Returns
1966
+ -------
1967
+ None
1968
+
1969
+ Raises
1970
+ ------
1971
+ InvalidParameterException
1972
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
1973
+ PropertyServerException
1974
+ Raised by the server when an issue arises in processing a valid request.
1975
+ NotAuthorizedException
1976
+ The principle specified by the user_id does not have authorization for the requested action.
1977
+
1978
+ Notes
1979
+ ----
1980
+ Body is currently required but can be empty except for class. Basic structure is:
1981
+
1982
+ {
1983
+ "class" : "NewClassificationRequestBody",
1984
+ "effectiveTime" : {{@isoTimestamp}},
1985
+ "properties" : {
1986
+ "class" : "GlossaryTermRelationship",
2115
1987
 
1988
+ "effectiveFrom" : "{{@isoTimestamp}}",
1989
+ "effectiveTo" : "{{@isoTimestamp}}",
1990
+ "extendedProperties" : {
1991
+ }
1992
+ }
1993
+ }
2116
1994
  """
2117
1995
 
2118
- validate_guid(glossary_term_guid)
2119
- is_merge_update_s = str(is_merge_update).lower()
2120
- for_lineage_s = str(for_lineage).lower()
2121
- for_duplicate_processing_s = str(for_duplicate_processig).lower()
1996
+ if body is None:
1997
+ body = {
1998
+ "class": "NewClassificationRequestBody",
1999
+ "properties": {
2000
+ "class": "ActivityDescriptionProperties",
2001
+ "type": activity_type,
2002
+ }
2003
+ }
2122
2004
 
2123
2005
  url = (
2124
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/{glossary_term_guid}/"
2125
- f"update?isMergeUpdate={is_merge_update_s}&forLineage={for_lineage_s}&forDuplicateProcessing={for_duplicate_processing_s}"
2006
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
2007
+ f"terms/{term_guid}/is-activity"
2126
2008
  )
2009
+ await self._async_new_classification_request(url, "ActivityDescriptionProperties",body)
2010
+ logger.info(f"Added DataValue classification to {term_guid}")
2127
2011
 
2128
- await self._async_make_request("POST", url, body)
2129
- return
2130
2012
 
2131
- def update_term(
2132
- self,
2133
- glossary_term_guid: str,
2134
- body: dict,
2135
- is_merge_update: bool = True,
2136
- for_lineage: bool = False,
2137
- for_duplicate_processig: bool = False,
2138
- ) -> None:
2139
- """Add the data field values classification to a glossary term
2140
2013
 
2141
- Async Version.
2014
+ def add_activity_description(
2015
+ self, term_guid: str, activity_type: int = None, body: dict | NewClassificationRequestBody = None,
2016
+ ) -> None:
2017
+ """Add a relationship between terms.
2142
2018
 
2143
2019
  Parameters
2144
2020
  ----------
2145
- glossary_term_guid: str
2146
- Unique identifier for the source glossary term.
2147
- body: dict
2148
- Body containing information about the data field to add
2149
- is_merge_update: bool, optional, default = True
2150
- Whether the data field values should be merged with existing definition or replace it.
2151
-
2021
+ term1_guid : str
2022
+ Unique identifier of the first glossary term in relationship.
2023
+ term2_guid : str
2024
+ Unique identifier of the second glossary term in relationship.
2025
+ relationship_type: str
2026
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
2027
+ body: dict, optional, default = None
2028
+ Further optional details for the relationship.
2152
2029
 
2153
2030
  Returns
2154
2031
  -------
@@ -2162,49 +2039,49 @@ class GlossaryManager(GlossaryBrowser):
2162
2039
  Raised by the server when an issue arises in processing a valid request.
2163
2040
  NotAuthorizedException
2164
2041
  The principle specified by the user_id does not have authorization for the requested action.
2042
+
2165
2043
  Notes
2166
- -----
2167
- An example body is:
2044
+ ----
2045
+ Body is currently required but can be empty except for class. Basic structure is:
2168
2046
 
2169
2047
  {
2170
- "class" : "ReferenceableRequestBody",
2171
- "elementProperties" :
2172
- {
2173
- "class" : "GlossaryTermProperties",
2174
- "description" : "This is the long description of the term. And this is some more text."
2175
- },
2176
- "updateDescription" : "Final updates based on in-house review comments."
2048
+ "class" : "NewRelationshipRequestBody",
2049
+ "effectiveTime" : {{@isoTimestamp}},
2050
+ "properties" : {
2051
+ "class" : "GlossaryTermRelationship",
2052
+ "expression" : "",
2053
+ "confidence" : 0,
2054
+ "description" : "",
2055
+ "status" : "",
2056
+ "steward" : "",
2057
+ "source" : "",
2058
+ "effectiveFrom" : "{{@isoTimestamp}}",
2059
+ "effectiveTo" : "{{@isoTimestamp}}",
2060
+ "extendedProperties" : {
2061
+ }
2062
+ }
2177
2063
  }
2178
-
2179
2064
  """
2180
2065
  loop = asyncio.get_event_loop()
2181
2066
  loop.run_until_complete(
2182
- self._async_update_term(
2183
- glossary_term_guid,
2184
- body,
2185
- is_merge_update,
2186
- for_lineage,
2187
- for_duplicate_processig,
2067
+ self._async_add_activity_description(term_guid, activity_type, body)
2188
2068
  )
2189
- )
2190
2069
 
2191
- return
2192
-
2193
- async def _async_update_term_version_id(
2194
- self,
2195
- glossary_term_guid: str,
2196
- new_version_identifier: str,
2197
- ) -> None:
2198
- """Update a glossary term's version identifier
2199
-
2200
- Async Version.
2070
+ async def _async_remove_activity_description(
2071
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
2072
+ ) -> None:
2073
+ """Add a relationship between terms. Async Version.
2201
2074
 
2202
2075
  Parameters
2203
2076
  ----------
2204
- glossary_term_guid: str
2205
- Unique identifier for the source glossary term.
2206
- new_version_identifier: str
2207
- The new version identifier to update the term with.
2077
+ term1_guid : str
2078
+ Unique identifier of the first glossary term in relationship.
2079
+ term2_guid : str
2080
+ Unique identifier of the second glossary term in relationship.
2081
+ relationship_type: str
2082
+ Type of relationship to add.
2083
+ body: dict, optional, default = None
2084
+ Further optional details for the relationship.
2208
2085
 
2209
2086
 
2210
2087
  Returns
@@ -2219,45 +2096,47 @@ class GlossaryManager(GlossaryBrowser):
2219
2096
  Raised by the server when an issue arises in processing a valid request.
2220
2097
  NotAuthorizedException
2221
2098
  The principle specified by the user_id does not have authorization for the requested action.
2099
+
2222
2100
  Notes
2223
- -----
2224
- This is a useful example of a term update, specifying a new version identifier.
2101
+ ----
2102
+ Body is currently required but can be empty except for class. Basic structure is:
2225
2103
 
2226
- """
2104
+ {
2105
+ "class" : "NewClassificationRequestBody",
2106
+ "effectiveTime" : {{@isoTimestamp}},
2107
+ "properties" : {
2108
+ "class" : "GlossaryTermRelationship",
2227
2109
 
2228
- validate_guid(glossary_term_guid)
2110
+ "effectiveFrom" : "{{@isoTimestamp}}",
2111
+ "effectiveTo" : "{{@isoTimestamp}}",
2112
+ "extendedProperties" : {
2113
+ }
2114
+ }
2115
+ }
2116
+ """
2229
2117
 
2230
2118
  url = (
2231
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/terms/{glossary_term_guid}/"
2232
- f"update?isMergeUpdate=true"
2119
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
2120
+ f"terms/{term_guid}/is-activity/remove"
2233
2121
  )
2122
+ await self._async_delete_request(url, body)
2123
+ logger.info(f"Removed ActivityDescription classification to {term_guid}")
2234
2124
 
2235
- body = {
2236
- "class": "ReferenceableRequestBody",
2237
- "elementProperties": {
2238
- "class": "GlossaryTermProperties",
2239
- "publishVersionIdentifier": new_version_identifier,
2240
- },
2241
- }
2242
- await self._async_make_request("POST", url, body)
2243
- return
2244
-
2245
- def update_term_version_id(
2246
- self,
2247
- glossary_term_guid: str,
2248
- new_version_identifier: str,
2249
- ) -> None:
2250
- """Update a glossary term's version identifier
2251
-
2252
- Async Version.
2125
+ def remove_activity_description(
2126
+ self, term_guid: str, body: dict | DeleteRequestBody = None,
2127
+ ) -> None:
2128
+ """Add a relationship between terms.
2253
2129
 
2254
2130
  Parameters
2255
2131
  ----------
2256
- glossary_term_guid: str
2257
- Unique identifier for the source glossary term.
2258
- new_version_identifier: str
2259
- The new version identifier to update the term with.
2260
-
2132
+ term1_guid : str
2133
+ Unique identifier of the first glossary term in relationship.
2134
+ term2_guid : str
2135
+ Unique identifier of the second glossary term in relationship.
2136
+ relationship_type: str
2137
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
2138
+ body: dict, optional, default = None
2139
+ Further optional details for the relationship.
2261
2140
 
2262
2141
  Returns
2263
2142
  -------
@@ -2271,27 +2150,54 @@ class GlossaryManager(GlossaryBrowser):
2271
2150
  Raised by the server when an issue arises in processing a valid request.
2272
2151
  NotAuthorizedException
2273
2152
  The principle specified by the user_id does not have authorization for the requested action.
2153
+
2274
2154
  Notes
2275
- -----
2276
- This is a useful example of a term update, specifying a new version identifier.
2155
+ ----
2156
+ Body is currently required but can be empty except for class. Basic structure is:
2277
2157
 
2158
+ {
2159
+ "class" : "NewRelationshipRequestBody",
2160
+ "effectiveTime" : {{@isoTimestamp}},
2161
+ "properties" : {
2162
+ "class" : "GlossaryTermRelationship",
2163
+ "expression" : "",
2164
+ "confidence" : 0,
2165
+ "description" : "",
2166
+ "status" : "",
2167
+ "steward" : "",
2168
+ "source" : "",
2169
+ "effectiveFrom" : "{{@isoTimestamp}}",
2170
+ "effectiveTo" : "{{@isoTimestamp}}",
2171
+ "extendedProperties" : {
2172
+ }
2173
+ }
2174
+ }
2278
2175
  """
2279
2176
  loop = asyncio.get_event_loop()
2280
2177
  loop.run_until_complete(
2281
- self._async_update_term_version_id(
2282
- glossary_term_guid, new_version_identifier
2178
+ self._async_remove_activity_description(term_guid, body)
2283
2179
  )
2284
- )
2285
2180
 
2286
- async def _async_undo_term_update(self, glossary_term_guid: str) -> None:
2287
- """Undo an update to a glossary term
2181
+ #
2182
+ # Term - Term Relationships
2183
+ #
2288
2184
 
2289
- Async Version.
2185
+ async def _async_add_relationship_between_terms(
2186
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | NewRelationshipRequestBody = None,
2187
+ ) -> None:
2188
+ """Add a relationship between terms. Async Version.
2290
2189
 
2291
2190
  Parameters
2292
2191
  ----------
2293
- glossary_term_guid: str
2294
- Unique identifier for the source glossary term.
2192
+ term1_guid : str
2193
+ Unique identifier of the first glossary term in relationship.
2194
+ term2_guid : str
2195
+ Unique identifier of the second glossary term in relationship.
2196
+ relationship_type: str
2197
+ Type of relationship to add.
2198
+ body: dict, optional, default = None
2199
+ Further optional details for the relationship.
2200
+
2295
2201
 
2296
2202
  Returns
2297
2203
  -------
@@ -2305,28 +2211,64 @@ class GlossaryManager(GlossaryBrowser):
2305
2211
  Raised by the server when an issue arises in processing a valid request.
2306
2212
  NotAuthorizedException
2307
2213
  The principle specified by the user_id does not have authorization for the requested action.
2214
+
2308
2215
  Notes
2309
- -----
2310
- This creates a new version with the state of the term before the last update.
2216
+ ----
2217
+ Body is currently required but can be empty except for class. Basic structure is:
2311
2218
 
2219
+ {
2220
+ "class" : "NewRelationshipRequestBody",
2221
+ "effectiveTime" : {{@isoTimestamp}},
2222
+ "properties" : {
2223
+ "class" : "GlossaryTermRelationship",
2224
+ "expression" : "",
2225
+ "confidence" : 0,
2226
+ "description" : "",
2227
+ "status" : "",
2228
+ "steward" : "",
2229
+ "source" : "",
2230
+ "effectiveFrom" : "{{@isoTimestamp}}",
2231
+ "effectiveTo" : "{{@isoTimestamp}}",
2232
+ "extendedProperties" : {
2233
+ }
2234
+ }
2235
+ }
2312
2236
  """
2313
2237
 
2314
- validate_guid(glossary_term_guid)
2238
+ validate_guid(term1_guid)
2239
+ validate_guid(term2_guid)
2240
+
2241
+ if body is None:
2242
+ body = {
2243
+ "class": "RelationshipRequestBody",
2244
+ "properties":
2245
+ {"class": "GlossaryTermRelationship", }
2246
+ }
2247
+
2248
+
2315
2249
 
2316
2250
  url = (
2317
- f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/terms/"
2318
- f"{glossary_term_guid}/undo"
2251
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
2252
+ f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}"
2319
2253
  )
2254
+ await self._async_new_relationship_request(url, ["GlossaryTermRelationship"],body)
2255
+ logger.info(f"Added relationship between {term1_guid} and {term2_guid} of type {relationship_type}")
2320
2256
 
2321
- await self._async_make_request("POST", url)
2322
-
2323
- def undo_term_update(self, glossary_term_guid: str) -> None:
2324
- """Undo an update to a glossary term
2257
+ def add_relationship_between_terms(
2258
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | NewRelationshipRequestBody = None,
2259
+ ) -> None:
2260
+ """Add a relationship between terms.
2325
2261
 
2326
2262
  Parameters
2327
2263
  ----------
2328
- glossary_term_guid: str
2329
- Unique identifier for the source glossary term.
2264
+ term1_guid : str
2265
+ Unique identifier of the first glossary term in relationship.
2266
+ term2_guid : str
2267
+ Unique identifier of the second glossary term in relationship.
2268
+ relationship_type: str
2269
+ Type of relationship to add. A list of relationship types can be found using get_term_relationship_types().
2270
+ body: dict, optional, default = None
2271
+ Further optional details for the relationship.
2330
2272
 
2331
2273
  Returns
2332
2274
  -------
@@ -2340,32 +2282,51 @@ class GlossaryManager(GlossaryBrowser):
2340
2282
  Raised by the server when an issue arises in processing a valid request.
2341
2283
  NotAuthorizedException
2342
2284
  The principle specified by the user_id does not have authorization for the requested action.
2285
+
2343
2286
  Notes
2344
- -----
2345
- This creates a new version with the state of the term before the last update.
2287
+ ----
2288
+ Body is currently required but can be empty except for class. Basic structure is:
2346
2289
 
2290
+ {
2291
+ "class" : "NewRelationshipRequestBody",
2292
+ "effectiveTime" : {{@isoTimestamp}},
2293
+ "properties" : {
2294
+ "class" : "GlossaryTermRelationship",
2295
+ "expression" : "",
2296
+ "confidence" : 0,
2297
+ "description" : "",
2298
+ "status" : "",
2299
+ "steward" : "",
2300
+ "source" : "",
2301
+ "effectiveFrom" : "{{@isoTimestamp}}",
2302
+ "effectiveTo" : "{{@isoTimestamp}}",
2303
+ "extendedProperties" : {
2304
+ }
2305
+ }
2306
+ }
2347
2307
  """
2348
2308
  loop = asyncio.get_event_loop()
2349
- loop.run_until_complete(self._async_undo_term_update(glossary_term_guid))
2350
-
2309
+ loop.run_until_complete(
2310
+ self._async_add_relationship_between_terms(term1_guid, term2_guid, relationship_type,
2311
+ body)
2312
+ )
2351
2313
 
2314
+ async def _async_update_relationship_between_terms(
2315
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | UpdateRelationshipRequestBody = None
2316
+ ) -> None:
2352
2317
 
2353
- async def _async_delete_term(
2354
- self,
2355
- term_guid: str,
2356
- for_lineage: bool = False,
2357
- for_duplicate_processing: bool = False,
2358
- ) -> list | str:
2359
- """Delete the glossary terms associated with the specified glossary. Async version.
2318
+ """Update a relationship between terms. Async Version.
2360
2319
 
2361
2320
  Parameters
2362
2321
  ----------
2363
- term_guid : str,
2364
- The unique identifier for the term to delete.
2365
- for_lineage: bool, opt, default = False
2366
- Set true for lineage processing - generally false.
2367
- for_duplicate_processing: bool, opt, default = False
2368
- Set true if duplicate processing handled externally - generally set False.
2322
+ term1_guid : str
2323
+ Unique identifier of the first glossary term in relationship.
2324
+ term2_guid : str
2325
+ Unique identifier of the second glossary term in relationship.
2326
+ relationship_type: str
2327
+ Type of relationship to update.
2328
+ body: dict, optional, default = None
2329
+ Further optional details for the relationship.
2369
2330
 
2370
2331
  Returns
2371
2332
  -------
@@ -2379,36 +2340,58 @@ class GlossaryManager(GlossaryBrowser):
2379
2340
  Raised by the server when an issue arises in processing a valid request.
2380
2341
  NotAuthorizedException
2381
2342
  The principle specified by the user_id does not have authorization for the requested action.
2343
+
2382
2344
  Notes
2383
- -----
2345
+ ----
2346
+ Body is currently required but can be empty except for class. Basic structure is:
2347
+
2348
+ {
2349
+ "class" : "UpdateRelationshipRequestBody",
2350
+ "effectiveTime" : {{@isoTimestamp}},
2351
+ "properties" : {
2352
+ "class" : "GlossaryTermRelationship",
2353
+ "expression" : "",
2354
+ "confidence" : 0,
2355
+ "description" : "",
2356
+ "status" : "",
2357
+ "steward" : "",
2358
+ "source" : "",
2359
+ "effectiveFrom" : "{{@isoTimestamp}}",
2360
+ "effectiveTo" : "{{@isoTimestamp}}",
2361
+ "extendedProperties" : {
2362
+ }
2363
+ }
2364
+ }
2384
2365
  """
2385
2366
 
2386
- validate_guid(term_guid)
2367
+ validate_guid(term1_guid)
2368
+ validate_guid(term2_guid)
2369
+
2370
+
2387
2371
 
2388
2372
  url = (
2389
2373
  f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
2390
- f"terms/{term_guid}/remove?forLineage={for_lineage}&forDuplicateProcessing={for_duplicate_processing}"
2391
- )
2374
+ f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/update")
2392
2375
 
2393
- await self._async_make_request("POST", url)
2394
- return
2376
+ await self._async_update_relationship_request(url, "GlossaryTermRelationship", body)
2377
+ logger.info(f"Updated relationship between {term1_guid} and {term2_guid} of type {relationship_type}")
2395
2378
 
2396
- def delete_term(
2397
- self,
2398
- term_guid: str,
2399
- for_lineage: bool = False,
2400
- for_duplicate_processing: bool = False,
2401
- ) -> list | str:
2402
- """Delete the glossary terms associated with the specified glossary.
2379
+ def update_relationship_between_terms(
2380
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | UpdateRelationshipRequestBody = None
2381
+ ) -> None:
2382
+ """Update a relationship between terms.
2403
2383
 
2404
2384
  Parameters
2405
2385
  ----------
2406
- term_guid : str,
2407
- The unique identifier for the term to delete.
2408
- for_lineage: bool, opt, default = False
2409
- Set true for lineage processing - generally false.
2410
- for_duplicate_processing: bool, opt, default = False
2411
- Set true if duplicate processing handled externally - generally set False.
2386
+ term1_guid : str
2387
+ Unique identifier of the first glossary term in relationship.
2388
+ term2_guid : str
2389
+ Unique identifier of the second glossary term in relationship.
2390
+ relationship_type: str
2391
+ Type of relationship to update. A list of relationship types can be found using
2392
+ get_term_relationship_types().
2393
+ body: dict
2394
+ Details of the relationship to update.
2412
2395
 
2413
2396
  Returns
2414
2397
  -------
@@ -2422,18 +2405,117 @@ class GlossaryManager(GlossaryBrowser):
2422
2405
  Raised by the server when an issue arises in processing a valid request.
2423
2406
  NotAuthorizedException
2424
2407
  The principle specified by the user_id does not have authorization for the requested action.
2408
+
2425
2409
  Notes
2426
- -----
2410
+ ----
2411
+ Body is currently required but can be empty except for class. Basic structure is:
2412
+
2413
+ {
2414
+ "class" : "UpdateRelationshipRequestBody",
2415
+ "effectiveTime" : {{@isoTimestamp}},
2416
+ "properties" : {
2417
+ "class" : "GlossaryTermRelationship",
2418
+ "expression" : "",
2419
+ "confidence" : 0,
2420
+ "description" : "",
2421
+ "status" : "",
2422
+ "steward" : "",
2423
+ "source" : "",
2424
+ "effectiveFrom" : "{{@isoTimestamp}}",
2425
+ "effectiveTo" : "{{@isoTimestamp}}",
2426
+ "extendedProperties" : {
2427
+ }
2428
+ }
2429
+ }
2427
2430
  """
2428
2431
  loop = asyncio.get_event_loop()
2429
2432
  loop.run_until_complete(
2430
- self._async_delete_term(term_guid, for_lineage, for_duplicate_processing)
2433
+ self._async_update_relationship_between_terms(term1_guid, term2_guid, relationship_type,
2434
+ body)
2435
+ )
2436
+
2437
+ async def _async_remove_relationship_between_terms(
2438
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | DeleteRequestBody = None,
2439
+ ) -> None:
2440
+ """Remove a relationship between terms. Async Version.
2441
+
2442
+ Parameters
2443
+ ----------
2444
+ term1_guid : str
2445
+ Unique identifier of the first glossary term in relationship.
2446
+ term2_guid : str
2447
+ Unique identifier of the second glossary term in relationship.
2448
+ relationship_type: str
2449
+ Type of relationship to add.
2450
+ effective_time: str, optional, default = None
2451
+ Effective time to remove the relationship.
2452
+ for_lineage: bool, default is set by server
2453
+ - determines if elements classified as Memento should be returned - normally false
2454
+ for_duplicate_processing: bool, default is set by server
2455
+ - Normally false. Set true when the caller is part of a deduplication function
2456
+
2457
+ Returns
2458
+ -------
2459
+ None
2460
+
2461
+ Raises
2462
+ ------
2463
+ InvalidParameterException
2464
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
2465
+ PropertyServerException
2466
+ Raised by the server when an issue arises in processing a valid request.
2467
+ NotAuthorizedException
2468
+ The principle specified by the user_id does not have authorization for the requested action.
2469
+
2470
+
2471
+ """
2472
+
2473
+ validate_guid(term1_guid)
2474
+ validate_guid(term2_guid)
2475
+
2476
+
2477
+ url = (
2478
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
2479
+ f"terms/{term1_guid}/relationships/{relationship_type}/terms/{term2_guid}/remove"
2431
2480
  )
2432
2481
 
2433
- return
2482
+ await self._async_delete_request(url, body)
2434
2483
 
2435
- async def _async_relate_terms(self, term1_guid: str, term2_guid: str, relationship: str) -> None:
2436
- pass
2484
+ def remove_relationship_between_terms(
2485
+ self, term1_guid: str, term2_guid: str, relationship_type: str, body: dict | DeleteRequestBody = None) -> None:
2486
+
2487
+ """Remove a relationship between terms.
2488
+
2489
+ Parameters
2490
+ ----------
2491
+ term1_guid : str
2492
+ Unique identifier of the first glossary term in relationship.
2493
+ term2_guid : str
2494
+ Unique identifier of the second glossary term in relationship.
2495
+ relationship_type: str
2496
+ Type of relationship to remove. A list of relationship types can be found using
2497
+ get_term_relationship_types().
2498
+
2499
+
2500
+ Returns
2501
+ -------
2502
+ None
2503
+
2504
+ Raises
2505
+ ------
2506
+ InvalidParameterException
2507
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
2508
+ PropertyServerException
2509
+ Raised by the server when an issue arises in processing a valid request.
2510
+ NotAuthorizedException
2511
+ The principle specified by the user_id does not have authorization for the requested action.
2512
+
2513
+ """
2514
+ loop = asyncio.get_event_loop()
2515
+ loop.run_until_complete(
2516
+ self._async_remove_relationship_between_terms(term1_guid, term2_guid, relationship_type,
2517
+ body)
2518
+ )
2437
2519
 
2438
2520
 
2439
2521
  if __name__ == "__main__":