pyegeria 5.4.0.33__py3-none-any.whl → 5.4.0.34__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 (132) hide show
  1. commands/.DS_Store +0 -0
  2. commands/cat/.DS_Store +0 -0
  3. commands/cat/.env +8 -0
  4. commands/cat/debug_log.2025-08-26_20-04-40_905576.log.zip +0 -0
  5. commands/cat/debug_log.2025-08-27_20-09-41_795022.log.zip +0 -0
  6. commands/cat/debug_log.log +898 -0
  7. commands/cat/list_format_set.py +4 -1
  8. commands/cat/logs/pyegeria.log +90 -0
  9. commands/cli/debug_log.log +0 -0
  10. commands/doc/.DS_Store +0 -0
  11. commands/ops/logs/pyegeria.log +0 -0
  12. md_processing/.DS_Store +0 -0
  13. md_processing/.idea/.gitignore +8 -0
  14. md_processing/.idea/inspectionProfiles/Project_Default.xml +59 -0
  15. md_processing/.idea/md_processing.iml +15 -0
  16. md_processing/.idea/modules.xml +8 -0
  17. md_processing/.idea/sonarlint/issuestore/index.pb +0 -0
  18. md_processing/.idea/sonarlint/securityhotspotstore/index.pb +0 -0
  19. md_processing/.idea/vcs.xml +6 -0
  20. md_processing/.idea/workspace.xml +107 -0
  21. md_processing/__init__.py +3 -2
  22. md_processing/data/commands.json +11496 -10345
  23. md_processing/dr_egeria.py +14 -6
  24. md_processing/dr_egeria_inbox/Derive-Dr-Gov-Defs.md +8 -0
  25. md_processing/dr_egeria_inbox/Dr.Egeria Templates.md +873 -0
  26. md_processing/dr_egeria_inbox/arch_test.md +57 -0
  27. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +254 -0
  28. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +696 -0
  29. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +254 -0
  30. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +298 -0
  31. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +608 -0
  32. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +94 -0
  33. md_processing/dr_egeria_inbox/archive/freddie_intro.md +284 -0
  34. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +275 -0
  35. md_processing/dr_egeria_inbox/archive/test-term.md +110 -0
  36. md_processing/dr_egeria_inbox/cat_test.md +100 -0
  37. md_processing/dr_egeria_inbox/collections.md +39 -0
  38. md_processing/dr_egeria_inbox/data_designer_debug.log +6 -0
  39. md_processing/dr_egeria_inbox/data_designer_out.md +60 -0
  40. md_processing/dr_egeria_inbox/data_designer_search_test.md +11 -0
  41. md_processing/dr_egeria_inbox/data_field.md +54 -0
  42. md_processing/dr_egeria_inbox/data_spec.md +77 -0
  43. md_processing/dr_egeria_inbox/data_spec_test.md +2406 -0
  44. md_processing/dr_egeria_inbox/data_test.md +179 -0
  45. md_processing/dr_egeria_inbox/data_test2.md +429 -0
  46. md_processing/dr_egeria_inbox/data_test3.md +462 -0
  47. md_processing/dr_egeria_inbox/dr_egeria_data_designer_1.md +124 -0
  48. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +168 -0
  49. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +280 -0
  50. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +318 -0
  51. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +1073 -0
  52. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +44 -0
  53. md_processing/dr_egeria_inbox/generated_help_report.md +9 -0
  54. md_processing/dr_egeria_inbox/glossary_list.md +5 -0
  55. md_processing/dr_egeria_inbox/glossary_search_test.md +40 -0
  56. md_processing/dr_egeria_inbox/glossary_test1.md +363 -0
  57. md_processing/dr_egeria_inbox/gov_def.md +482 -0
  58. md_processing/dr_egeria_inbox/gov_def2.md +447 -0
  59. md_processing/dr_egeria_inbox/img.png +0 -0
  60. md_processing/dr_egeria_inbox/output_tests.md +103 -0
  61. md_processing/dr_egeria_inbox/product.md +211 -0
  62. md_processing/dr_egeria_inbox/rel.md +8 -0
  63. md_processing/dr_egeria_inbox/sb.md +119 -0
  64. md_processing/dr_egeria_inbox/solution-components.md +136 -0
  65. md_processing/dr_egeria_inbox/solution_blueprints.md +118 -0
  66. md_processing/dr_egeria_inbox/synonym_test.md +42 -0
  67. md_processing/dr_egeria_inbox/t2.md +268 -0
  68. md_processing/dr_egeria_outbox/.DS_Store +0 -0
  69. md_processing/dr_egeria_outbox/.obsidian/app.json +1 -0
  70. md_processing/dr_egeria_outbox/.obsidian/appearance.json +1 -0
  71. md_processing/dr_egeria_outbox/.obsidian/community-plugins.json +7 -0
  72. md_processing/dr_egeria_outbox/.obsidian/core-plugins.json +33 -0
  73. md_processing/dr_egeria_outbox/.obsidian/plugins/buttons/main.js +5164 -0
  74. md_processing/dr_egeria_outbox/.obsidian/plugins/buttons/manifest.json +10 -0
  75. md_processing/dr_egeria_outbox/.obsidian/plugins/buttons/styles.css +624 -0
  76. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/data.json +10 -0
  77. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/main.js +4459 -0
  78. md_processing/dr_egeria_outbox/.obsidian/plugins/calendar/manifest.json +10 -0
  79. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/data.json +3 -0
  80. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/main.js +153 -0
  81. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/manifest.json +11 -0
  82. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-kanban/styles.css +1 -0
  83. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/main.js +500 -0
  84. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +12 -0
  85. md_processing/dr_egeria_outbox/.obsidian/plugins/obsidian-tasks-plugin/styles.css +1 -0
  86. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/data.json +38 -0
  87. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/main.js +37 -0
  88. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/manifest.json +11 -0
  89. md_processing/dr_egeria_outbox/.obsidian/plugins/templater-obsidian/styles.css +220 -0
  90. md_processing/dr_egeria_outbox/.obsidian/types.json +28 -0
  91. md_processing/dr_egeria_outbox/.obsidian/workspace.json +270 -0
  92. md_processing/dr_egeria_outbox/Button Test.md +11 -0
  93. md_processing/dr_egeria_outbox/Scripts/.DS_Store +0 -0
  94. md_processing/dr_egeria_outbox/Scripts/sendRest.js +24 -0
  95. md_processing/dr_egeria_outbox/Templates/sendToApi.md.md +17 -0
  96. md_processing/dr_egeria_outbox/Untitled.canvas +1 -0
  97. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  98. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  99. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  100. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  101. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:08-gov_def2.md +486 -0
  102. md_processing/dr_egeria_outbox/thursday/processed-2025-07-17 22:10-gov_def2.md +486 -0
  103. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:53-gov_def2.md +486 -0
  104. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 08:54-gov_def2.md +486 -0
  105. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:03-gov_def2.md +486 -0
  106. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:06-gov_def2.md +486 -0
  107. md_processing/dr_egeria_outbox/thursday/processed-2025-07-18 09:10-gov_def2.md +486 -0
  108. md_processing/md_commands/glossary_commands.py +2 -2
  109. md_processing/md_commands/old_project_commands.py +164 -0
  110. md_processing/md_commands/product_manager_commands.py +5 -5
  111. md_processing/md_commands/project_commands.py +368 -134
  112. md_processing/md_processing_utils/common_md_proc_utils.py +1 -0
  113. md_processing/md_processing_utils/common_md_utils.py +13 -1
  114. md_processing/md_processing_utils/debug_log +3 -574
  115. md_processing/md_processing_utils/debug_log.log +0 -0
  116. md_processing/md_processing_utils/determine_width.py +103 -0
  117. md_processing/md_processing_utils/generate_dr_help.py +44 -18
  118. md_processing/md_processing_utils/logs/pyegeria.log +56 -0
  119. md_processing/md_processing_utils/md_processing_constants.py +37 -4
  120. pyegeria/.DS_Store +0 -0
  121. pyegeria/_output_formats.py +38 -10
  122. pyegeria/glossary_manager.py +0 -2
  123. pyegeria/output_formatter.py +9 -8
  124. pyegeria/project_manager.py +541 -420
  125. {pyegeria-5.4.0.33.dist-info → pyegeria-5.4.0.34.dist-info}/METADATA +2 -1
  126. {pyegeria-5.4.0.33.dist-info → pyegeria-5.4.0.34.dist-info}/RECORD +129 -24
  127. md_processing/dr-egeria-outbox/Collections-2025-08-12-13-30-37.md +0 -163
  128. md_processing/dr-egeria-outbox/Collections-2025-08-12-13-35-58.md +0 -474
  129. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +0 -2065
  130. {pyegeria-5.4.0.33.dist-info → pyegeria-5.4.0.34.dist-info}/LICENSE +0 -0
  131. {pyegeria-5.4.0.33.dist-info → pyegeria-5.4.0.34.dist-info}/WHEEL +0 -0
  132. {pyegeria-5.4.0.33.dist-info → pyegeria-5.4.0.34.dist-info}/entry_points.txt +0 -0
