pyegeria 5.4.8.7__py3-none-any.whl → 5.4.8.9__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.

Potentially problematic release.


This version of pyegeria might be problematic. Click here for more details.

Files changed (51) hide show
  1. examples/Coco_config/README.md +19 -0
  2. examples/Coco_config/__init__.py +4 -0
  3. examples/Coco_config/config_cocoMDS1.py +108 -0
  4. examples/Coco_config/config_cocoMDS2.py +126 -0
  5. examples/Coco_config/config_cocoMDS3.py +109 -0
  6. examples/Coco_config/config_cocoMDS4.py +91 -0
  7. examples/Coco_config/config_cocoMDS5.py +116 -0
  8. examples/Coco_config/config_cocoMDS6.py +114 -0
  9. examples/Coco_config/config_cocoMDSx.py +119 -0
  10. examples/Coco_config/config_cocoView1.py +155 -0
  11. examples/Coco_config/config_coco_core.py +255 -0
  12. examples/Coco_config/config_coco_datalake.py +450 -0
  13. examples/Coco_config/config_exchangeDL01.py +106 -0
  14. examples/Coco_config/config_governDL01.py +80 -0
  15. examples/Coco_config/config_monitorDev01.py +60 -0
  16. examples/Coco_config/config_monitorGov01.py +194 -0
  17. examples/Coco_config/globals.py +154 -0
  18. examples/GeoSpatial Products Example.py +535 -0
  19. examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
  20. examples/Jupyter Notebooks/README.md +2 -0
  21. examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
  22. examples/Jupyter Notebooks/common/__init__.py +14 -0
  23. examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
  24. examples/Jupyter Notebooks/common/environment-check.ipynb +53 -0
  25. examples/Jupyter Notebooks/common/globals.ipynb +184 -0
  26. examples/Jupyter Notebooks/common/globals.py +154 -0
  27. examples/Jupyter Notebooks/common/orig_globals.py +152 -0
  28. examples/format_sets/all_format_sets.json +910 -0
  29. examples/format_sets/custom_format_sets.json +268 -0
  30. examples/format_sets/subset_format_sets.json +187 -0
  31. examples/format_sets_save_load_example.py +294 -0
  32. examples/output_formats_example.py +193 -0
  33. md_processing/__init__.py +1 -1
  34. md_processing/data/commands.json +39 -39
  35. md_processing/dr_egeria.py +3 -3
  36. md_processing/md_commands/feedback_commands.py +58 -83
  37. md_processing/md_processing_utils/common_md_utils.py +2 -2
  38. md_processing/md_processing_utils/extraction_utils.py +9 -5
  39. md_processing/md_processing_utils/md_processing_constants.py +7 -3
  40. pyegeria/_client_new.py +77 -20
  41. pyegeria/_exceptions_new.py +19 -11
  42. pyegeria/_globals.py +101 -92
  43. pyegeria/asset_catalog_omvs.py +2 -2
  44. pyegeria/base_report_formats.py +45 -8
  45. pyegeria/output_formatter.py +6 -2
  46. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/METADATA +1 -1
  47. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/RECORD +51 -19
  48. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/top_level.txt +1 -0
  49. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/WHEEL +0 -0
  50. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/entry_points.txt +0 -0
  51. {pyegeria-5.4.8.7.dist-info → pyegeria-5.4.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -64,7 +64,8 @@ def process_add_comment_command(egeria_client: EgeriaTech, txt: str, directive:
64
64
 
65
65
  attributes = parsed_output['attributes']
66
66
 
67
-
67
+ valid = parsed_output['valid']
68
+ exists = parsed_output['exists']
68
69
 
69
70
  qualified_name = parsed_output.get('qualified_name', None)
70
71
  guid = parsed_output.get('guid', None)
@@ -79,19 +80,18 @@ def process_add_comment_command(egeria_client: EgeriaTech, txt: str, directive:
79
80
  associated_element = attributes.get('Associated Element', {}).get('value', None)
80
81
  associated_element_guid = attributes.get('Associated Element', {}).get('guid', None)
81
82
  description = attributes.get('Comment Text', {}).get('value', None)
82
- comment_type = attributes.get('Comment Type', {}).get('value', None)
83
- parent_comment = attributes.get('Parent Comment', {}).get('value', None)
84
- parent_comment_guid = attributes.get('Parent Comment', {}).get('guid', None)
85
-
86
- if associated_element_guid is None and parent_comment_guid is None:
87
- valid = False
88
- msg = f"Validation failed for {command} - One of `Associated Element` or `Parent Comment` must be specified\n"
89
- logger.error(msg)
90
- print(msg)
91
- else:
92
- if description:
93
- valid = True
94
- exists = True
83
+ comment_type = attributes.get('Comment Type', {}).get('value', None).strip()
84
+
85
+
86
+ # if associated_element_guid is None and parent_comment_guid is None:
87
+ # valid = False
88
+ # msg = f"Validation failed for {command} - One of `Associated Element` or `Parent Comment` must be specified\n"
89
+ # logger.error(msg)
90
+ # print(msg)
91
+ # else:
92
+ # if description:
93
+ # valid = True
94
+ # exists = True
95
95
  #
96
96
 
97
97
  if directive == "display":
@@ -109,13 +109,14 @@ def process_add_comment_command(egeria_client: EgeriaTech, txt: str, directive:
109
109
  obj = "Comment"
110
110
  if comment_type not in COMMENT_TYPES:
111
111
  raise ValueError(f"Invalid comment type: {comment_type}")
112
- target_guid = parent_comment_guid if parent_comment_guid else associated_element_guid
112
+ # target_guid = parent_comment_guid if parent_comment_guid else associated_element_guid
113
113
  if qualified_name is None:
114
- qualified_name = egeria_client.make_feedback_qn("Comment",target_guid,display_name)
114
+ qualified_name = egeria_client.make_feedback_qn("Comment",associated_element_guid,display_name)
115
115
  # Set the property body for a glossary collection
116
116
  #
117
117
  prop_body = {
118
118
  "class": "CommentProperties",
119
+ "displayName": display_name,
119
120
  "qualifiedName": qualified_name,
120
121
  "description": description,
121
122
  "commentType": comment_type
@@ -165,20 +166,21 @@ def process_add_comment_command(egeria_client: EgeriaTech, txt: str, directive:
165
166
  return None
166
167
 
167
168
  else:
169
+
168
170
  body = set_create_body(object_type,attributes)
169
171
  body['class'] = "NewAttachmentRequestBody"
170
172
  body["properties"] = prop_body
171
173
  slim_body = body_slimmer(body)
172
- if parent_comment_guid:
173
- guid = egeria_client.add_comment_reply(element_guid = parent_comment_guid, body = slim_body)
174
- else:
175
- guid = egeria_client.add_comment_to_element(element_guid = associated_element_guid, body =slim_body)
174
+ # if parent_comment_guid:
175
+ # guid = egeria_client.add_comment_reply(element_guid = parent_comment_guid, body = slim_body)
176
+ # else:
177
+ guid = egeria_client.add_comment_to_element(element_guid = associated_element_guid, body =slim_body)
176
178
 
177
179
  if guid:
178
180
  update_element_dictionary(qualified_name, {
179
181
  'guid': guid, 'display_name': display_name
180
182
  })
181
- msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
183
+ msg = f"## ==> Created Element `{display_name}` with GUID {guid}\n\n___"
182
184
  logger.success(msg)
183
185
  print(Markdown(msg))
184
186
  return egeria_client.get_comment_by_guid(guid, output_format='MD', report_spec = "Comments-DrE")
@@ -196,10 +198,11 @@ def process_add_comment_command(egeria_client: EgeriaTech, txt: str, directive:
196
198
  else:
197
199
  return None
198
200
 
199
- def process_upsert_note_log_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
201
+ def process_journal_entry_command(egeria_client: EgeriaTech, txt: str,
202
+ directive: str = "display") -> Optional[str]:
200
203
  """
201
- Processes a noteLog create or update object_action by extracting key attributes from the given text and applying
202
- this using the pyegeria function.
204
+ Creates or updates a journal entry. If the journal (NoteLog) doesn't exist, then it will be created. Each journal
205
+ entry is a note in a NoteLog.
203
206
 
204
207
  :param txt: A string representing the input cell to be processed for
205
208
  extracting glossary-related attributes.
@@ -227,10 +230,24 @@ def process_upsert_note_log_command(egeria_client: EgeriaTech, txt: str, directi
227
230
 
228
231
  attributes = parsed_output['attributes']
229
232
 
230
- display_name = attributes['Display Name'].get('value', None)
231
- description = attributes['Description'].get('value', None)
233
+ journal_name = attributes['Journal Name'].get('value', None)
234
+ journal_qn = attributes['Journal Name'].get('qualified_name', None)
235
+ journal_exists = attributes['Journal Name'].get('Exists', False)
236
+ note_entry = attributes['Note Entry'].get('value', None)
237
+ journal_description = attributes['Journal Description'].get('value', None)
238
+
232
239
  associated_element = attributes.get('Associated Element', {}).get('value', None)
233
- associated_element_guid = attributes.get('Associated Element', {}).get('guid', None)
240
+ associated_element_qn = attributes.get('Associated Element', {}).get('qualified_name', None)
241
+
242
+ if journal_exists is False:
243
+ qualified_name = None
244
+ journal_qn = None
245
+
246
+
247
+ if journal_name and note_entry:
248
+ valid = True
249
+ else:
250
+ valid = False
234
251
  #
235
252
 
236
253
  if directive == "display":
@@ -244,71 +261,29 @@ def process_upsert_note_log_command(egeria_client: EgeriaTech, txt: str, directi
244
261
 
245
262
  elif directive == "process":
246
263
  try:
247
- obj = "NoteLog"
248
-
249
- # Set the property body for a glossary collection
250
- #
251
- prop_body = set_element_prop_body(obj, qualified_name, attributes)
252
264
 
253
- if object_action == "Update":
254
- if not exists:
255
- msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
256
- f"{object_action}\n")
257
- logger.error(msg)
258
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
259
- elif not valid:
260
- msg = (" The input data is invalid and cannot be processed. \nPlease review")
265
+ if object_action == "Create":
266
+ if valid is False:
267
+ msg = "Journal name or Journal entry are missing."
261
268
  logger.error(msg)
269
+ print(msg)
262
270
  print(Markdown(f"==> Validation of {command} failed!!\n"))
263
- print(Markdown(msg))
264
- return None
265
- else:
266
- print(Markdown(
267
- f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
268
-
269
-
270
- body = set_update_body(obj, attributes)
271
- body['properties'] = prop_body
272
-
273
- egeria_client.update_note_log(associated_element_guid, body)
274
-
275
- logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
276
- update_element_dictionary(qualified_name, {
277
- 'guid': guid, 'display_name': display_name
278
- })
279
- return egeria_client.get_note_logs_by_name(filter = qualified_name, element_type="NoteLog",
280
- output_format='MD', report_spec = "NoteLog-DrE")
281
-
282
-
283
- elif object_action == "Create":
284
- if valid is False and exists:
285
- msg = (f"NoteLog `{display_name}` already exists and result document updated changing "
286
- f"`Create` to `Update` in processed output\n\n___")
287
- logger.error(msg)
288
- return update_a_command(txt, object_action, object_type, qualified_name, guid)
289
- elif not valid:
290
- msg = ("The input data is invalid and cannot be processed. \nPlease review")
291
- logger.error(msg)
292
- print(Markdown(f"==> Validation of {command} failed!!\n"))
293
- print(Markdown(msg))
294
271
  return None
295
272
 
296
273
  else:
297
- body = set_create_body(object_type,attributes)
298
274
 
299
- body["properties"] = prop_body
300
- slim_body = body_slimmer(body)
301
- guid = egeria_client.create_note_log(associated_element_guid, slim_body)
302
- if guid:
303
- update_element_dictionary(qualified_name, {
304
- 'guid': guid, 'display_name': display_name
305
- })
306
- msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
275
+ note_guid = egeria_client.add_journal_entry(note_log_qn = journal_qn,
276
+ element_qn = associated_element_qn,
277
+ note_log_display_name = journal_name,
278
+ note_entry = note_entry )
279
+ if note_guid:
280
+ msg = f"Created entry in `{journal_name}` with GUID {note_guid}\n\n___"
307
281
  logger.success(msg)
308
- return egeria_client.get_note_logs_by_name(filter = qualified_name, element_type="NoteLog",
309
- output_format='MD', report_spec = "NoteLog-DrE")
282
+ print(Markdown(msg))
283
+ return egeria_client.get_note_by_guid(note_guid,
284
+ output_format='MD', report_spec = "Journal-Entry-DrE")
310
285
  else:
311
- msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
286
+ msg = f"Failed to create entry for `{journal_name}`\n\n___"
312
287
  logger.error(msg)
313
288
  return None
314
289
 
@@ -572,8 +572,8 @@ def add_note_in_dr_e(client: Client2, qualified_name: str, display_name: str, jo
572
572
  note_log_qn = f"{qualified_name}-NoteLog"
573
573
  note_log_display_name = f"{display_name}-NoteLog"
574
574
  note_display_name = f"{qualified_name}-Journal-Entry-{datetime.now().strftime('%Y-%m-%d %H:%M')}"
575
- journal_entry_guid = client.add_journal_entry(note_log_qn, qualified_name, note_log_display_name, note_display_name,
576
- journal_entry)
575
+ journal_entry_guid = client.add_journal_entry(note_log_qn, qualified_name, note_log_display_name,
576
+ note_display_name, journal_entry)
577
577
  logger.info(f"Added journal entry `{journal_entry_guid}` to `{qualified_name}`")
578
578
  return journal_entry_guid
579
579
  else:
@@ -142,17 +142,21 @@ def extract_attribute(text: str, labels: List[str]) -> Optional[str]:
142
142
  Returns:
143
143
  The cleaned value of the attribute, or None if not found.
144
144
  """
145
+
146
+
145
147
  for label in labels:
146
- # Construct pattern for the current label
147
- pattern = rf"## {re.escape(label)}\n(.*?)(?=^##|\Z)" # Captures content until the next '##' or end of text
148
+ # Construct pattern for the current label - stops at next ##, ___ separator, or end of text
149
+ pattern = rf"## {re.escape(label)}\n(.*?)(?=^##|^_{3,}|\Z)"
148
150
  match = re.search(pattern, text, re.DOTALL | re.MULTILINE)
149
151
  if match:
150
152
  # Extract matched text
151
153
  extracted_text = match.group(1)
152
154
 
153
- # Remove lines starting with '>'
154
- filtered_lines = [line for line in extracted_text.splitlines() if not line.lstrip().startswith(">")]
155
-
155
+ # Remove lines starting with '>' and lines that are only underscores/whitespace
156
+ filtered_lines = [
157
+ line for line in extracted_text.splitlines()
158
+ if not line.lstrip().startswith(">") and not re.match(r'^\s*_+\s*$', line)
159
+ ]
156
160
  # Join the lines back, preserving single newlines
157
161
  cleaned_text = "\n".join(filtered_lines).strip()
158
162
 
@@ -6,10 +6,12 @@ import json
6
6
  import os
7
7
 
8
8
  import inflect
9
+ from loguru import logger
9
10
  from rich.markdown import Markdown
10
11
 
11
12
  from md_processing.md_processing_utils.message_constants import ERROR
12
13
  from pyegeria._globals import DEBUG_LEVEL
14
+ from pyegeria.logging_configuration import config_logging
13
15
 
14
16
  inflect_engine = inflect.engine()
15
17
 
@@ -167,7 +169,7 @@ COLLECTION_CREATE = ["Create Collection", "Update Collection", "Create Digital P
167
169
  "Update Digital Product Catalog",
168
170
  "Create Root Collection", "Update Root Collection", "Create Folder", "Update Folder",
169
171
  ]
170
- FEEDBACK_COMMANDS = ["Create Comment", "Update Comment", "Create NoteLog", "Update NoteLog", "Create Note", "Update Note",
172
+ FEEDBACK_COMMANDS = ["Create Comment", "Update Comment", "Create Journal Entry",
171
173
  "Create Informal Tag", "Update Informal Tag", "Tag Element"]
172
174
 
173
175
  command_list = ["Provenance", "Create Glossary", "Update Glossary", "Create Term", "Update Term", "List Terms",
@@ -263,9 +265,10 @@ command_seperator = Markdown("\n---\n")
263
265
  EXISTS_REQUIRED = "Exists Required"
264
266
  COMMAND_DEFINITIONS = {}
265
267
 
268
+ config_logging()
269
+ logger.enable("pyegeria")
266
270
  debug_level = DEBUG_LEVEL
267
271
 
268
-
269
272
  # def load_commands(filename: str) -> None:
270
273
  # global COMMAND_DEFINITIONS
271
274
  #
@@ -288,7 +291,8 @@ def load_commands(filename: str) -> None:
288
291
  # Validate JSON before attempting to load
289
292
  try:
290
293
  COMMAND_DEFINITIONS = json.loads(config_str)
291
- print(f"Successfully loaded {filename}")
294
+ msg = f"Successfully loaded {filename}"
295
+ logger.info(msg)
292
296
  except json.JSONDecodeError as json_err:
293
297
  # Provide detailed error information
294
298
  error_line = json_err.lineno
pyegeria/_client_new.py CHANGED
@@ -21,7 +21,7 @@ from pydantic import TypeAdapter
21
21
 
22
22
  from pyegeria._base_client import BaseClient
23
23
  from pyegeria._exceptions_new import (
24
- PyegeriaConnectionException, PyegeriaInvalidParameterException, PyegeriaException
24
+ PyegeriaConnectionException, PyegeriaInvalidParameterException, PyegeriaException, PyegeriaErrorCode
25
25
  )
26
26
  from pyegeria._globals import max_paging_size, NO_ELEMENTS_FOUND, default_time_out, COMMENT_TYPES
27
27
  from pyegeria.base_report_formats import get_report_spec_match
@@ -1317,7 +1317,6 @@ class Client2(BaseClient):
1317
1317
 
1318
1318
  def remove_comment_from_element(
1319
1319
  self,
1320
- element_guid: str,
1321
1320
  comment_guid: str,
1322
1321
  body: dict | DeleteElementRequestBody = None,
1323
1322
  cascade_delete: bool = False,
@@ -1330,8 +1329,6 @@ class Client2(BaseClient):
1330
1329
 
1331
1330
  Parameters
1332
1331
  ----------
1333
- element_guid: str
1334
- - unique id for the element
1335
1332
  comment_guid: str
1336
1333
  - unique id for the comment object
1337
1334
  body: dict | DeleteElementRequestBody, optional
@@ -1349,7 +1346,7 @@ class Client2(BaseClient):
1349
1346
  """
1350
1347
  loop = asyncio.get_event_loop()
1351
1348
  loop.run_until_complete(
1352
- self._async_remove_note_log(element_guid, body, cascade_delete=cascade_delete)
1349
+ self._async_remove_comment_from_element(comment_guid, body, cascade_delete=cascade_delete)
1353
1350
  )
1354
1351
 
1355
1352
  async def _async_get_comment_by_guid(
@@ -1794,6 +1791,7 @@ class Client2(BaseClient):
1794
1791
  "class": "NewAttachmentRequestBody",
1795
1792
  "properties": {
1796
1793
  "class": "NoteLogProperties",
1794
+ "typeName": "NoteLog",
1797
1795
  "displayName": display_name,
1798
1796
  "qualifiedName": self.make_feedback_qn("NoteLog", element_guid, display_name),
1799
1797
  "description": description,
@@ -1804,6 +1802,7 @@ class Client2(BaseClient):
1804
1802
  "class": "NewAElementRequestBody",
1805
1803
  "properties": {
1806
1804
  "class": "NoteLogProperties",
1805
+ "typeName": "NoteLog",
1807
1806
  "displayName": display_name,
1808
1807
  "qualifiedName": self.make_feedback_qn("NoteLog", element_guid, display_name),
1809
1808
  "description": description,
@@ -1817,7 +1816,7 @@ class Client2(BaseClient):
1817
1816
  if element_guid:
1818
1817
  url = f"{self.command_root}feedback-manager/elements/{element_guid}/note-logs"
1819
1818
  else:
1820
- url = f"{self.command_root}feedback-manager/elements/note-logs"
1819
+ url = f"{self.command_root}feedback-manager/note-logs"
1821
1820
  response = await self._async_make_request("POST", url, body_slimmer(body))
1822
1821
  return response.json()
1823
1822
 
@@ -2296,7 +2295,7 @@ class Client2(BaseClient):
2296
2295
  """
2297
2296
 
2298
2297
  url = f"{self.command_root}feedback-manager/note-logs/by-name"
2299
- response = await self._async_get_name_request(url, _type=element_type,
2298
+ response = await self._async_get_name_request(url, _type=element_type, filter=filter,
2300
2299
  _gen_output=self._generate_feedback_output, start_from=start_from,
2301
2300
  page_size=page_size, output_format=output_format,
2302
2301
  report_spec=report_spec,
@@ -2438,7 +2437,7 @@ class Client2(BaseClient):
2438
2437
 
2439
2438
  @dynamic_catch
2440
2439
  async def _async_create_note(self, note_log_guid: str, display_name: str = None, description: str = None,
2441
- body: dict | NewElementRequestBody = None) -> str:
2440
+ associated_element: str = None, body: dict | NewElementRequestBody = None) -> str:
2442
2441
  """
2443
2442
  Creates a new note for a note log and returns the unique identifier for it. Async version.
2444
2443
 
@@ -2450,6 +2449,8 @@ class Client2(BaseClient):
2450
2449
  - optional display name for the note
2451
2450
  description
2452
2451
  - optional description for the note
2452
+ associated_element: str, default is None
2453
+ - guid of the element to associate with the note - if provided, the note will be anchored to this element.
2453
2454
  body
2454
2455
  - optional body for the note
2455
2456
 
@@ -2501,10 +2502,11 @@ class Client2(BaseClient):
2501
2502
  }
2502
2503
 
2503
2504
  """
2505
+
2504
2506
  if body is None and display_name:
2505
2507
  body = {
2506
2508
  "class": "NewElementRequestBody",
2507
- "anchorGUID": note_log_guid,
2509
+ "anchorGUID": associated_element if associated_element else note_log_guid,
2508
2510
  "isOwnAnchor": False,
2509
2511
  "parentGUID": note_log_guid,
2510
2512
  "parentRelationshipTypeName": "AttachedNoteLogEntry",
@@ -2602,8 +2604,10 @@ class Client2(BaseClient):
2602
2604
  return response
2603
2605
 
2604
2606
  @dynamic_catch
2605
- async def _async_add_journal_entry(self, note_log_qn: str = None, element_qn: str = None, note_log_display_name: str = None, journal_entry_display_name: str = None, journal_entry_description: str = None,
2606
- body: dict | NewElementRequestBody = None ) -> str:
2607
+ async def _async_add_journal_entry(self, note_log_qn: str = None, element_qn: str = None,
2608
+ note_log_display_name: str = None, journal_entry_display_name: str = None,
2609
+ note_entry: str = None,
2610
+ body: dict | NewElementRequestBody = None) -> str:
2607
2611
  """
2608
2612
  Creates a new journal entry for a note log and returns the unique identifier for it. The note_log will be
2609
2613
  created if it does not exist. Async version.
@@ -2619,7 +2623,7 @@ class Client2(BaseClient):
2619
2623
  - optional note log display name
2620
2624
  journal_entry_display_name: str = None
2621
2625
  - optional journal entry display name
2622
- journal_entry_description: str = None
2626
+ note_entry: str = None
2623
2627
  - the journal entry text
2624
2628
 
2625
2629
  body
@@ -2683,24 +2687,29 @@ class Client2(BaseClient):
2683
2687
  if note_log_guid is None or note_log_guid == NO_ELEMENTS_FOUND:
2684
2688
  if element_qn is None:
2685
2689
  if note_log_display_name is None:
2686
- note_log_display_name = f"NoName-{datetime.now().strftime('%Y-%m-%d %H:%M')}"
2690
+ note_log_display_name = f"NoteLog-{datetime.now().strftime('%Y-%m-%d %H:%M')}"
2687
2691
 
2688
2692
  else:
2689
2693
  element_guid = await self._async_get_guid_for_name(element_qn, ["qualifiedName"])
2694
+ if element_guid is None or element_guid == NO_ELEMENTS_FOUND:
2695
+ context = { "reason" : "The specified associated element was not found"}
2696
+ raise PyegeriaException(error_code = PyegeriaErrorCode.VALIDATION_ERROR, context = context)
2690
2697
 
2691
2698
  note_log = await self._async_create_note_log(element_guid = element_guid, display_name = note_log_display_name)
2692
2699
  note_log_guid = note_log["guid"]
2693
2700
 
2694
2701
  # Create the Journal Entry (Note)
2702
+ if journal_entry_display_name is None:
2703
+ journal_entry_display_name = f"Note-{datetime.now().strftime('%Y-%m-%d %H:%M')}"
2695
2704
  journal_entry_guid = await self._async_create_note(note_log_guid, journal_entry_display_name,
2696
- journal_entry_description, body)
2705
+ note_entry, body)
2697
2706
 
2698
2707
  return journal_entry_guid
2699
2708
 
2700
2709
  @dynamic_catch
2701
2710
  def add_journal_entry(self, note_log_qn: str = None, element_qn: str = None,
2702
2711
  note_log_display_name: str = None, journal_entry_display_name: str = None,
2703
- journal_entry_description: str = None,
2712
+ note_entry: str = None,
2704
2713
  body: dict | NewElementRequestBody = None) -> str:
2705
2714
  """
2706
2715
  Creates a new journal entry for a note log and returns the unique identifier for it. The note_log will be
@@ -2717,7 +2726,7 @@ class Client2(BaseClient):
2717
2726
  - optional note log display name
2718
2727
  journal_entry_display_name: str = None
2719
2728
  - optional journal entry display name
2720
- journal_entry_description: str = None
2729
+ note_entry: str = None
2721
2730
  - the journal entry text
2722
2731
 
2723
2732
  body
@@ -2773,7 +2782,7 @@ class Client2(BaseClient):
2773
2782
  """
2774
2783
  loop = asyncio.get_event_loop()
2775
2784
  response = loop.run_until_complete(
2776
- self._async_add_journal_entry(note_log_qn, element_qn, note_log_display_name, journal_entry_display_name, journal_entry_description, body)
2785
+ self._async_add_journal_entry(note_log_qn, element_qn, note_log_display_name, journal_entry_display_name, note_entry, body)
2777
2786
  )
2778
2787
  return response
2779
2788
 
@@ -3563,9 +3572,9 @@ class Client2(BaseClient):
3563
3572
 
3564
3573
  url = f"{self.command_root}feedback-manager/tags/by-name"
3565
3574
 
3566
- response = await self._async_get_name_request(url, "InformalTag", self._generate_feedback_output,
3567
- tag_name, [], start_from,
3568
- page_size, output_format, report_spec)
3575
+ response = await self._async_get_name_request(url, self._generate_feedback_output, tag_name,
3576
+ None,start_from, page_size, output_format, report_spec
3577
+ )
3569
3578
  return response
3570
3579
 
3571
3580
  @dynamic_catch
@@ -4714,6 +4723,11 @@ class Client2(BaseClient):
4714
4723
  extra = self._extract_element_properties_for_keyword(element, columns_struct)
4715
4724
  col_data = overlay_additional_values(col_data, extra)
4716
4725
 
4726
+ note_logs = element.get("presentInNoteLogs", [])
4727
+ if note_logs != []:
4728
+ extra = self._extract_element_properties_for_notes( element, columns_struct)
4729
+ col_data = overlay_additional_values(col_data, extra)
4730
+
4717
4731
  return col_data
4718
4732
 
4719
4733
  @dynamic_catch
@@ -5667,3 +5681,46 @@ class Client2(BaseClient):
5667
5681
  get_additional_props_func=None,
5668
5682
  columns_struct=output_formats,
5669
5683
  )
5684
+
5685
+ def _extract_element_properties_for_keyword(self, element: dict, columns_struct: dict) -> dict:
5686
+ keyword_elements = None
5687
+ keyword_elements = element["keywordElements"]
5688
+ out_body = {}
5689
+ keyword = element["properties"].get('keyword', '')
5690
+ for el in keyword_elements:
5691
+ element = el.get("relatedElement", {})
5692
+ element_guid = element['elementHeader']['guid']
5693
+ element_type = element['elementHeader']['type']['typeName']
5694
+ element_display_name = element['properties'].get('displayName',"")
5695
+ element_description = element['properties'].get('description',"")
5696
+ element_category = element['properties'].get('category',"")
5697
+ out_body = {
5698
+ "element_display_name": element_display_name,
5699
+ "element_description": element_description,
5700
+ "element_category": element_category,
5701
+ "element_type": element_type,
5702
+ "element_guid": element_guid,
5703
+ "keyword": keyword
5704
+ }
5705
+ return out_body
5706
+
5707
+ def _extract_element_properties_for_notes(self, element: dict, columns_struct: dict):
5708
+ note_log_qualified_name = None
5709
+ note_log_guid = None
5710
+ note_log_display_name = None
5711
+ note_log_description = None
5712
+
5713
+ note_log_el = element.get("presentInNoteLogs",{})[0].get("relatedElement",None)
5714
+ if note_log_el:
5715
+ note_log_guid = note_log_el['elementHeader']['guid']
5716
+ note_log_display_name = note_log_el['properties'].get('displayName',"")
5717
+ note_log_qualified_name = note_log_el['properties']['qualifiedName']
5718
+ note_log_description = note_log_el['properties'].get('description',"")
5719
+
5720
+ return {
5721
+ "note_log_name": note_log_display_name,
5722
+ "note_log_description": note_log_description,
5723
+ "note_log_qualified_name": note_log_qualified_name,
5724
+ "note_log_guid": note_log_guid,
5725
+ }
5726
+
@@ -391,17 +391,25 @@ def print_basic_exception(e: PyegeriaException):
391
391
  table.add_column("Item", justify="left", width=80)
392
392
 
393
393
  if isinstance(e, PyegeriaException):
394
- table.add_row("HTTP Code", str(e.response_code))
395
- table.add_row("HTTP Reason", str(http_reason))
396
- table.add_row("Egeria Code", str(related_code))
397
- table.add_row("Caller Method", e.context.get("caller method", "---")) if e.context else ""
398
- table.add_row("Request URL", str(e.response_url))
399
- table.add_row("Egeria Message",
400
- format_dict_to_string(related_response.get('exceptionErrorMessage',"")) if isinstance(related_response,dict) else related_response)
401
- table.add_row("Egeria User Action",
402
- format_dict_to_string(related_response.get('exceptionUserAction',"")) if isinstance(related_response,dict) else related_response)
403
-
404
- exception_msg_id = related_response.get("exceptionErrorMessageId", None) if isinstance(related_response,dict) else related_response
394
+ if e.context:
395
+ table.add_row("Context", e.context.get('reason',""), style = "bold yellow")
396
+ if e.response:
397
+ table.add_row("HTTP Code", str(e.response_code))
398
+ table.add_row("HTTP Reason", str(http_reason))
399
+ table.add_row("Egeria Code", str(related_code))
400
+ table.add_row("Caller Method", e.context.get("caller method", "---")) if e.context else ""
401
+ table.add_row("Request URL", str(e.response_url))
402
+ if related_response:
403
+ if isinstance(related_response, dict):
404
+ table.add_row("Egeria Message",
405
+ format_dict_to_string(related_response.get('exceptionErrorMessage',"")))
406
+ elif isinstance(related_response, str):
407
+ table.add_row(related_response,)
408
+
409
+ table.add_row("Egeria User Action",
410
+ format_dict_to_string(related_response.get('exceptionUserAction',"")) if isinstance(related_response,dict) else related_response)
411
+
412
+ exception_msg_id = related_response.get("exceptionErrorMessageId", None) if isinstance(related_response,dict) else related_response
405
413
  table.add_row("Pyegeria Exception", exception_msg_id)
406
414
  table.add_row("Pyegeria Message", e.message)
407
415
  console.print(table)