pyegeria 5.3.9.9.3__py3-none-any.whl → 5.5.3.3__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 (272) hide show
  1. commands/__init__.py +24 -0
  2. commands/cat/Dr-Egeria_md-orig.py +2 -2
  3. commands/cat/__init__.py +1 -17
  4. commands/cat/collection_actions.py +197 -0
  5. commands/cat/dr_egeria_command_help.py +372 -0
  6. commands/cat/dr_egeria_jupyter.py +7 -7
  7. commands/cat/dr_egeria_md.py +27 -182
  8. commands/cat/exp_list_glossaries.py +11 -14
  9. commands/cat/get_asset_graph.py +37 -267
  10. commands/cat/{get_collection.py → get_collection_tree.py} +10 -18
  11. commands/cat/get_project_dependencies.py +14 -14
  12. commands/cat/get_project_structure.py +15 -14
  13. commands/cat/get_tech_type_elements.py +16 -116
  14. commands/cat/glossary_actions.py +145 -298
  15. commands/cat/list_assets.py +3 -11
  16. commands/cat/list_cert_types.py +17 -63
  17. commands/cat/list_collections.py +46 -138
  18. commands/cat/list_deployed_catalogs.py +15 -27
  19. commands/cat/list_deployed_database_schemas.py +27 -43
  20. commands/cat/list_deployed_databases.py +16 -31
  21. commands/cat/list_deployed_servers.py +35 -54
  22. commands/cat/list_glossaries.py +18 -17
  23. commands/cat/list_projects.py +10 -12
  24. commands/cat/list_tech_type_elements.py +21 -37
  25. commands/cat/list_tech_types.py +13 -25
  26. commands/cat/list_terms.py +38 -79
  27. commands/cat/list_todos.py +4 -11
  28. commands/cat/list_user_ids.py +3 -10
  29. commands/cat/my_reports.py +559 -0
  30. commands/cat/run_report.py +394 -0
  31. commands/cat/run_report_orig.py +528 -0
  32. commands/cli/egeria.py +222 -247
  33. commands/cli/egeria_cat.py +68 -81
  34. commands/cli/egeria_my.py +13 -0
  35. commands/cli/egeria_ops.py +69 -74
  36. commands/cli/egeria_tech.py +17 -93
  37. commands/cli/ops_config.py +3 -6
  38. commands/{cat/list_categories.py → deprecated/list_data_designer.py} +53 -64
  39. commands/{cat/list_data_structures.py → deprecated/list_data_structures_full.py} +3 -6
  40. commands/deprecated/old_get_asset_graph.py +315 -0
  41. commands/my/__init__.py +0 -2
  42. commands/my/list_my_profile.py +27 -34
  43. commands/my/list_my_roles.py +1 -7
  44. commands/my/monitor_my_todos.py +1 -7
  45. commands/my/monitor_open_todos.py +6 -7
  46. commands/my/todo_actions.py +4 -5
  47. commands/ops/__init__.py +0 -2
  48. commands/ops/gov_server_actions.py +17 -21
  49. commands/ops/list_archives.py +17 -38
  50. commands/ops/list_catalog_targets.py +33 -40
  51. commands/ops/load_archive.py +35 -26
  52. commands/ops/{monitor_engine_activity_c.py → monitor_active_engine_activity.py} +51 -82
  53. commands/ops/{monitor_integ_daemon_status.py → monitor_daemon_status.py} +35 -55
  54. commands/ops/monitor_engine_activity.py +79 -77
  55. commands/ops/{monitor_gov_eng_status.py → monitor_engine_status.py} +10 -7
  56. commands/ops/monitor_platform_status.py +38 -50
  57. commands/ops/monitor_server_startup.py +6 -11
  58. commands/ops/monitor_server_status.py +7 -11
  59. commands/ops/orig_monitor_server_list.py +8 -8
  60. commands/ops/orig_monitor_server_status.py +1 -5
  61. commands/ops/refresh_integration_daemon.py +5 -5
  62. commands/ops/restart_integration_daemon.py +5 -5
  63. commands/ops/table_integ_daemon_status.py +6 -6
  64. commands/ops/x_engine_actions.py +7 -7
  65. commands/tech/__init__.py +0 -2
  66. commands/tech/{generic_actions.py → element_actions.py} +6 -11
  67. commands/tech/get_element_info.py +20 -29
  68. commands/tech/get_guid_info.py +23 -42
  69. commands/tech/get_tech_details.py +20 -35
  70. commands/tech/get_tech_type_template.py +28 -39
  71. commands/tech/list_all_om_type_elements.py +24 -30
  72. commands/tech/list_all_om_type_elements_x.py +22 -28
  73. commands/tech/list_all_related_elements.py +19 -28
  74. commands/tech/list_anchored_elements.py +22 -30
  75. commands/tech/list_asset_types.py +19 -24
  76. commands/tech/list_elements_by_classification_by_property_value.py +26 -32
  77. commands/tech/list_elements_by_property_value.py +19 -25
  78. commands/tech/list_elements_by_property_value_x.py +20 -28
  79. commands/tech/list_elements_for_classification.py +28 -41
  80. commands/tech/list_gov_action_processes.py +16 -27
  81. commands/tech/list_information_supply_chains.py +22 -30
  82. commands/tech/list_registered_services.py +14 -26
  83. commands/tech/list_related_elements_with_prop_value.py +15 -25
  84. commands/tech/list_related_specification.py +1 -4
  85. commands/tech/list_relationship_types.py +15 -25
  86. commands/tech/list_relationships.py +20 -36
  87. commands/tech/list_solution_blueprints.py +28 -33
  88. commands/tech/list_solution_components.py +23 -29
  89. commands/tech/list_solution_roles.py +21 -32
  90. commands/tech/list_tech_templates.py +51 -54
  91. commands/tech/list_valid_metadata_values.py +5 -9
  92. commands/tech/table_tech_templates.py +2 -6
  93. commands/tech/x_list_related_elements.py +1 -4
  94. examples/GeoSpatial Products Example.py +524 -0
  95. examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
  96. examples/Jupyter Notebooks/README.md +2 -0
  97. examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
  98. examples/Jupyter Notebooks/common/__init__.py +14 -0
  99. examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
  100. examples/Jupyter Notebooks/common/environment-check.ipynb +52 -0
  101. examples/Jupyter Notebooks/common/globals.ipynb +184 -0
  102. examples/Jupyter Notebooks/common/globals.py +154 -0
  103. examples/Jupyter Notebooks/common/orig_globals.py +152 -0
  104. examples/format_sets/all_format_sets.json +910 -0
  105. examples/format_sets/custom_format_sets.json +268 -0
  106. examples/format_sets/subset_format_sets.json +187 -0
  107. examples/format_sets_save_load_example.py +291 -0
  108. examples/jacquard_data_sets.py +129 -0
  109. examples/output_formats_example.py +193 -0
  110. examples/test_jacquard_data_sets.py +54 -0
  111. examples/test_jacquard_data_sets_scenarios.py +94 -0
  112. md_processing/__init__.py +90 -0
  113. md_processing/command_dispatcher.py +33 -0
  114. md_processing/command_mapping.py +221 -0
  115. md_processing/data/commands/commands_data_designer.json +537 -0
  116. md_processing/data/commands/commands_external_reference.json +733 -0
  117. md_processing/data/commands/commands_feedback.json +155 -0
  118. md_processing/data/commands/commands_general.json +204 -0
  119. md_processing/data/commands/commands_glossary.json +218 -0
  120. md_processing/data/commands/commands_governance.json +3678 -0
  121. md_processing/data/commands/commands_product_manager.json +865 -0
  122. md_processing/data/commands/commands_project.json +642 -0
  123. md_processing/data/commands/commands_solution_architect.json +366 -0
  124. md_processing/data/commands.json +17568 -0
  125. md_processing/data/commands_working.json +30641 -0
  126. md_processing/data/gened_report_specs.py +6584 -0
  127. md_processing/data/generated_format_sets.json +6533 -0
  128. md_processing/data/generated_format_sets_old.json +4137 -0
  129. md_processing/data/generated_format_sets_old.py +45 -0
  130. md_processing/dr_egeria.py +182 -0
  131. md_processing/md_commands/__init__.py +3 -0
  132. md_processing/md_commands/data_designer_commands.py +1276 -0
  133. md_processing/md_commands/ext_ref_commands.py +530 -0
  134. md_processing/md_commands/feedback_commands.py +726 -0
  135. md_processing/md_commands/glossary_commands.py +684 -0
  136. md_processing/md_commands/governance_officer_commands.py +600 -0
  137. md_processing/md_commands/product_manager_commands.py +1266 -0
  138. md_processing/md_commands/project_commands.py +383 -0
  139. md_processing/md_commands/solution_architect_commands.py +1184 -0
  140. md_processing/md_commands/view_commands.py +295 -0
  141. md_processing/md_processing_utils/__init__.py +4 -0
  142. md_processing/md_processing_utils/common_md_proc_utils.py +1249 -0
  143. md_processing/md_processing_utils/common_md_utils.py +578 -0
  144. md_processing/md_processing_utils/determine_width.py +103 -0
  145. md_processing/md_processing_utils/extraction_utils.py +547 -0
  146. md_processing/md_processing_utils/gen_report_specs.py +643 -0
  147. md_processing/md_processing_utils/generate_dr_help.py +193 -0
  148. md_processing/md_processing_utils/generate_md_cmd_templates.py +144 -0
  149. md_processing/md_processing_utils/generate_md_templates.py +83 -0
  150. md_processing/md_processing_utils/md_processing_constants.py +1228 -0
  151. md_processing/md_processing_utils/message_constants.py +19 -0
  152. pyegeria/__init__.py +201 -443
  153. pyegeria/core/__init__.py +40 -0
  154. pyegeria/core/_base_platform_client.py +574 -0
  155. pyegeria/core/_base_server_client.py +573 -0
  156. pyegeria/core/_exceptions.py +457 -0
  157. pyegeria/core/_globals.py +60 -0
  158. pyegeria/core/_server_client.py +6073 -0
  159. pyegeria/core/_validators.py +257 -0
  160. pyegeria/core/config.py +654 -0
  161. pyegeria/{create_tech_guid_lists.py → core/create_tech_guid_lists.py} +0 -1
  162. pyegeria/core/load_config.py +37 -0
  163. pyegeria/core/logging_configuration.py +207 -0
  164. pyegeria/core/mcp_adapter.py +144 -0
  165. pyegeria/core/mcp_server.py +212 -0
  166. pyegeria/core/utils.py +405 -0
  167. pyegeria/deprecated/__init__.py +0 -0
  168. pyegeria/{_client.py → deprecated/_client.py} +62 -24
  169. pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
  170. pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1988 -1878
  171. pyegeria/deprecated/output_formatter_with_machine_keys.py +1127 -0
  172. pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +216 -229
  173. pyegeria/{valid_metadata_omvs.py → deprecated/valid_metadata_omvs.py} +93 -93
  174. pyegeria/{x_action_author_omvs.py → deprecated/x_action_author_omvs.py} +2 -3
  175. pyegeria/egeria_cat_client.py +25 -51
  176. pyegeria/egeria_client.py +140 -98
  177. pyegeria/egeria_config_client.py +48 -24
  178. pyegeria/egeria_tech_client.py +170 -83
  179. pyegeria/models/__init__.py +150 -0
  180. pyegeria/models/collection_models.py +168 -0
  181. pyegeria/models/models.py +654 -0
  182. pyegeria/omvs/__init__.py +84 -0
  183. pyegeria/omvs/action_author.py +342 -0
  184. pyegeria/omvs/actor_manager.py +5980 -0
  185. pyegeria/omvs/asset_catalog.py +842 -0
  186. pyegeria/omvs/asset_maker.py +2736 -0
  187. pyegeria/omvs/automated_curation.py +4403 -0
  188. pyegeria/omvs/classification_manager.py +11213 -0
  189. pyegeria/omvs/collection_manager.py +5780 -0
  190. pyegeria/omvs/community_matters_omvs.py +468 -0
  191. pyegeria/{core_omag_server_config.py → omvs/core_omag_server_config.py} +157 -157
  192. pyegeria/{data_designer_omvs.py → omvs/data_designer.py} +1991 -1691
  193. pyegeria/omvs/data_discovery.py +869 -0
  194. pyegeria/omvs/data_engineer.py +372 -0
  195. pyegeria/omvs/digital_business.py +1133 -0
  196. pyegeria/omvs/external_links.py +1752 -0
  197. pyegeria/omvs/feedback_manager.py +834 -0
  198. pyegeria/{full_omag_server_config.py → omvs/full_omag_server_config.py} +73 -69
  199. pyegeria/omvs/glossary_manager.py +3231 -0
  200. pyegeria/omvs/governance_officer.py +3009 -0
  201. pyegeria/omvs/lineage_linker.py +314 -0
  202. pyegeria/omvs/location_arena.py +1525 -0
  203. pyegeria/omvs/metadata_expert.py +668 -0
  204. pyegeria/omvs/metadata_explorer_omvs.py +2943 -0
  205. pyegeria/omvs/my_profile.py +1042 -0
  206. pyegeria/omvs/notification_manager.py +358 -0
  207. pyegeria/omvs/people_organizer.py +394 -0
  208. pyegeria/{platform_services.py → omvs/platform_services.py} +113 -193
  209. pyegeria/omvs/product_manager.py +1825 -0
  210. pyegeria/omvs/project_manager.py +1907 -0
  211. pyegeria/omvs/reference_data.py +1140 -0
  212. pyegeria/omvs/registered_info.py +334 -0
  213. pyegeria/omvs/runtime_manager.py +2817 -0
  214. pyegeria/omvs/schema_maker.py +446 -0
  215. pyegeria/{server_operations.py → omvs/server_operations.py} +27 -26
  216. pyegeria/omvs/solution_architect.py +6490 -0
  217. pyegeria/omvs/specification_properties.py +37 -0
  218. pyegeria/omvs/subject_area.py +1042 -0
  219. pyegeria/omvs/template_manager_omvs.py +236 -0
  220. pyegeria/omvs/time_keeper.py +1761 -0
  221. pyegeria/omvs/valid_metadata.py +3221 -0
  222. pyegeria/omvs/valid_metadata_lists.py +37 -0
  223. pyegeria/omvs/valid_type_lists.py +37 -0
  224. pyegeria/view/__init__.py +28 -0
  225. pyegeria/view/_output_format_models.py +514 -0
  226. pyegeria/view/_output_formats.py +14 -0
  227. pyegeria/view/base_report_formats.py +2719 -0
  228. pyegeria/view/dr_egeria_reports.py +56 -0
  229. pyegeria/view/format_set_executor.py +397 -0
  230. pyegeria/{md_processing_utils.py → view/md_processing_utils.py} +5 -5
  231. pyegeria/{mermaid_utilities.py → view/mermaid_utilities.py} +2 -154
  232. pyegeria/view/output_formatter.py +1297 -0
  233. pyegeria-5.5.3.3.dist-info/METADATA +218 -0
  234. pyegeria-5.5.3.3.dist-info/RECORD +241 -0
  235. {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info}/WHEEL +2 -1
  236. pyegeria-5.5.3.3.dist-info/entry_points.txt +103 -0
  237. pyegeria-5.5.3.3.dist-info/top_level.txt +4 -0
  238. commands/cat/.DS_Store +0 -0
  239. commands/cat/README.md +0 -16
  240. commands/cli/txt_custom_v2.tcss +0 -19
  241. commands/my/README.md +0 -17
  242. commands/ops/README.md +0 -24
  243. commands/ops/monitor_asset_events.py +0 -108
  244. commands/tech/README.md +0 -24
  245. pyegeria/.DS_Store +0 -0
  246. pyegeria/README.md +0 -35
  247. pyegeria/_globals.py +0 -47
  248. pyegeria/_validators.py +0 -385
  249. pyegeria/asset_catalog_omvs.py +0 -864
  250. pyegeria/automated_curation_omvs.py +0 -3765
  251. pyegeria/collection_manager_omvs.py +0 -2744
  252. pyegeria/dr.egeria spec.md +0 -9
  253. pyegeria/egeria_my_client.py +0 -56
  254. pyegeria/feedback_manager_omvs.py +0 -4573
  255. pyegeria/glossary_browser_omvs.py +0 -3728
  256. pyegeria/glossary_manager_omvs.py +0 -2440
  257. pyegeria/m_test.py +0 -118
  258. pyegeria/md_processing_helpers.py +0 -58
  259. pyegeria/md_processing_utils_orig.py +0 -1103
  260. pyegeria/metadata_explorer_omvs.py +0 -2326
  261. pyegeria/my_profile_omvs.py +0 -1022
  262. pyegeria/output_formatter.py +0 -389
  263. pyegeria/project_manager_omvs.py +0 -1933
  264. pyegeria/registered_info.py +0 -167
  265. pyegeria/solution_architect_omvs.py +0 -2156
  266. pyegeria/template_manager_omvs.py +0 -1414
  267. pyegeria/utils.py +0 -197
  268. pyegeria-5.3.9.9.3.dist-info/METADATA +0 -72
  269. pyegeria-5.3.9.9.3.dist-info/RECORD +0 -143
  270. pyegeria-5.3.9.9.3.dist-info/entry_points.txt +0 -99
  271. /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
  272. {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,457 @@
1
+ """
2
+ SPDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+
5
+ Definitions, utilities and exceptions in support of the Egeria Python Client package.
6
+
7
+ """
8
+ import os
9
+ import json
10
+ from enum import Enum
11
+
12
+ from httpx import Response
13
+ from loguru import logger
14
+ from pydantic_core import ValidationError
15
+ from rich.markdown import Markdown
16
+ from rich.table import Table
17
+ from rich.text import Text
18
+ from rich import print, box
19
+ from rich.console import Console
20
+
21
+
22
+ # Standardize on CONSOLE_WIDTH with backward-compatible fallback
23
+ try:
24
+ _width_val = int(os.getenv("CONSOLE_WIDTH", os.getenv("PYEGERIA_CONSOLE_WIDTH", 190)))
25
+ except Exception:
26
+ _width_val = 250
27
+ console = Console(width=_width_val)
28
+
29
+ """
30
+
31
+ The following definitions are used in creating Exception messages.
32
+ They mirror similar definitions in the Egeria core.
33
+ Note that not all of the definitions are currently used - they merely serve as placeholders for future extensions.
34
+
35
+ """
36
+ class PyegeriaErrorCode(Enum):
37
+ """Egeria error codes"""
38
+ CLIENT_ERROR = {
39
+ "http_code": 400,
40
+ "egeria_code": "From Egeria",
41
+ "message_id": "CLIENT_ERROR_400",
42
+ "message_template": "Client error occurred with status code `{0}`.",
43
+ "system_action": "The client is unable to connect to the Egeria platform.",
44
+ "user_action": "Check the URL to ensure the valid platform url, server, user id are correct.",
45
+ }
46
+ VALIDATION_ERROR = {
47
+ "http_code": 0,
48
+ "egeria_code": "From Egeria",
49
+ "message_id": "VALIDATION_ERROR_1",
50
+ "message_template": "Invalid parameters were provided -> `{0}`.",
51
+ "system_action": "The parameters provided were invalid.",
52
+ "user_action": "Check that your parameters are correct - please see documentation, if unsure.",
53
+ }
54
+ AUTHORIZATION_ERROR = {
55
+ "http_code": 401,
56
+ "pyegeria_code": "From Egeria",
57
+ "message_id": "AUTHORIZATION_ERROR_401",
58
+ "message_template": "User not authorized received for user - `{0}`.",
59
+ "system_action": "The user credentials provided were not authorized.",
60
+ "user_action": "Check that your user credentials are correct - please see documentation, if unsure.",
61
+ }
62
+ AUTHENTICATION_ERROR = {
63
+ "http_code": 403,
64
+ "egeria_code": "From Egeria",
65
+ "message_id": "AUTHENTICATION_ERROR_403",
66
+ "message_template": "User not authenticated received for user - `{0}`.",
67
+ "system_action": "The user credentials provided were not authenticated.",
68
+ "user_action": "Check that your user credentials and token are valid - please see documentation, if unsure.",
69
+ }
70
+ CONNECTION_ERROR = {
71
+ "http_code": 404,
72
+ "egeria_code": "Connection error",
73
+ "message_id": "CONNECTION_ERROR_1",
74
+ "message_template": "Client failed to connect to the Egeria platform using URL `{0}`.",
75
+ "system_action": "The client is unable to connect to the Egeria platform.",
76
+ "user_action": "Check the URL to ensure the valid platform url, server, user id are correct.",
77
+ }
78
+ EGERIA_ERROR = {
79
+ "http_code": 500,
80
+ "egeria_code": "From Egeria",
81
+ "message_id": "SERVER_ERROR_500",
82
+ "message_template": "Egeria detected error: `{0}`.",
83
+ "system_action": "Server-side issue requires attention.",
84
+ "user_action": "Contact server support."
85
+ }
86
+
87
+ def __str__(self):
88
+ return (
89
+ "\nhttp_code= "
90
+ + str(self.value["http_code"])
91
+ + "\n\t* messageId= "
92
+ + self.value["message_id"]
93
+ + ",\n\t message= "
94
+ + self.value["message_template"]
95
+ + ",\n\t systemAction= "
96
+ + self.value["system_action"]
97
+ + ",\n\t userAction= "
98
+ + self.value["user_action"]
99
+ )
100
+ colors = ["blue", "red", "green"]
101
+
102
+ def print_bullet_list_colored(items, colors)->Text:
103
+ for i, item in enumerate(items):
104
+ bullet_text = Text(f"\t• ", style="bold yellow")
105
+ wrapped_text = Text(item, style=colors[i % len(colors)]) # Rotate colors
106
+ bullet_text.append(wrapped_text)
107
+ return bullet_text
108
+
109
+ def print_bullet_list(items)->Text:
110
+ for key, value in items:
111
+ bullet_text = Text(f"\t• {key}", style="bold yellow")
112
+ wrapped_text = Text(value, style= "blue")
113
+ bullet_text.append(wrapped_text)
114
+ console.print(bullet_text)
115
+ return bullet_text
116
+
117
+
118
+ def flatten_dict_to_string(d: dict) -> str:
119
+ """Flatten a dictionary into a string and replace quotes with backticks."""
120
+ try:
121
+ if d:
122
+ flat_string = "\n\t".join(
123
+ # Change replace(\"'\", '`') to replace("'", '`')
124
+ f"\t* {key}=`{str(value).replace('\"', '`').replace("'", '`')}`"
125
+ for key, value in d.items()
126
+ )
127
+ return flat_string
128
+ else:
129
+ return ""
130
+ except Exception as e:
131
+ # Corrected syntax for exception chaining
132
+ raise Exception("Error flattening dictionary") from e
133
+
134
+ def format_dict_to_string(d: dict) -> str:
135
+ """
136
+ Converts a dictionary into a printable string of name-value pairs.
137
+ Replaces quotes with backticks and removes braces.
138
+
139
+ Args:
140
+ d (dict): The input dictionary.
141
+
142
+ Returns:
143
+ str: A formatted printable string.
144
+ """
145
+ if isinstance(d, dict):
146
+ name_value_set = {
147
+ f"`{str(value).replace('\"', '`').replace("'", '`')}`"
148
+ for key, value in d.items()
149
+ }
150
+ # Join the set elements into a single printable string
151
+ return ", ".join(name_value_set)
152
+ else:
153
+ return str(d)
154
+
155
+
156
+ class PyegeriaException(Exception):
157
+ """Base exception for My REST Library errors."""
158
+
159
+ def __init__(self, response:Response = None, error_code: PyegeriaErrorCode = None,
160
+ context: dict = None, additional_info:dict = None, e:Exception = None) -> None:
161
+ if response:
162
+ self.response = response
163
+ self.response_url = getattr(response, "url", "unknown URL") if response else additional_info.get("endpoint", "")
164
+ self.response_code = getattr(response, "status_code", "unknown status code") if response else ""
165
+ self.response_reason_phrase = getattr(response, "reason_phrase", "unknown reason")
166
+ self.http_status_code = getattr(response, "status_code", "unknown status code")
167
+ if self.http_status_code == 200:
168
+ self.response_egeria_msg_id = response.json().get("exceptionErrorMessageId", "")
169
+ self.response_egeria_msg = response.json().get("exceptionErrorMessage", "")
170
+ else:
171
+ self.response = None
172
+ self.response_url = ""
173
+ self.response_code = ""
174
+ self.response_egeria_msg_id = ""
175
+ self.response_egeria_msg = ""
176
+ self.error_code = error_code
177
+ self.error_details = error_code.value
178
+ self.pyegeria_code = self.error_details.get("message_id", "UNKNOWN_ERROR")
179
+
180
+ self.message = self.error_details["message_template"].format(self.response_url, self.response_code)
181
+ self.system_action = self.error_details.get("system_action", "")
182
+ self.user_action = self.error_details.get("user_action", "")
183
+ # self.original_exception = context.get("exception", {}) if context else None
184
+ self.context = context
185
+ self.additional_info = additional_info or {}
186
+ self.e = e
187
+
188
+
189
+ def __str__(self):
190
+ msg = "\n"
191
+ # ctx_str = flatten_dict_to_string(self.context)
192
+ ctx_str = flatten_dict_to_string(self.context)
193
+
194
+ msg += f"\n=> \t{self.pyegeria_code}"
195
+ msg += f"\n=>\t{self.message}"
196
+ msg += f"\n\t* Context: \n\t{ctx_str}\n"
197
+
198
+ related_http_code = self.additional_info.get('relatedHTTPCode', None)
199
+ if related_http_code:
200
+ if related_http_code != 200:
201
+ msg += f"\t* Egeria error information: \n"
202
+ for key, value in self.additional_info.items():
203
+ msg += f"\t* {key}= `{str(value).replace('\"', '`').replace("'", '`')}`\n"
204
+
205
+ else:
206
+ msg += f"\t* System Action: {self.system_action}\n"
207
+ msg += f"\t* User Action: {self.user_action}\n"
208
+ if self.response:
209
+ msg += f"\t* HTTP Code: {self.response_code}\n"
210
+ return msg
211
+
212
+
213
+ class PyegeriaConnectionException(PyegeriaException):
214
+ """Raised when there's an issue connecting to an Egeria Platform."""
215
+ def __init__(self, context: dict = None, additional_info:dict = None, e: Exception = None) -> None:
216
+ super().__init__(None, PyegeriaErrorCode.CONNECTION_ERROR,
217
+ context, additional_info, e)
218
+ self.message = self.error_details["message_template"].format(self.response_url)
219
+ logger.info(self.__str__())
220
+
221
+ class PyegeriaInvalidParameterException(PyegeriaException):
222
+ """Raised for invalid parameters - parameters that might be missing or incorrect."""
223
+ def __init__(self, response: Response = None,
224
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
225
+ super().__init__(response, PyegeriaErrorCode.VALIDATION_ERROR,
226
+ context, additional_info, e)
227
+ self.message = self.error_details["message_template"].format(self.additional_info.get('reason', ''))
228
+ logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
229
+
230
+ class PyegeriaClientException(PyegeriaException):
231
+ """Raised for invalid parameters - parameters that might be missing or incorrect."""
232
+ def __init__(self, response: Response,
233
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
234
+ # base_exception = context.get('caught_exception', None)
235
+ super().__init__(response, PyegeriaErrorCode.CLIENT_ERROR,
236
+ context, additional_info, e)
237
+ logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
238
+
239
+
240
+ class PyegeriaAPIException(PyegeriaException):
241
+ """Raised for errors reported by Egeria"""
242
+ def __init__(self, response: Response,
243
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
244
+ super().__init__(response, PyegeriaErrorCode.EGERIA_ERROR,
245
+ context, additional_info, e)
246
+ related_response = response.json()
247
+ self.related_http_code = related_response.get("relatedHTTPCode", None)
248
+ msg = self.__str__()
249
+ if self.related_http_code:
250
+ exception_msg_id = related_response.get("exceptionErrorMessageId", "UNKNOWN_ERROR")
251
+ msg += f"\n\t{self.error_details['message_template'].format(exception_msg_id)}\n"
252
+
253
+ for key, value in related_response.items():
254
+ msg += f"\t\t* {key} = {format_dict_to_string(value)}\n"
255
+
256
+ logger.info(msg, ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
257
+
258
+
259
+
260
+
261
+ # class PyegeriaAuthenticationException(PyegeriaException):
262
+ # """Raised for 401 authentication errors."""
263
+ # def __init__(self, response: Response,
264
+ # context: dict = None, additional_info: dict = None) -> None:
265
+ # super().__init__(response, PyegeriaErrorCode.AUTHENTICATION_ERROR,
266
+ # context, additional_info)
267
+ # self.message = self.error_details["message_template"].format(additional_info.get("userid",""))
268
+ # logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
269
+
270
+ class PyegeriaUnauthorizedException(PyegeriaException):
271
+ """Raised for 403 authorization errors."""
272
+ def __init__(self, response: Response,
273
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
274
+ super().__init__(response, PyegeriaErrorCode.AUTHORIZATION_ERROR,
275
+ context, additional_info, e)
276
+ self.message = self.error_details["message_template"].format(additional_info.get("userid", ""))
277
+ logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
278
+
279
+
280
+
281
+ class PyegeriaNotFoundException(PyegeriaException):
282
+ """Raised for 404 Not Found errors."""
283
+ def __init__(self, response: Response,
284
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
285
+ super().__init__(response, PyegeriaErrorCode.CLIENT_ERROR,
286
+ context, additional_info, e)
287
+ logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
288
+
289
+
290
+ # class PyegeriaInvalidResponseException(PyegeriaException):
291
+ # """Raised when the API returns an unparseable or unexpected response."""
292
+ # def __init__(self, response: Response,
293
+ # context: dict = None, additional_info: dict = None) -> None:
294
+ # super().__init__(response, PyegeriaErrorCode.CLIENT_ERROR,
295
+ # context, additional_info)
296
+ # logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
297
+ #
298
+ #
299
+ # class PyegeriaValidationException(PyegeriaException):
300
+ # """Raised when data sent to the API fails validation, or received data fails Pydantic validation."""
301
+ #
302
+ # def __init__(self, response: Response = None,
303
+ # context: dict = None, additional_info: dict = None) -> None:
304
+ # super().__init__(response, PyegeriaErrorCode.VALIDATION_ERROR,
305
+ # context, additional_info)
306
+ # reason = additional_info.get("reason","")
307
+ # input_parameters = additional_info.get("input_parameters","")
308
+ # self.message = self.error_details["message_template"].format(reason, input_parameters)
309
+ # logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
310
+ #
311
+ # class PyegeriaRequestException(PyegeriaException):
312
+ # """Raised when data sent to the API fails validation, or received data fails Pydantic validation."""
313
+ # def __init__(self, response: Response,
314
+ # context: dict = None, additional_info: dict = None) -> None:
315
+ # super().__init__(response, PyegeriaErrorCode.CLIENT_ERROR,
316
+ # context, additional_info)
317
+ # logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
318
+
319
+
320
+ class PyegeriaUnknownException(PyegeriaException):
321
+ """Raised when data sent to the API fails validation, or received data fails Pydantic validation."""
322
+ def __init__(self, response: Response,
323
+ context: dict = None, additional_info: dict = None, e: Exception = None) -> None:
324
+ super().__init__(response, PyegeriaErrorCode.CLIENT_ERROR,
325
+ context, additional_info, e)
326
+ logger.info(self.__str__(), ip=self.response_url, http_code=self.response_code, pyegeria_code=self.pyegeria_code)
327
+
328
+
329
+
330
+ def print_exception_response(e: PyegeriaException):
331
+ """Prints the exception response"""
332
+ if isinstance(e, PyegeriaException):
333
+ console.print(Markdown(f"\n---\n# Exception: {e.__class__.__name__}"))
334
+ msg: Text = Text(e.__str__(), overflow="fold")
335
+ if e.response_code:
336
+ related_response = e.response.json()
337
+ exception_msg_id = related_response.get("exceptionErrorMessageId", None)
338
+ if exception_msg_id:
339
+ msg.append( f"\n\t{e.error_details['message_template'].format(exception_msg_id)}\n")
340
+
341
+ # for key, value in related_response.items():
342
+ # msg += f"\t\t* {key} = {print(value)}\n"
343
+ for key, value in related_response.items():
344
+ msg.append( Text(f"\t* {key} =", style = "bold yellow"))
345
+ msg.append(Text( f"\n\t\t{format_dict_to_string(value)}\n", overflow="fold", style = "green"))
346
+ console.print(msg)
347
+ else:
348
+ print(f"\n\n\t Not an Pyegeria exception {e}")
349
+
350
+ def print_exception_table(e: PyegeriaException):
351
+ """Prints the exception response"""
352
+ related_code = e.related_http_code if hasattr(e, "related_http_code") else ""
353
+ related_response = e.response.json()
354
+
355
+ table = Table(title=f"Exception: {e.__class__.__name__}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
356
+ table.caption = e.pyegeria_code
357
+ table.add_column("Facet", justify="center")
358
+ table.add_column("Item", justify="center")
359
+
360
+ if isinstance(e, PyegeriaException):
361
+ table.add_row("HTTP Code", str(e.response_code))
362
+ table.add_row("Egeria Code", str(related_code))
363
+ table.add_row("Caller Method", e.context.get("caller method", "---"))
364
+ table.add_row("Request URL", str(e.response_url))
365
+ if e.response_code:
366
+ item_table = Table(show_lines = True, header_style="bold")
367
+ item_table.add_column("Item", justify="center")
368
+ item_table.add_column("Detail", justify="left")
369
+ if related_response:
370
+ for key, value in related_response.items():
371
+ item_table.add_row(key, format_dict_to_string(value))
372
+ table.add_row("Egeria Details", item_table)
373
+
374
+
375
+
376
+
377
+ exception_msg_id = related_response.get("exceptionErrorMessageId", None)
378
+ table.add_row("Pyegeria Exception", exception_msg_id)
379
+ table.add_row("Pyegeria Message",
380
+ f"\n\t{e.error_details['message_template'].format(exception_msg_id)}\n")
381
+
382
+
383
+ console.print(table)
384
+ else:
385
+ print(f"\n\n\t Not an Pyegeria exception {e}")
386
+
387
+ def print_basic_exception(e: PyegeriaException):
388
+ """Prints the exception response"""
389
+ standard_errors = ["OMAG-REPOSITORY-HANDLER-404-001",
390
+ "OMAG-REPOSITORY-HANDLER-404-007",
391
+ ]
392
+ if e.response_egeria_msg_id and e.response_egeria_msg_id in standard_errors:
393
+ print(f"\n==> {e.response_egeria_msg}")
394
+ return
395
+
396
+ related_code = e.related_http_code if hasattr(e, "related_http_code") else ""
397
+ http_reason = e.response.text if e.response else ""
398
+
399
+ table = Table(title=f"Exception: {e.__class__.__name__}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
400
+ table.caption = e.pyegeria_code
401
+ table.add_column("Facet", justify="center")
402
+ table.add_column("Item", justify="left", width=80)
403
+ if e.response:
404
+ related_response = e.response.json() if isinstance(e, PyegeriaException) else None
405
+ exception_msg_id = related_response.get("exceptionErrorMessageId", None)
406
+ else:
407
+ exception_msg_id = ""
408
+
409
+ table = Table(title=f"Exception: {e.__class__.__name__}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
410
+ table.caption = e.pyegeria_code
411
+ table.add_column("Facet", justify="center")
412
+ table.add_column("Item", justify="left", width=80)
413
+
414
+ if isinstance(e, PyegeriaException):
415
+ if e.context:
416
+ table.add_row("Context", e.context.get('reason',""), style = "bold yellow")
417
+ if e.response:
418
+ table.add_row("HTTP Code", str(e.response_code))
419
+ table.add_row("HTTP Reason", str(http_reason))
420
+ table.add_row("Egeria Code", str(related_code))
421
+ table.add_row("Caller Method", e.context.get("caller method", "---")) if e.context else ""
422
+ table.add_row("Request URL", str(e.response_url))
423
+ if related_response:
424
+ if isinstance(related_response, dict):
425
+ table.add_row("Egeria Message",
426
+ format_dict_to_string(related_response.get('exceptionErrorMessage',"")))
427
+ elif isinstance(related_response, str):
428
+ table.add_row(related_response,)
429
+
430
+ table.add_row("Egeria User Action",
431
+ format_dict_to_string(related_response.get('exceptionUserAction',"")) if isinstance(related_response,dict) else related_response)
432
+
433
+ exception_msg_id = related_response.get("exceptionErrorMessageId", None) if isinstance(related_response,dict) else related_response
434
+ table.add_row("Egeria Exception Message Id", exception_msg_id)
435
+ table.add_row("Pyegeria Message", e.message)
436
+ console.print(table)
437
+
438
+ else:
439
+ print(f"\n\n\t Not an Pyegeria exception {e}")
440
+
441
+ def print_validation_error(e: ValidationError):
442
+ """Prints the pydantic validation exception response"""
443
+
444
+ table = Table(title=f"Validation Error for {e.title}", show_lines=True, header_style="bold", box=box.HEAVY_HEAD)
445
+ table.caption = "Pydantic Validation Error"
446
+ table.add_column("Type", justify="center")
447
+ table.add_column("Attribute", justify="center")
448
+ table.add_column("Message", justify="center")
449
+
450
+ for error in e.errors():
451
+ error_type = error["type"]
452
+ attribute = " ".join(str(part) for part in error["loc"])
453
+ message = error["msg"]
454
+ table.add_row(error_type, attribute, message)
455
+
456
+
457
+ console.print(table)
@@ -0,0 +1,60 @@
1
+ """
2
+ SPDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+ """
5
+
6
+ """
7
+ This common file is used to set some global values and enumerations used by the overall package.
8
+
9
+ """
10
+
11
+
12
+ is_debug = False
13
+ disable_ssl_warnings = True
14
+ enable_ssl_check = False
15
+ max_paging_size = 500
16
+ default_time_out = 30
17
+ DEBUG_LEVEL = "quiet"
18
+ COMMENT_TYPES = (
19
+ "STANDARD_COMMENT",
20
+ "ANSWER",
21
+ "OTHER",
22
+ "QUESTION",
23
+ "SUGGESTION",
24
+ "USAGE_EXPERIENCE",
25
+ "REQUIREMENT"
26
+ )
27
+ star_ratings = (
28
+ "FIVE_STARS",
29
+ "FOUR_STARS",
30
+ "NO_RECOMMENDATION",
31
+ "ONE_STAR",
32
+ "THREE_STARS",
33
+ "TWO_STARS",
34
+ )
35
+
36
+ TEMPLATE_GUIDS: dict = {}
37
+ INTEGRATION_GUIDS: dict = {}
38
+
39
+ NO_ELEMENTS_FOUND = "No elements found"
40
+ NO_ASSETS_FOUND = "No assets found"
41
+ NO_SERVERS_FOUND = "No servers found"
42
+ NO_CATALOGS_FOUND = "No catalogs found"
43
+ NO_GLOSSARIES_FOUND = "No glossaries found"
44
+ NO_TERMS_FOUND = "No terms found"
45
+ NO_CATEGORIES_FOUND = "No categories found"
46
+ NO_ELEMENT_FOUND = "No element found"
47
+ NO_PROJECTS_FOUND = "No projects found"
48
+ NO_COLLECTION_FOUND = "No collection found"
49
+ NO_GUID_RETURNED = "No guid returned"
50
+ NO_MEMBERS_FOUND = "No members found"
51
+
52
+ MERMAID_GRAPHS = ["anchorMermaidGraph", "informationSupplyChainMermaidGraph","fieldLevelLineageGraph",
53
+ "actionMermaidGraph", "localLineageGraph", "edgeMermaidGraph", "iscImplementationMermaidGraph",
54
+ "specificationMermaidGraph", "solutionBlueprintMermaidGraph","mermaidGraph",
55
+ "solutionSubcomponentMermaidGraph"]
56
+ MERMAID_GRAPH_TITLES = ["Anchor Mermaid Graph", "Information Supply Chain Mermaid Graph","Field Level Lineage Graph",
57
+ "Action Mermaid Graph", "Local Lineage Graph", "Edge Mermaid Graph", "ISC Implementation Mermaid Graph",
58
+ "Specification Mermaid Graph", "Solution Blueprint Mermaid Graph","Mermaid Graph",
59
+ "Solution Subcomponent Mermaid Graph"]
60
+ TERM_STATUS = ["DRAFT", "PREPARED","PROPOSED","APPROVED", "REJECTED", "ACTIVE", "DEPRECATED", "DELETED", "OTHER"]