@@ -1,164 +1,398 @@
1
1
  """
2
- This file contains project-related object_action functions for processing Egeria Markdown
2
+ This file contains glossary-related object_action functions for processing Egeria Markdown
3
3
  """
4
4
 
5
+ import json
6
+ import os
7
+ import re
8
+ from typing import List, Optional
9
+
10
+ from inflect import engine
11
+ from loguru import logger
12
+ from pydantic import ValidationError
13
+ from rich import print
14
+ from rich.console import Console
5
15
  from rich.markdown import Markdown
6
16
 
7
- from md_processing.md_processing_utils.common_md_utils import (debug_level, print_msg, is_valid_iso_date)
8
- from md_processing.md_processing_utils.extraction_utils import (extract_command, process_simple_attribute)
9
- from md_processing.md_processing_utils.md_processing_constants import ALWAYS, ERROR, INFO, pre_command
10
- from pyegeria._globals import NO_PROJECTS_FOUND
11
- from pyegeria.project_manager import ProjectManager
17
+ from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command,
18
+ sync_collection_memberships)
19
+ from md_processing.md_processing_utils.common_md_utils import update_element_dictionary, set_update_body, \
20
+ set_element_status_request_body, set_prop_body, set_delete_request_body, set_rel_request_body, \
21
+ set_peer_gov_def_request_body, \
22
+ set_rel_request_body, set_create_body, set_object_classifications, set_product_body, set_rel_request_body_for_type
23
+
24
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
25
+ from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
26
+ from pyegeria import DEBUG_LEVEL, body_slimmer, to_pascal_case, PyegeriaException, print_basic_exception, \
27
+ print_exception_table, print_validation_error
28
+ from pyegeria.egeria_tech_client import EgeriaTech
29
+
30
+
31
+
32
+ from md_processing.md_processing_utils.common_md_utils import (debug_level, print_msg, set_debug_level,
33
+ get_element_dictionary, update_element_dictionary,
34
+ )
35
+ from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, extract_command,
36
+ process_simple_attribute, process_element_identifiers,
37
+ update_a_command, extract_attribute,
38
+ get_element_by_name, process_name_list)
39
+ from md_processing.md_processing_utils.md_processing_constants import (GLOSSARY_NAME_LABELS, TERM_NAME_LABELS,
40
+ TERM_RELATIONSHPS, ALWAYS, ERROR, INFO,
41
+ WARNING, pre_command, EXISTS_REQUIRED,
42
+ OUTPUT_LABELS, SEARCH_LABELS, GUID_LABELS,
43
+ ELEMENT_OUTPUT_FORMATS, command_seperator)
44
+ from pyegeria import body_slimmer
45
+ from pyegeria._globals import (NO_GLOSSARIES_FOUND, NO_ELEMENTS_FOUND, NO_CATEGORIES_FOUND)
46
+ from pyegeria.egeria_tech_client import EgeriaTech
47
+
48
+ # EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "170"))
49
+ # console = Console(width=EGERIA_WIDTH)
50
+
51
+
12
52
 
13
- def process_per_proj_upsert_command(egeria_client: ProjectManager, txt: str, directive: str = "display") -> str | None:
53
+ def process_project_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
14
54
  """
15
- Processes a personal project create or update object_action by extracting key attributes such as
16
- glossary name, language, description, and usage from the given cell.
55
+ Processes a project create or update object_action by extracting key attributes such as
56
+ glossary name, language, description, and usage from the given text.
17
57
 
18
58
  :param txt: A string representing the input cell to be processed for
19
59
  extracting glossary-related attributes.
20
60
  :param directive: an optional string indicating the directive to be used - display, validate or execute
21
61
  :return: A string summarizing the outcome of the processing.
22
62
  """
23
- from md_processing.md_processing_utils.common_md_utils import set_debug_level
24
63
 
25
- command = extract_command(txt)
64
+ command, object_type, object_action = extract_command_plus(txt)
26
65
  print(Markdown(f"# {command}\n"))
27
66
 
28
- object = command.split()
29
- object_type = f"{object[1]} {object[2]}"
30
- object_action = object[0]
31
- set_debug_level(directive)
32
-
33
- project_name = process_simple_attribute(txt, ['Project Name'])
34
- description = process_simple_attribute(txt, ['Description'])
35
- project_identifier = process_simple_attribute(txt, ['Project Identifier'])
36
- project_status = process_simple_attribute(txt, ['Status'])
37
- project_phase = process_simple_attribute(txt, ['Project Phase'])
38
- project_health = process_simple_attribute(txt, ['Project Health'])
39
- start_date = process_simple_attribute(txt, ['Start Date'])
40
- planned_end_date = process_simple_attribute(txt, ['Planned End Date'])
41
- print(Markdown(f"{pre_command} `\'{command}\'` for project: `{project_name}` with directive: `{directive}` "))
42
-
43
- project_display = (f"\n* Command: {command}\n\t* Project: {project_name}\n\t"
44
- f"* Status: {project_status}\n\t* Description: {description}\n\t"
45
- f"* Phase: {project_phase}\n\t* Health: {project_health}\n\t"
46
- f"* Start Date: {start_date}\n\t* Planned End Date: {planned_end_date}\n")
47
-
48
- def validate_project(obj_action: str) -> tuple[bool, bool, str, str]:
49
- valid = True
50
- msg = ""
51
- known_guid = None
52
- known_q_name = None
53
-
54
- project_details = egeria_client.get_projects_by_name(project_name)
55
- if project_details == NO_PROJECTS_FOUND:
56
- project_exists = False
57
- else:
58
- project_exists = True
59
-
60
- if project_name is None:
61
- msg = f"* {ERROR}Project name is missing\n"
62
- valid = False
63
- if project_status is None:
64
- msg += f"* {INFO}No Project status found\n"
65
-
66
- if description is None:
67
- msg += f"* {INFO}No Description found\n"
68
-
69
- if project_identifier is None:
70
- msg += f"* {INFO}No Project Identifier found\n"
71
-
72
- if project_phase is None:
73
- msg += f"* {INFO}No Project Phase found\n"
74
-
75
- if project_health is None:
76
- msg += f"* {INFO}No Project Health found\n"
77
-
78
- if start_date is None:
79
- msg += f"* {INFO}No Start Date found\n"
80
- elif not is_valid_iso_date(start_date):
81
- msg += f"* {ERROR}Start Date is not a valid ISO date of form YYYY-MM-DD\n"
82
- valid = False
83
-
84
- if planned_end_date is None:
85
- msg += f"* {INFO} No Planned End Date found\n"
86
- elif not is_valid_iso_date(planned_end_date):
87
- msg += f"* {ERROR}Planned End Date is not a valid ISO date of form YYYY-MM-DD\n"
88
- valid = False
89
-
90
- if obj_action == "Update":
91
- q_name = process_simple_attribute(txt, 'Qualified Name')
92
-
93
- if not project_exists:
94
- msg += f"* {ERROR}Project {project_name} does not exist\n"
95
- valid = False
96
- if len(project_details) > 1 and project_exists:
97
- msg += f"* {ERROR}More than one project with name {project_name} found\n"
98
- valid = False
99
- if len(project_details) == 1:
100
- known_guid = project_details[0]['elementHeader'].get('guid', None)
101
- known_q_name = project_details[0]['glossaryProperties'].get('qualifiedName', None)
102
- if q_name is None:
103
- msg += f"* {INFO}Qualified Name is missing => can use known qualified name of {known_q_name}\n"
104
- valid = True
105
- elif q_name != known_q_name:
106
- msg += (f"* {ERROR}Project {project_name} qualifiedName mismatch between {q_name} and {known_q_name}\n")
107
- valid = False
108
- if valid:
109
- msg += project_display
110
- msg += f"* -->Project {project_name} exists and can be updated\n"
111
- else:
112
- msg += f"* --> validation failed\n"
113
- msg += '---'
114
- print(Markdown(msg))
115
- return valid, project_exists, known_guid, known_q_name
116
-
117
- elif obj_action == "Create":
118
- if project_exists:
119
- msg += f"\n{ERROR}Project {project_name} already exists"
120
- else:
121
- msg += f"\n-->It is valid to create Project \'{project_name}\' with:\n"
122
- print(Markdown(msg))
123
- return valid, project_exists, known_guid, known_q_name
67
+ parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
68
+ if not parsed_output:
69
+ logger.error(f"No output for `{object_action}`")
70
+ return None
71
+
72
+ valid = parsed_output['valid']
73
+ exists = parsed_output['exists']
74
+
75
+ qualified_name = parsed_output.get('qualified_name', None)
76
+ guid = parsed_output.get('guid', None)
77
+
78
+ print(Markdown(parsed_output['display']))
79
+
80
+ logger.debug(json.dumps(parsed_output, indent=4))
81
+
82
+ attributes = parsed_output['attributes']
83
+
84
+ display_name = attributes['Display Name'].get('value', None)
85
+ status = attributes.get('Status', {}).get('value', None)
86
+ #
124
87
 
125
88
  if directive == "display":
126
- print(Markdown(project_display))
127
89
  return None
128
90
  elif directive == "validate":
129
- valid, project_exists, known_guid, known_q_name = validate_project(object_action)
91
+ if valid:
92
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
93
+ else:
94
+ msg = f"Validation failed for object_action `{command}`\n"
130
95
  return valid
96
+
131
97
  elif directive == "process":
132
- valid, project_exists, known_guid, known_q_name = validate_project(object_action)
133
- if valid:
134
- if object_action == "Create":
135
- if project_exists:
136
- print(f"\n{ERROR}Project {project_name} already exists\n")
98
+ try:
99
+ obj = "Project"
100
+ project_types = ["Campaign", "Task", "Personal Project", "Study Project"]
101
+
102
+
103
+ # Set the property body for a glossary collection
104
+ #
105
+ prop_body = set_prop_body(obj, qualified_name, attributes)
106
+ prop_body["identifier"] = attributes.get('Identifier', {}).get('value', None)
107
+ prop_body["mission"] = attributes.get('Mission', {}).get('value', None)
108
+ prop_body["purposes"] = attributes.get('Purposes', {}).get('value', None)
109
+ prop_body["startDate"] = attributes.get('Start Date', {}).get('value', None)
110
+ prop_body["endDate"] = attributes.get('End Date', {}).get('value', None)
111
+ prop_body["priority"] = attributes.get('Priority', {}).get('value', None)
112
+ prop_body["projectPhase"] = attributes.get('Project Phase', {}).get('value', None)
113
+ prop_body["projectStatus"] = attributes.get('Project Status', {}).get('value', None)
114
+ prop_body["projectHealth"] = attributes.get('Project Health', {}).get('value', None)
115
+
116
+ if object_action == "Update":
117
+ if not exists:
118
+ msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
119
+ f"{object_action}\n")
120
+ logger.error(msg)
121
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
122
+ elif not valid:
123
+ msg = (" The input data is invalid and cannot be processed. \nPlease review")
124
+ logger.error(msg)
125
+ print(Markdown(f"==> Validation of {command} failed!!\n"))
126
+ print(Markdown(msg))
137
127
  return None
138
128
  else:
139
- project_guid = egeria_client.create_personal_project(project_name, description, project_identifier,
140
- project_status, project_phase, project_health,
141
- start_date, planned_end_date)
142
- if project_guid:
143
- print_msg(ALWAYS, f"Created Project {project_name} with GUID {project_guid}", debug_level)
144
- return egeria_client.get_project_by_guid(project_guid, output_format='MD')
145
- else:
146
- print_msg(ERROR, f"Failed to create Project {project_name}", debug_level)
147
- return None
148
- elif object_action == "Update":
149
- if not project_exists:
150
- print(f"\n{ERROR}Project {project_name} does not exist\n")
129
+ print(Markdown(
130
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
131
+
132
+
133
+ body = set_update_body(obj, attributes)
134
+ body['properties'] = prop_body
135
+
136
+ egeria_client.update_project(guid, body)
137
+ # if status:
138
+ # egeria_client.update_project_status(guid, status)
139
+
140
+ logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
141
+ update_element_dictionary(qualified_name, {
142
+ 'guid': guid, 'display_name': display_name
143
+ })
144
+ return egeria_client.get_project_by_guid(guid, element_type='Project',
145
+ output_format='MD', output_format_set = "Projects")
146
+
147
+
148
+ elif object_action == "Create":
149
+ if valid is False and exists:
150
+ msg = (f"Project `{display_name}` already exists and result document updated changing "
151
+ f"`Create` to `Update` in processed output\n\n___")
152
+ logger.error(msg)
153
+ return update_a_command(txt, object_action, object_type, qualified_name, guid)
154
+ elif not valid:
155
+ msg = ("The input data is invalid and cannot be processed. \nPlease review")
156
+ logger.error(msg)
157
+ print(Markdown(f"==> Validation of {command} failed!!\n"))
158
+ print(Markdown(msg))
151
159
  return None
160
+
152
161
  else:
153
- project_guid = egeria_client.update_personal_project(known_guid, project_name, description,
154
- project_identifier, project_status,
155
- project_phase, project_health, start_date,
156
- planned_end_date)
157
- if project_guid:
158
- print_msg(ALWAYS, f"Updated Project {project_name} with GUID {project_guid}", debug_level)
159
- return egeria_client.get_project_by_guid(project_guid, output_format='MD')
162
+ body = set_create_body(object_type,attributes)
163
+
164
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
165
+ body["initialClassifications"] = set_object_classifications(object_type, attributes, project_types)
166
+
167
+ body["properties"] = prop_body
168
+ slim_body = body_slimmer(body)
169
+ guid = egeria_client.create_project(body = slim_body)
170
+ if guid:
171
+ update_element_dictionary(qualified_name, {
172
+ 'guid': guid, 'display_name': display_name
173
+ })
174
+ msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
175
+ logger.success(msg)
176
+ return egeria_client.get_project_by_guid(guid, output_format='MD', output_format_set = "Projects")
160
177
  else:
161
- print_msg(ERROR, f"Failed to update Project {project_name}", debug_level)
178
+ msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
179
+ logger.error(msg)
162
180
  return None
181
+
182
+ except PyegeriaException as e:
183
+ logger.error(f"Pyegeria error performing {command}: {e}")
184
+ print_basic_exception(e)
185
+ return None
186
+ except Exception as e:
187
+ logger.error(f"Error performing {command}: {e}")
188
+ else:
189
+ return None
190
+
191
+
192
+
193
+ def process_link_project_hierarchy_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
194
+
195
+ # """ Set one project to manage another."""
196
+ #
197
+ command, object_type, object_action = extract_command_plus(txt)
198
+ print(Markdown(f"# {command}\n"))
199
+
200
+ parsed_output = parse_view_command(egeria_client, object_type, object_action,
201
+ txt, directive)
202
+
203
+ if not parsed_output:
204
+ logger.error(f"No output for `{object_action}`")
205
+ print(Markdown("## Parsing failed"))
206
+ return None
207
+
208
+ print(Markdown(parsed_output['display']))
209
+
210
+ logger.debug(json.dumps(parsed_output, indent=4))
211
+
212
+ attributes = parsed_output['attributes']
213
+
214
+ parent_project_guid = attributes.get('Parent Project', {}).get('guid', None)
215
+ child_project_guid = attributes.get('Child Project', {}).get('guid', None)
216
+ label = attributes.get('Link Label', {}).get('value', "")
217
+
218
+ valid = parsed_output['valid']
219
+ exists = parent_project_guid is not None and child_project_guid is not None
220
+
221
+ if directive == "display":
222
+
223
+ return None
224
+ elif directive == "validate":
225
+ if valid:
226
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
163
227
  else:
228
+ msg = f"Validation failed for object_action `{command}`\n"
229
+ logger.error(msg)
230
+ print(Markdown(f"==> Validation of {command} failed!!\n"))
231
+ return valid
232
+
233
+ elif directive == "process":
234
+
235
+
236
+ try:
237
+ if object_action == "Detach":
238
+ if not exists:
239
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
240
+ f"object_action\n")
241
+ logger.error(msg)
242
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
243
+ return out
244
+ elif not valid:
245
+ return None
246
+ else:
247
+ print(Markdown(
248
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
249
+ body = set_delete_request_body(object_type, attributes)
250
+
251
+ egeria_client.clear_project_hierarchy(child_project_guid, parent_project_guid,body)
252
+
253
+ logger.success(f"===> Detached segment with {label} from `{child_project_guid}`to {parent_project_guid}\n")
254
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
255
+
256
+ return (out)
257
+
258
+
259
+ elif object_action == "Link":
260
+ if valid is False and exists:
261
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
262
+ f"`Link` to `Detach` in processed output\n")
263
+ logger.error(msg)
264
+
265
+ elif valid is False:
266
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
267
+ logger.error(msg)
268
+ return
269
+
270
+ else:
271
+ body = set_rel_request_body_for_type("Project", attributes)
272
+
273
+ egeria_client.set_project_hierarchy(project_guid =child_project_guid,
274
+ parent_project_guid = parent_project_guid,
275
+ body=body_slimmer(body))
276
+ msg = f"==>Created {object_type} link named `{label}`\n"
277
+ logger.success(msg)
278
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
279
+ return out
280
+
281
+ except ValidationError as e:
282
+ print_validation_error(e)
283
+ logger.error(f"Validation Error performing {command}: {e}")
284
+ return None
285
+ except PyegeriaException as e:
286
+ print_basic_exception(e)
287
+ logger.error(f"PyegeriaException occurred: {e}")
288
+ return None
289
+
290
+ except Exception as e:
291
+ logger.error(f"Error performing {command}: {e}")
164
292
  return None
293
+ else:
294
+ return None
295
+
296
+
297
+
298
+ def process_link_project_dependency_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
299
+
300
+ # """ Set one project to manage another."""
301
+ #
302
+ command, object_type, object_action = extract_command_plus(txt)
303
+ print(Markdown(f"# {command}\n"))
304
+
305
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
306
+
307
+ if not parsed_output:
308
+ logger.error(f"No output for `{object_action}`")
309
+ print(Markdown("## Parsing failed"))
310
+ return None
311
+
312
+ print(Markdown(parsed_output['display']))
313
+
314
+ logger.debug(json.dumps(parsed_output, indent=4))
315
+
316
+ attributes = parsed_output['attributes']
317
+
318
+ parent_project_guid = attributes.get('Parent Project', {}).get('guid', None)
319
+ child_project_guid = attributes.get('Child Project', {}).get('guid', None)
320
+ label = attributes.get('Link Label', {}).get('value', "")
321
+
322
+ valid = parsed_output['valid']
323
+ exists = parent_project_guid is not None and child_project_guid is not None
324
+
325
+ if directive == "display":
326
+
327
+ return None
328
+ elif directive == "validate":
329
+ if valid:
330
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
331
+ else:
332
+ msg = f"Validation failed for object_action `{command}`\n"
333
+ logger.error(msg)
334
+ print(Markdown(f"==> Validation of {command} failed!!\n"))
335
+ return valid
336
+
337
+ elif directive == "process":
338
+
339
+
340
+ try:
341
+ if object_action == "Detach":
342
+ if not exists:
343
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
344
+ f"object_action\n")
345
+ logger.error(msg)
346
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
347
+ return out
348
+ elif not valid:
349
+ return None
350
+ else:
351
+ print(Markdown(
352
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
353
+ body = set_delete_request_body(object_type, attributes)
354
+
355
+ egeria_client.clear_project_dependency(child_project_guid, parent_project_guid,body)
356
+
357
+ logger.success(f"===> Detached segment with {label} from `{child_project_guid}`to {parent_project_guid}\n")
358
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
359
+
360
+ return (out)
361
+
362
+
363
+ elif object_action == "Link":
364
+ if valid is False and exists:
365
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
366
+ f"`Link` to `Detach` in processed output\n")
367
+ logger.error(msg)
368
+
369
+ elif valid is False:
370
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
371
+ logger.error(msg)
372
+ return
373
+
374
+ else:
375
+ body = set_rel_request_body_for_type("Project", attributes)
376
+
377
+ egeria_client.set_project_dependency(project_guid =child_project_guid,
378
+ parent_project_guid = parent_project_guid,
379
+ body=body_slimmer(body))
380
+ msg = f"==>Created {object_type} link named `{label}`\n"
381
+ logger.success(msg)
382
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
383
+ return out
384
+
385
+ except ValidationError as e:
386
+ print_validation_error(e)
387
+ logger.error(f"Validation Error performing {command}: {e}")
388
+ return None
389
+ except PyegeriaException as e:
390
+ print_basic_exception(e)
391
+ logger.error(f"PyegeriaException occurred: {e}")
392
+ return None
393
+
394
+ except Exception as e:
395
+ logger.error(f"Error performing {command}: {e}")
396
+ return None
397
+ else:
398
+ return None
@@ -282,6 +282,7 @@ def parse_view_command(egeria_client: EgeriaTech, object_type: str, object_actio
282
282
  command_spec = get_command_spec(f"Link {object_type}")
283
283
  else:
284
284
  command_spec = get_command_spec(f"{object_action} {object_type}")
285
+
285
286
  attributes = command_spec.get('Attributes', [])
286
287
  command_display_name = command_spec.get('display_name', None)
287
288
 
@@ -419,6 +419,18 @@ def set_peer_gov_def_request_body(object_type: str, attributes: dict)->dict:
419
419
  }
420
420
  return rel_body
421
421
 
422
+ def set_rel_request_body_for_type(object_type: str, attributes: dict)->dict:
423
+ rel_body = set_rel_request_body(object_type, attributes)
424
+ class_prop = camel_to_title_case(object_type) + "Properties"
425
+ rel_body["properties"] = {
426
+ "class" : class_prop,
427
+ "description": attributes.get('Description', {}).get('value', None),
428
+ "effectiveFrom": attributes.get('Effective From', {}).get('value', None),
429
+ "effectiveTo": attributes.get('Effective To', {}).get('value', None),
430
+ "label": attributes.get('Label', {}).get('value', None),
431
+ }
432
+ return rel_body
433
+
422
434
  def set_delete_request_body(object_type: str, attributes: dict)->dict:
423
435
  return {
424
436
  "class": "DeleteRequestBody",
@@ -463,7 +475,7 @@ def set_classifications(object_type: str, attributes: dict)->dict:
463
475
  body = {classification: {} for classification in classifications} if cclassifications else {}
464
476
  return body
465
477
 
466
- def set_collection_classifications(object_type: str, attributes: dict, obj_types: list[str])->dict:
478
+ def set_object_classifications(object_type: str, attributes: dict, obj_types: list[str])->dict:
467
479
  classifications = attributes.get('Classifications', {}).get('name_list', None)
468
480
  obj = object_type.replace(" ", "")
469
481
  if object_type in obj_types: