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,4403 @@
1
+ """
2
+ SPDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+
5
+ Automated Curation View Service Methods
6
+
7
+ """
8
+
9
+ import asyncio
10
+ import datetime
11
+
12
+ from httpx import Response
13
+ from loguru import logger
14
+ from pydantic import HttpUrl
15
+ from pyegeria.core._globals import NO_ELEMENTS_FOUND
16
+ from pyegeria.core._server_client import ServerClient
17
+ from pyegeria.core._validators import validate_guid, validate_name, validate_search_string
18
+ # from pyegeria._exceptions import (
19
+ # PyegeriaInvalidParameterException,
20
+ # PyegeriaAPIException,
21
+ # PyegeriaUnauthorizedException,
22
+ # )
23
+ from pyegeria.models import GetRequestBody, FilterRequestBody, SearchStringRequestBody, TemplateRequestBody
24
+ from typing import Any, Optional
25
+ from pyegeria.core.utils import body_slimmer, dynamic_catch
26
+ from pyegeria.core.config import settings
27
+ from pyegeria.view.base_report_formats import select_report_format, get_report_spec_match
28
+ from pyegeria.view.output_formatter import (
29
+ generate_output,
30
+ _extract_referenceable_properties,
31
+ populate_columns_from_properties,
32
+ get_required_relationships,
33
+ )
34
+ settings.Logging.console_logging_level = "ERROR"
35
+
36
+
37
+ class AutomatedCuration(ServerClient):
38
+ """
39
+ Client for the Automated Curation View Service.
40
+
41
+ The Automated Curation View Service provides methods to automate the
42
+ curation of metadata, including creating elements from templates,
43
+ initiating surveys, and managing engine actions.
44
+
45
+ Attributes
46
+ ----------
47
+ view_server : str
48
+ The name of the View Server to use.
49
+ platform_url : str
50
+ URL of the server platform to connect to.
51
+ user_id : str
52
+ The identity of the user calling the method.
53
+ user_pwd : str
54
+ The password associated with the user_id. Defaults to None.
55
+ """
56
+
57
+ def __init__(
58
+ self,
59
+ view_server: str,
60
+ platform_url: str,
61
+ user_id: str,
62
+ user_pwd: Optional[str] = None,
63
+ token: Optional[str] = None,
64
+ ):
65
+ self.view_server = view_server
66
+ self.platform_url = platform_url
67
+ self.user_id = user_id
68
+ self.user_pwd = user_pwd
69
+ ServerClient.__init__(self, view_server, platform_url, user_id, user_pwd, token=token)
70
+ self.curation_command_root = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/automated-curation"
71
+
72
+ # Default entity label used by the output formatter for Technology Types
73
+ self.TECH_TYPE_ENTITY_LABEL = "TechType"
74
+ self.GOV_ACTION_TYPE_LABEL = "GovActionType"
75
+ self.CATALOG_TARGET_LABEL = "CatalogTarget"
76
+ self.ENGINE_ACTION_LABEL = "EngineAction"
77
+ self.GOV_ACTION_PROCESS_LABEL = "GovActionProcess"
78
+
79
+
80
+ def _extract_tech_type_element_properties(self, element: dict, columns_struct: dict) -> dict:
81
+ """
82
+ Extract properties from a technology type element and populate the provided columns_struct.
83
+ Tolerant to missing fields.
84
+ """
85
+ # Populate direct properties first
86
+ col_data = populate_columns_from_properties(element, columns_struct)
87
+ columns_list = col_data.get("formats", {}).get("columns", [])
88
+
89
+ # Referenceable header extraction (GUID, qualifiedName, displayName, etc.)
90
+ header_props = _extract_referenceable_properties(element)
91
+ for column in columns_list:
92
+ key = column.get("key")
93
+ if key in header_props:
94
+ column["value"] = header_props.get(key)
95
+ elif isinstance(key, str) and key.lower() == "guid":
96
+ column["value"] = header_props.get("GUID")
97
+ elif key == "mermaidGraph":
98
+ column["value"] = element.get("mermaidGraph","")
99
+ elif key == "specificationMermaidGraph":
100
+ column["value"] = element.get("specificationMermaidGraph","")
101
+
102
+ return col_data
103
+ # return columns_struct
104
+
105
+ def _extract_tech_type_properties(self, element: dict, columns_struct: dict) -> dict:
106
+ """
107
+ Extract properties from a technology type element and populate the provided columns_struct.
108
+ Tolerant to missing fields.
109
+ """
110
+ # # Populate direct properties first
111
+ # col_data = populate_columns_from_properties(element, columns_struct)
112
+ # columns_list = col_data.get("formats", {}).get("columns", [])
113
+ #
114
+ # # Referenceable header extraction (GUID, qualifiedName, displayName, etc.)
115
+ # header_props = _extract_referenceable_properties(element)
116
+ # for column in columns_list:
117
+ # key = column.get("key")
118
+ # if key in header_props:
119
+ # column["value"] = header_props.get(key)
120
+ # elif isinstance(key, str) and key.lower() == "guid":
121
+ # column["value"] = header_props.get("GUID")
122
+ #
123
+ # # Try common category/type fields
124
+ # category = (
125
+ # element.get("properties", {}).get("category")
126
+ # or element.get("elementProperties", {}).get("category")
127
+ # or element.get("elementType", {}).get("typeName")
128
+ # or ""
129
+ # )
130
+ columns_list = columns_struct.get("formats", {}).get("attributes", [])
131
+
132
+ guid = element.get('technologyTypeGUID',None)
133
+ qualified_name = element.get('qualifiedName',None)
134
+ display_name = element.get('displayName',None)
135
+ description = element.get('description',None)
136
+ catalog_templates = element.get('catalogTemplates',None)
137
+ governance_processes = element.get('governanceActionProcesses',None)
138
+ external_references = element.get('externalReferences',None)
139
+ url = element.get('url',None)
140
+
141
+
142
+ # Mermaid graph support if present
143
+ mermaid_val = element.get("mermaidGraph", "") or ""
144
+ for column in columns_list:
145
+ if column.get("key") == "mermaidGraph":
146
+ column["value"] = mermaid_val
147
+ break
148
+ elif column.get("key") == "catalog_template_specs":
149
+ specs = ""
150
+ for template in catalog_templates:
151
+ for placeholder in template['specification']['placeholderProperty']:
152
+ specs += (f"* Placeholder Property: {placeholder.get('name','')}\n\t"
153
+ f"Type: {placeholder.get('dataType',"")}\n\t"
154
+ f"Description: {placeholder.get('description',"")}\n\t"
155
+ f"Required: {placeholder.get("required","")}\n\t"
156
+ f"Example: {placeholder.get("example","")}\n\n")
157
+ column["value"] = specs
158
+ elif column.get("key") == "catalog_templates":
159
+ column["value"] =catalog_templates
160
+ elif column.get("key") == "governance_processes":
161
+ procs = ""
162
+ specs = ""
163
+ if governance_processes:
164
+ for proc in governance_processes:
165
+ proc_props = proc['relatedElement'].get("properties", {})
166
+ proc_qn = proc_props.get("qualifiedName","")
167
+ proc_dn = proc_props.get("displayName","")
168
+ proc_description = proc_props.get("description","")
169
+
170
+ proc_specs = proc.get("specification",{}).get("supportedRequestParameter",{})
171
+ for spec in proc_specs:
172
+ name = spec.get("name","")
173
+ description = spec.get("description","")
174
+ data_type = spec.get("dataType","")
175
+ example = spec.get("example","")
176
+ required = str(spec.get("required",""))
177
+ specs += (f"* Name: {name}\n"
178
+ f"* Description: {description}\n"
179
+ f"* Data Type: {data_type}\n"
180
+ f"* Example: {example}\n"
181
+ f"* Required: {required}\n\t---------\n"
182
+ )
183
+
184
+ procs += (f"* Display Name: {proc_dn}\n"
185
+ f"* Resource Use: {proc.get("resourceUse", "")}\n"
186
+ f"* Description: {proc_description}\n"
187
+ f"* Qualified Name: {proc_qn}\n"
188
+ f"* Parameters:\n\t---------\n{specs}\n\t==========\n\n"
189
+ )
190
+ column['value'] = procs
191
+ elif column.get("key") == "governance_processes_d":
192
+ processes = []
193
+
194
+ if governance_processes:
195
+ for proc in governance_processes:
196
+ procs = {}
197
+ proc_props = proc['relatedElement'].get("properties", {})
198
+ procs['proc_qualified_name'] = proc_props.get("qualifiedName", "")
199
+ procs['proc_display_name'] = proc_props.get("displayName", "")
200
+ procs['proc_description'] = proc_props.get("description", "")
201
+ procs['proc_params'] = proc.get("specification",{}).get("supportedRequestParameter",{})
202
+ processes.append(procs)
203
+ column['value'] = processes
204
+ elif column.get("key") == "guid":
205
+ column["value"] = guid
206
+ elif column.get("key") == "qualified_name":
207
+ column["value"] = qualified_name
208
+ elif column.get("key") == "display_name":
209
+ column["value"] = display_name
210
+ elif column.get("key") == "description":
211
+ column["value"] = description
212
+ elif column.get("key") == "external_references":
213
+ column["value"] = external_references
214
+ elif column.get("key") == "ref_url":
215
+ if isinstance(external_references, dict):
216
+ column["value"] = external_references[0]['relatedElement']['properties'].get('url',"")
217
+ elif column.get("key") == "url":
218
+ column["value"] = url
219
+ columns_struct["formats"]["attributes"] = columns_list
220
+ return columns_struct
221
+
222
+ def _generate_tech_type_output(
223
+ self,
224
+ elements: dict | list[dict],
225
+ filter_string: str | None,
226
+ element_type_name: str | None,
227
+ output_format: str = "DICT",
228
+ report_spec: dict | str | None = None,
229
+ **kwargs,
230
+ ) -> str | list[dict]:
231
+ """Generate output for technology types in the specified format."""
232
+ entity_type = element_type_name or self.TECH_TYPE_ENTITY_LABEL
233
+
234
+ # Resolve report format (with backward-compatible legacy kwarg)
235
+ get_additional_props_func = None
236
+ if report_spec is None and isinstance(kwargs, dict) and 'report_spec' in kwargs:
237
+ report_spec = kwargs.get('report_spec')
238
+ if report_spec:
239
+ if isinstance(report_spec, str):
240
+ output_formats = select_report_format(report_spec, output_format)
241
+ else:
242
+ output_formats = get_report_spec_match(report_spec, output_format)
243
+ elif element_type_name:
244
+ output_formats = select_report_format(element_type_name, output_format)
245
+ else:
246
+ output_formats = select_report_format(entity_type, output_format)
247
+
248
+ if output_formats is None:
249
+ output_formats = select_report_format("Default", output_format)
250
+
251
+ # Optional hook for extra server calls to enrich rows
252
+ get_additional_props_name = (
253
+ output_formats.get("get_additional_props", {}).get("function") if output_formats else None
254
+ )
255
+ if isinstance(get_additional_props_name, str):
256
+ parts = get_additional_props_name.split(".")
257
+ method_name = parts[-1] if parts else None
258
+ if method_name and hasattr(self, method_name):
259
+ get_additional_props_func = getattr(self, method_name)
260
+
261
+ return generate_output(
262
+ elements,
263
+ filter_string,
264
+ entity_type,
265
+ output_format,
266
+ self._extract_tech_type_properties,
267
+ get_additional_props_func,
268
+ output_formats,
269
+ )
270
+
271
+ def _generate_tech_type_element_output(
272
+ self,
273
+ elements: dict | list[dict],
274
+ filter_string: str | None,
275
+ element_type_name: str | None,
276
+ output_format: str = "DICT",
277
+ report_spec: dict | str | None = None,
278
+ **kwargs,
279
+ ) -> str | list[dict]:
280
+ """Generate output for technology type elements in the specified format."""
281
+ entity_type = element_type_name or self.TECH_TYPE_ENTITY_LABEL
282
+
283
+ # Resolve report format (with backward-compatible legacy kwarg)
284
+ get_additional_props_func = None
285
+ if report_spec is None and isinstance(kwargs, dict) and 'report_spec' in kwargs:
286
+ report_spec = kwargs.get('report_spec')
287
+ if report_spec:
288
+ if isinstance(report_spec, str):
289
+ output_formats = select_report_format(report_spec, output_format)
290
+ else:
291
+ output_formats = get_report_spec_match(report_spec, output_format)
292
+ elif element_type_name:
293
+ output_formats = select_report_format(element_type_name, output_format)
294
+ else:
295
+ output_formats = select_report_format(entity_type, output_format)
296
+
297
+ if output_formats is None:
298
+ output_formats = select_report_format("Default", output_format)
299
+
300
+ # Optional hook for extra server calls to enrich rows
301
+ get_additional_props_name = (
302
+ output_formats.get("get_additional_props", {}).get("function") if output_formats else None
303
+ )
304
+ if isinstance(get_additional_props_name, str):
305
+ parts = get_additional_props_name.split(".")
306
+ method_name = parts[-1] if parts else None
307
+ if method_name and hasattr(self, method_name):
308
+ get_additional_props_func = getattr(self, method_name)
309
+
310
+ return generate_output(
311
+ elements,
312
+ filter_string,
313
+ entity_type,
314
+ output_format,
315
+ self._extract_tech_type_element_properties,
316
+ get_additional_props_func,
317
+ output_formats,
318
+ )
319
+
320
+ def _extract_gov_action_type_properties(self, element: dict, columns_struct: dict) -> dict:
321
+ col_data = populate_columns_from_properties(element, columns_struct)
322
+ columns_list = col_data.get("formats", {}).get("attributes", [])
323
+ header_props = _extract_referenceable_properties(element)
324
+ for column in columns_list:
325
+ key = column.get("key")
326
+ if key in header_props:
327
+ column["value"] = header_props.get(key)
328
+ elif isinstance(key, str) and key.lower() == "guid":
329
+ column["value"] = header_props.get("GUID")
330
+ col_data = get_required_relationships(element, col_data)
331
+ mermaid_val = element.get("mermaidGraph", "") or ""
332
+ for column in columns_list:
333
+ if column.get("key") == "mermaid":
334
+ column["value"] = mermaid_val
335
+ break
336
+ return col_data
337
+
338
+ def _generate_gov_action_type_output(self, elements: dict | list[dict], filter_string: str | None,
339
+ element_type_name: str | None, output_format: str = "DICT",
340
+ report_format: dict | str | None = None,
341
+ **kwargs) -> str | list[dict]:
342
+ entity_type = element_type_name or self.GOV_ACTION_TYPE_LABEL
343
+ get_additional_props_func = None
344
+ if report_format is None and isinstance(kwargs, dict) and 'report_spec' in kwargs:
345
+ report_format = kwargs.get('report_spec')
346
+ if report_format:
347
+ if isinstance(report_format, str):
348
+ output_formats = select_report_format(report_format, output_format)
349
+ else:
350
+ output_formats = get_report_spec_match(report_format, output_format)
351
+ elif element_type_name:
352
+ output_formats = select_report_format(element_type_name, output_format)
353
+ else:
354
+ output_formats = select_report_format(entity_type, output_format)
355
+ if output_formats is None:
356
+ output_formats = select_report_format("Default", output_format)
357
+ get_additional_props_name = (
358
+ output_formats.get("get_additional_props", {}).get("function") if output_formats else None
359
+ )
360
+ if isinstance(get_additional_props_name, str):
361
+ method_name = get_additional_props_name.split(".")[-1]
362
+ if hasattr(self, method_name):
363
+ get_additional_props_func = getattr(self, method_name)
364
+ return generate_output(
365
+ elements,
366
+ filter_string,
367
+ entity_type,
368
+ output_format,
369
+ self._extract_gov_action_type_properties,
370
+ get_additional_props_func,
371
+ output_formats,
372
+ )
373
+
374
+ def _extract_catalog_target_properties(self, element: dict, columns_struct: dict) -> dict:
375
+ col_data = populate_columns_from_properties(element, columns_struct)
376
+ columns_list = col_data.get("formats", {}).get("attributes", [])
377
+ header_props = _extract_referenceable_properties(element)
378
+ for column in columns_list:
379
+ key = column.get("key")
380
+ if key in header_props:
381
+ column["value"] = header_props.get(key)
382
+ elif isinstance(key, str) and key.lower() == "guid":
383
+ column["value"] = header_props.get("GUID")
384
+ col_data = get_required_relationships(element, col_data)
385
+ mermaid_val = element.get("mermaidGraph", "") or ""
386
+ for column in columns_list:
387
+ if column.get("key") == "mermaid":
388
+ column["value"] = mermaid_val
389
+ break
390
+ return col_data
391
+
392
+ def _generate_catalog_target_output(self, elements: dict | list[dict], filter_string: str | None,
393
+ element_type_name: str | None, output_format: str = "DICT",
394
+ report_format: dict | str | None = None,
395
+ **kwargs) -> str | list[dict]:
396
+ entity_type = element_type_name or self.CATALOG_TARGET_LABEL
397
+ get_additional_props_func = None
398
+ if report_format is None and isinstance(kwargs, dict) and 'report_spec' in kwargs:
399
+ report_format = kwargs.get('report_spec')
400
+ if report_format:
401
+ if isinstance(report_format, str):
402
+ output_formats = select_report_format(report_format, output_format)
403
+ else:
404
+ output_formats = get_report_spec_match(report_format, output_format)
405
+ elif element_type_name:
406
+ output_formats = select_report_format(element_type_name, output_format)
407
+ else:
408
+ output_formats = select_report_format(entity_type, output_format)
409
+ if output_formats is None:
410
+ output_formats = select_report_format("Default", output_format)
411
+ return generate_output(
412
+ elements,
413
+ filter_string,
414
+ entity_type,
415
+ output_format,
416
+ self._extract_catalog_target_properties,
417
+ None,
418
+ output_formats,
419
+ )
420
+
421
+ def _extract_engine_action_properties(self, element: dict, columns_struct: dict) -> dict:
422
+ col_data = populate_columns_from_properties(element, columns_struct)
423
+ columns_list = col_data.get("formats", {}).get("attributes", [])
424
+ header_props = _extract_referenceable_properties(element)
425
+ for col in columns_list:
426
+ key = col.get("key")
427
+ if key in header_props:
428
+ col["value"] = header_props.get(key)
429
+ elif isinstance(key, str) and key.lower() == "guid":
430
+ col["value"] = header_props.get("GUID")
431
+ # EngineAction specifics: status, process_name, received_guards, completion_guards, request_type
432
+ status = (
433
+ element.get("properties", {}).get("status")
434
+ or element.get("elementProperties", {}).get("status")
435
+ or element.get("status")
436
+ )
437
+ process_name = (
438
+ element.get("properties", {}).get("processName")
439
+ or element.get("elementProperties", {}).get("processName")
440
+ or element.get("processName")
441
+ )
442
+ req_type = (
443
+ element.get("properties", {}).get("requestType")
444
+ or element.get("elementProperties", {}).get("requestType")
445
+ or element.get("requestType")
446
+ )
447
+ rec_guards = element.get("receivedGuards") or element.get("received_guards") or []
448
+ comp_guards = element.get("completionGuards") or element.get("completion_guards") or []
449
+ # assign to columns if present
450
+ for col in columns_list:
451
+ key = col.get("key")
452
+ if key == "status":
453
+ col["value"] = status
454
+ elif key in ("process_name", "processName"):
455
+ col["value"] = process_name
456
+ elif key in ("request_type", "requestType"):
457
+ col["value"] = req_type
458
+ elif key in ("received_guards", "receivedGuards"):
459
+ col["value"] = ", ".join(map(str, rec_guards)) if isinstance(rec_guards, list) else rec_guards
460
+ elif key in ("completion_guards", "completionGuards"):
461
+ col["value"] = ", ".join(map(str, comp_guards)) if isinstance(comp_guards, list) else comp_guards
462
+ col_data = get_required_relationships(element, col_data)
463
+ mermaid_val = element.get("mermaidGraph", "") or ""
464
+ for col in columns_list:
465
+ if col.get("key") == "mermaid":
466
+ col["value"] = mermaid_val
467
+ break
468
+ return col_data
469
+
470
+ def _generate_engine_action_output(self, elements: dict | list[dict], filter_string: str | None,
471
+ element_type_name: str | None, output_format: str = "DICT",
472
+ report_spec: dict | str | None = None) -> str | list[dict]:
473
+ entity_type = element_type_name or self.ENGINE_ACTION_LABEL
474
+ get_additional_props_func = None
475
+ if report_spec:
476
+ if isinstance(report_spec, str):
477
+ output_formats = select_report_format(report_spec, output_format)
478
+ else:
479
+ output_formats = get_report_spec_match(report_spec, output_format)
480
+ elif element_type_name:
481
+ output_formats = select_report_format(element_type_name, output_format)
482
+ else:
483
+ output_formats = select_report_format(entity_type, output_format)
484
+ if output_formats is None:
485
+ output_formats = select_report_format("Default", output_format)
486
+ get_additional_props_name = (
487
+ output_formats.get("get_additional_props", {}).get("function") if output_formats else None
488
+ )
489
+ if isinstance(get_additional_props_name, str):
490
+ method_name = get_additional_props_name.split(".")[-1]
491
+ if hasattr(self, method_name):
492
+ get_additional_props_func = getattr(self, method_name)
493
+ return generate_output(
494
+ elements,
495
+ filter_string,
496
+ entity_type,
497
+ output_format,
498
+ self._extract_engine_action_properties,
499
+ get_additional_props_func,
500
+ output_formats,
501
+ )
502
+
503
+ def _extract_gov_action_process_properties(self, element: dict, columns_struct: dict) -> dict:
504
+ col_data = populate_columns_from_properties(element, columns_struct)
505
+ columns_list = col_data.get("formats", {}).get("attributes", [])
506
+ header_props = _extract_referenceable_properties(element)
507
+ for col in columns_list:
508
+ key = col.get("key")
509
+ if key in header_props:
510
+ col["value"] = header_props.get(key)
511
+ elif isinstance(key, str) and key.lower() == "guid":
512
+ col["value"] = header_props.get("GUID")
513
+ # GAP specifics: processStatus, elementTypeName, stepCount
514
+ proc_status = (
515
+ element.get("properties", {}).get("processStatus")
516
+ or element.get("elementProperties", {}).get("processStatus")
517
+ or element.get("processStatus")
518
+ )
519
+ step_count = (
520
+ element.get("properties", {}).get("stepCount")
521
+ or element.get("elementProperties", {}).get("stepCount")
522
+ or element.get("stepCount")
523
+ )
524
+ for col in columns_list:
525
+ key = col.get("key")
526
+ if key in ("process_status", "processStatus"):
527
+ col["value"] = proc_status
528
+ elif key == "stepCount":
529
+ col["value"] = step_count
530
+ col_data = get_required_relationships(element, col_data)
531
+ mermaid_val = element.get("mermaidGraph", "") or ""
532
+ for col in columns_list:
533
+ if col.get("key") == "mermaid":
534
+ col["value"] = mermaid_val
535
+ break
536
+ return col_data
537
+
538
+ def _generate_gov_action_process_output(self, elements: dict | list[dict], filter_string: str | None,
539
+ element_type_name: str | None, output_format: str = "DICT",
540
+ report_spec: dict | str | None = None) -> str | list[dict]:
541
+ entity_type = element_type_name or self.GOV_ACTION_PROCESS_LABEL
542
+ get_additional_props_func = None
543
+ if report_spec:
544
+ if isinstance(report_spec, str):
545
+ output_formats = select_report_format(report_spec, output_format)
546
+ else:
547
+ output_formats = get_report_spec_match(report_spec, output_format)
548
+ elif element_type_name:
549
+ output_formats = select_report_format(element_type_name, output_format)
550
+ else:
551
+ output_formats = select_report_format(entity_type, output_format)
552
+ if output_formats is None:
553
+ output_formats = select_report_format("Default", output_format)
554
+ return generate_output(
555
+ elements,
556
+ filter_string,
557
+ entity_type,
558
+ output_format,
559
+ self._extract_gov_action_process_properties,
560
+ None,
561
+ output_formats,
562
+ )
563
+
564
+ async def _async_create_elem_from_template(self, body: Optional[dict | TemplateRequestBody] = None) -> str:
565
+ """Create a new metadata element from a template. Async version.
566
+ Parameters
567
+ ----------
568
+ body : str
569
+ The json body used to instantiate the template.
570
+
571
+ Returns
572
+ -------
573
+ Response
574
+ The guid of the resulting element
575
+
576
+ Raises
577
+ ------
578
+ PyegeriaException
579
+ Notes
580
+ -----
581
+ See also: https://egeria-project.org/features/templated-cataloguing/overview/
582
+ The full description of the body is shown below:
583
+ {
584
+ "typeName" : "",
585
+ "initialStatus" : "",
586
+ "initialClassifications" : "",
587
+ "anchorGUID" : "",
588
+ "isOwnAnchor" : "",
589
+ "effectiveFrom" : "",
590
+ "effectiveTo" : "",
591
+ "templateGUID" : "",
592
+ "templateProperties" : {},
593
+ "placeholderPropertyValues" : {
594
+ "placeholderPropertyName1" : "placeholderPropertyValue1",
595
+ "placeholderPropertyName2" : "placeholderPropertyValue2"
596
+ },
597
+ "parentGUID" : "",
598
+ "parentRelationshipTypeName" : "",
599
+ "parentRelationshipProperties" : "",
600
+ "parentAtEnd1" : "",
601
+ "effectiveTime" : ""
602
+ }
603
+ """
604
+
605
+ url = f"{self.curation_command_root}/catalog-templates/new-element"
606
+ return await self._async_create_element_from_template(url, body)
607
+
608
+ def create_elem_from_template(self, body: Optional[dict | TemplateRequestBody] = None) -> str:
609
+ """Create a new metadata element from a template. Async version.
610
+ Parameters
611
+ ----------
612
+ body : str
613
+ The json body used to instantiate the template.
614
+
615
+
616
+ Returns
617
+ -------
618
+ Response
619
+ The guid of the resulting element
620
+
621
+ Raises
622
+ ------
623
+ PyegeriaInvalidParameterException
624
+ PyegeriaAPIException
625
+ PyegeriaUnauthorizedException
626
+
627
+ Notes
628
+ -----
629
+ See also: https://egeria-project.org/features/templated-cataloguing/overview/
630
+ The full description of the body is shown below:
631
+ {
632
+ "typeName" : "",
633
+ "initialStatus" : "",
634
+ "initialClassifications" : "",
635
+ "anchorGUID" : "",
636
+ "isOwnAnchor" : "",
637
+ "effectiveFrom" : "",
638
+ "effectiveTo" : "",
639
+ "templateGUID" : "",
640
+ "templateProperties" : {},
641
+ "placeholderPropertyValues" : {
642
+ "placeholderPropertyName1" : "placeholderPropertyValue1",
643
+ "placeholderPropertyName2" : "placeholderPropertyValue2"
644
+ },
645
+ "parentGUID" : "",
646
+ "parentRelationshipTypeName" : "",
647
+ "parentRelationshipProperties" : "",
648
+ "parentAtEnd1" : "",
649
+ "effectiveTime" : ""
650
+ }
651
+ """
652
+ loop = asyncio.get_event_loop()
653
+ response = loop.run_until_complete(
654
+ self._async_create_elem_from_template(body)
655
+ )
656
+ return response
657
+
658
+ async def _async_create_kafka_server_element_from_template(
659
+ self,
660
+ kafka_server: str,
661
+ host_name: str,
662
+ port: str,
663
+ description: Optional[str] = None,
664
+ ) -> str:
665
+ """Create a Kafka server element from a template. Async version.
666
+
667
+ Parameters
668
+ ----------
669
+ kafka_server : str
670
+ The name of the Kafka server.
671
+
672
+ host_name : str
673
+ The host name of the Kafka server.
674
+
675
+ port : str
676
+ The port number of the Kafka server.
677
+
678
+ description: str, opt
679
+ A description of the Kafka server.
680
+
681
+
682
+
683
+ Returns
684
+ -------
685
+ str
686
+ The GUID of the Kafka server element.
687
+ """
688
+ template_guid = await self._async_get_template_guid_for_technology_type("Apache Kafka Server")
689
+ body = {
690
+ "class": "TemplateRequestBody",
691
+ "templateGUID": template_guid,
692
+ "isOwnAnchor": "true",
693
+ "placeholderPropertyValues": {
694
+ "serverName": kafka_server,
695
+ "hostIdentifier": host_name,
696
+ "portNumber": port,
697
+ "description": description,
698
+ },
699
+ }
700
+ body_s = body_slimmer(body)
701
+ return await self._async_create_elem_from_template(body_s)
702
+
703
+ def create_kafka_server_element_from_template(
704
+ self,
705
+ kafka_server: str,
706
+ host_name: str,
707
+ port: str,
708
+ description: Optional[str] = None,
709
+ ) -> str:
710
+ """Create a Kafka server element from a template.
711
+
712
+ Parameters
713
+ ----------
714
+ kafka_server : str
715
+ The name of the Kafka server.
716
+
717
+ host_name : str
718
+ The host name of the Kafka server.
719
+
720
+ port : str
721
+ The port number of the Kafka server.
722
+
723
+ description: str, opt
724
+ A description of the Kafka server.
725
+
726
+
727
+
728
+ Returns
729
+ -------
730
+ str
731
+ The GUID of the Kafka server element.
732
+ """
733
+ loop = asyncio.get_event_loop()
734
+ response = loop.run_until_complete(
735
+ self._async_create_kafka_server_element_from_template(
736
+ kafka_server, host_name, port, description
737
+ )
738
+ )
739
+ return response
740
+
741
+ async def _async_create_csv_data_file_element_from_template(
742
+ self,
743
+ file_name: str,
744
+ file_type: str,
745
+ file_path_name: str,
746
+ version_identifier: str,
747
+ file_encoding: str = "UTF-8",
748
+ file_extension: str = "csv",
749
+ file_system_name: Optional[str] = None,
750
+ description: Optional[str] = None,
751
+ ) -> str:
752
+ """Create a CSV file element from a template. Async version.
753
+
754
+ Parameters
755
+ ----------
756
+ file_name : str
757
+ The name of the Kafka server.
758
+ file_type : str
759
+ The host name of the Kafka server.
760
+ file_path_name : str
761
+ The port number of the Kafka server.
762
+ version_identifier : str
763
+ The version identifier of the CSV file..
764
+ file_encoding: str, opt, default UTF-8
765
+ The encoding of the CSV file.
766
+ file_extension: str, opt, default is CSV
767
+ File extension of the CSV file.
768
+ file_system_name: str, opt
769
+ Name of the file system the CSV file is hosted on.
770
+ description: str, opt
771
+ A description of the CSV file..
772
+
773
+
774
+ Returns
775
+ -------
776
+ str
777
+ The GUID of the CSV File element.
778
+ """
779
+ template_guid = await self._async_get_template_guid_for_technology_type("CSV Data File")
780
+ body = {
781
+ "class": "TemplateRequestBody",
782
+ "templateGUID": template_guid,
783
+ "isOwnAnchor": "true",
784
+ "placeholderPropertyValues": {
785
+ "fileName": file_name,
786
+ "fileType": file_type,
787
+ "filePathName": file_path_name,
788
+ "versionIdentifier": version_identifier,
789
+ "fileEncoding": file_encoding,
790
+ "fileExtension": file_extension,
791
+ "fileSystemName": file_system_name,
792
+ "description": description
793
+ },
794
+ }
795
+ body_s = body_slimmer(body)
796
+ return await self._async_create_elem_from_template(body_s)
797
+
798
+ def create_csv_data_file_element_from_template(
799
+ self,
800
+ file_name: str,
801
+ file_type: str,
802
+ file_path_name: str,
803
+ version_identifier: str,
804
+ file_encoding: str = "UTF-8",
805
+ file_extension: str = "csv",
806
+ file_system_name: Optional[str] = None,
807
+ description: Optional[str] = None,
808
+ ) -> str:
809
+ """Create a CSV file element from a template. Async version.
810
+
811
+ Parameters
812
+ ----------
813
+ file_name : str
814
+ The name of the Kafka server.
815
+ file_type : str
816
+ The host name of the Kafka server.
817
+ file_path_name : str
818
+ The port number of the Kafka server.
819
+ version_identifier : str
820
+ The version identifier of the CSV file..
821
+ file_encoding: str, opt, default UTF-8
822
+ The encoding of the CSV file.
823
+ file_extension: str, opt, default is CSV
824
+ File extension of the CSV file.
825
+ file_system_name: str, opt
826
+ Name of the file system the CSV file is hosted on.
827
+ description: str, opt
828
+ A description of the CSV file..
829
+
830
+ Returns
831
+ -------
832
+ str
833
+ The GUID of the CSV File element.
834
+ """
835
+ loop = asyncio.get_event_loop()
836
+ response = loop.run_until_complete(
837
+ self._async_create_csv_data_file_element_from_template(
838
+ file_name, file_type, file_path_name, version_identifier,
839
+ file_encoding, file_extension, file_system_name, description
840
+ )
841
+ )
842
+ return response
843
+
844
+ async def _async_get_create_csv_data_file_element_from_template(
845
+ self,
846
+ file_name: str,
847
+ file_type: str,
848
+ file_path_name: str,
849
+ version_identifier: str,
850
+ file_encoding: str = "UTF-8",
851
+ file_extension: str = "csv",
852
+ file_system_name: Optional[str] = None,
853
+ description: Optional[str] = None,
854
+ ) -> str:
855
+ """Create a CSV file element from a template if it doesn't exist. If it does exist,
856
+ the guid will be returned. Async version.
857
+
858
+ Parameters
859
+ ----------
860
+ file_name : str
861
+ The name of the Kafka server.
862
+ file_type : str
863
+ The host name of the Kafka server.
864
+ file_path_name : str
865
+ The port number of the Kafka server.
866
+ version_identifier : str
867
+ The version identifier of the CSV file..
868
+ file_encoding: str, opt, default UTF-8
869
+ The encoding of the CSV file.
870
+ file_extension: str, opt, default is CSV
871
+ File extension of the CSV file.
872
+ file_system_name: str, opt
873
+ Name of the file system the CSV file is hosted on.
874
+ description: str, opt
875
+ A description of the CSV file..
876
+
877
+
878
+ Returns
879
+ -------
880
+ str
881
+ The GUID of the CSV File element.
882
+ """
883
+ template_guid = await self._async_get_template_guid_for_technology_type("CSV Data File")
884
+ body = {
885
+ "class": "TemplateRequestBody",
886
+ "templateGUID": template_guid,
887
+ "isOwnAnchor": True,
888
+ "allowRetrieve": True,
889
+ "placeholderPropertyValues": {
890
+ "fileName": file_name,
891
+ "fileType": file_type,
892
+ "filePathName": file_path_name,
893
+ "versionIdentifier": version_identifier,
894
+ "fileEncoding": file_encoding,
895
+ "fileExtension": file_extension,
896
+ "fileSystemName": file_system_name,
897
+ "description": description
898
+ },
899
+ }
900
+ body_s = body_slimmer(body)
901
+ return await self._async_create_elem_from_template(body_s)
902
+
903
+ def get_create_csv_data_file_element_from_template(
904
+ self,
905
+ file_name: str,
906
+ file_type: str,
907
+ file_path_name: str,
908
+ version_identifier: str,
909
+ file_encoding: str = "UTF-8",
910
+ file_extension: str = "csv",
911
+ file_system_name: Optional[str] = None,
912
+ description: Optional[str] = None,
913
+ ) -> str:
914
+ """Create a CSV file element from a template if it doesn't exist. If it does exist,
915
+ the guid will be returned.
916
+
917
+ Parameters
918
+ ----------
919
+ file_name : str
920
+ The name of the Kafka server.
921
+ file_type : str
922
+ The host name of the Kafka server.
923
+ file_path_name : str
924
+ The port number of the Kafka server.
925
+ version_identifier : str
926
+ The version identifier of the CSV file..
927
+ file_encoding: str, opt, default UTF-8
928
+ The encoding of the CSV file.
929
+ file_extension: str, opt, default is CSV
930
+ File extension of the CSV file.
931
+ file_system_name: str, opt
932
+ Name of the file system the CSV file is hosted on.
933
+ description: str, opt
934
+ A description of the CSV file..
935
+
936
+ Returns
937
+ -------
938
+ str
939
+ The GUID of the CSV File element.
940
+ """
941
+ loop = asyncio.get_event_loop()
942
+ response = loop.run_until_complete(
943
+ self._async_get_create_csv_data_file_element_from_template(
944
+ file_name, file_type, file_path_name, version_identifier,
945
+ file_encoding, file_extension, file_system_name, description
946
+ )
947
+ )
948
+ return response
949
+
950
+ async def _async_create_postgres_server_element_from_template(
951
+ self,
952
+ postgres_server: str,
953
+ host_name: str,
954
+ port: str,
955
+ db_user: str,
956
+ db_pwd: str,
957
+ description: Optional[str] = None,
958
+ ) -> str:
959
+ """Create a Postgres server element from a template. Async version.
960
+
961
+ Parameters
962
+ ----------
963
+ postgres_server : str
964
+ The name of the Postgres server.
965
+
966
+ host_name : str
967
+ The host name of the Postgres server.
968
+
969
+ port : str
970
+ The port number of the Postgres server.
971
+
972
+ db_user: str
973
+ User name to connect to the database
974
+
975
+ db_pwd: str
976
+ User password to connect to the database
977
+
978
+ description: str, opt
979
+ A description of the element.
980
+
981
+
982
+
983
+ Returns
984
+ -------
985
+ str
986
+ The GUID of the Postgres server element.
987
+ """
988
+ template_guid = await self._async_get_template_guid_for_technology_type("PostgreSQL Server")
989
+
990
+ body = {
991
+ "class": "TemplateRequestBody",
992
+ "templateGUID": template_guid,
993
+ "isOwnAnchor": "true",
994
+ "placeholderPropertyValues": {
995
+ "serverName": postgres_server,
996
+ "hostIdentifier": host_name,
997
+ "portNumber": port,
998
+ "databaseUserId": db_user,
999
+ "description": description,
1000
+ "databasePassword": db_pwd,
1001
+ },
1002
+ }
1003
+ body_s = body_slimmer(body)
1004
+ return await self._async_create_elem_from_template(body_s)
1005
+
1006
+ def create_postgres_server_element_from_template(
1007
+ self,
1008
+ postgres_server: str,
1009
+ host_name: str,
1010
+ port: str,
1011
+ db_user: str,
1012
+ db_pwd: str,
1013
+ description: Optional[str] = None,
1014
+ ) -> str:
1015
+ """Create a Postgres server element from a template.
1016
+
1017
+ Parameters
1018
+ ----------
1019
+ postgres_server : str
1020
+ The name of the Postgres server.
1021
+
1022
+ host_name : str
1023
+ The host name of the Postgres server.
1024
+
1025
+ port : str
1026
+ The port number of the Postgres server.
1027
+
1028
+
1029
+
1030
+ description: str, opt
1031
+ A description of the elementr.
1032
+
1033
+ db_user: str
1034
+ User name to connect to the database
1035
+
1036
+ db_pwd: str
1037
+ User password to connect to the database
1038
+
1039
+ Returns
1040
+ -------
1041
+ str
1042
+ The GUID of the Postgres server element.
1043
+ """
1044
+ loop = asyncio.get_event_loop()
1045
+ response = loop.run_until_complete(
1046
+ self._async_create_postgres_server_element_from_template(
1047
+ postgres_server, host_name, port, db_user, db_pwd, description
1048
+ )
1049
+ )
1050
+ return response
1051
+
1052
+ async def _async_create_postgres_database_element_from_template(
1053
+ self,
1054
+ postgres_database: str,
1055
+ server_name: str,
1056
+ host_identifier: str,
1057
+ port: str,
1058
+ db_user: str,
1059
+ db_pwd: str,
1060
+ description: Optional[str] = None,
1061
+ ) -> str:
1062
+ """Create a Postgres database element from a template. Async version.
1063
+
1064
+ Parameters
1065
+ ----------
1066
+ postgres_database : str
1067
+ The name of the Postgres database.
1068
+ server_name : str
1069
+ The server name of the Postgres server.
1070
+ host_identifier: str
1071
+ The host IP address or domain name.
1072
+ port : str
1073
+ The port number of the Postgres server.
1074
+ db_user: str
1075
+ User name to connect to the database
1076
+ db_pwd: str
1077
+ User password to connect to the database
1078
+ description: str, opt
1079
+ A description of the element.
1080
+
1081
+ Returns
1082
+ -------
1083
+ str
1084
+ The GUID of the Postgres database element.
1085
+ """
1086
+ template_guid = await self._async_get_template_guid_for_technology_type("PostgreSQL Relational Database")
1087
+
1088
+ body = {
1089
+ "class": "TemplateRequestBody",
1090
+ "templateGUID": template_guid,
1091
+ "isOwnAnchor": "true",
1092
+ "placeholderPropertyValues": {
1093
+ "databaseName": postgres_database,
1094
+ "serverName": server_name,
1095
+ "hostIdentifier": host_identifier,
1096
+ "portNumber": port,
1097
+ "databaseUserId": db_user,
1098
+ "description": description,
1099
+ "databasePassword": db_pwd,
1100
+ },
1101
+ }
1102
+ body_s = body_slimmer(body)
1103
+ response = await self._async_create_elem_from_template(body_s)
1104
+ return str(response)
1105
+
1106
+ def create_postgres_database_element_from_template(
1107
+ self,
1108
+ postgres_database: str,
1109
+ server_name: str,
1110
+ host_identifier: str,
1111
+ port: str,
1112
+ db_user: str,
1113
+ db_pwd: str,
1114
+ description: Optional[str] = None,
1115
+ ) -> str:
1116
+ """Create a Postgres database element from a template. Async version.
1117
+
1118
+ Parameters
1119
+ ----------
1120
+ postgres_database : str
1121
+ The name of the Postgres database.
1122
+ server_name : str
1123
+ The server name of the Postgres server.
1124
+ host_identifier: str
1125
+ The host IP address or domain name.
1126
+ port : str
1127
+ The port number of the Postgres server.
1128
+ db_user: str
1129
+ User name to connect to the database
1130
+ db_pwd: str
1131
+ User password to connect to the database
1132
+ description: str, opt
1133
+ A description of the element.
1134
+
1135
+ Returns
1136
+ -------
1137
+ str
1138
+ The GUID of the Postgres database element.
1139
+ """
1140
+ loop = asyncio.get_event_loop()
1141
+ response = loop.run_until_complete(
1142
+ self._async_create_postgres_database_element_from_template(
1143
+ postgres_database,
1144
+ server_name,
1145
+ host_identifier,
1146
+ port,
1147
+ db_user,
1148
+ db_pwd,
1149
+ description,
1150
+ )
1151
+ )
1152
+ return response
1153
+
1154
+ async def _async_create_folder_element_from_template(
1155
+ self,
1156
+ path_name: str,
1157
+ folder_name: str,
1158
+ file_system: str,
1159
+ description: Optional[str] = None,
1160
+ version: Optional[str] = None,
1161
+ ) -> str:
1162
+ """Create a File folder element from a template.
1163
+ Async version.
1164
+
1165
+ Parameters
1166
+ ----------
1167
+ path_name : str
1168
+ The path including the folder..
1169
+
1170
+ folder_name : str
1171
+ The name of the folder to create.
1172
+
1173
+ file_system : str
1174
+ The unique name for the file system that the folder belongs to. It may be a machine name or URL to a
1175
+ remote file store.
1176
+
1177
+ description: str, opt
1178
+ A description of the element.
1179
+
1180
+ version: str, opt
1181
+ version of the element - typically of the form x.y.z
1182
+
1183
+
1184
+
1185
+ Returns
1186
+ -------
1187
+ str
1188
+ The GUID of the File Folder element.
1189
+ """
1190
+ template_guid = await self._async_get_template_guid_for_technology_type("File System Directory")
1191
+
1192
+ body = {
1193
+ "class": "TemplateRequestBody",
1194
+ "templateGUID": template_guid,
1195
+ "isOwnAnchor": "true",
1196
+ "placeholderPropertyValues": {
1197
+ "directoryPathName": path_name,
1198
+ "directoryName": folder_name,
1199
+ "versionIdentifier": version,
1200
+ "fileSystemName": file_system,
1201
+ "description": description,
1202
+ },
1203
+ }
1204
+ body_s = body_slimmer(body)
1205
+ response = await self._async_create_elem_from_template(body_s)
1206
+ return str(response)
1207
+
1208
+ def create_folder_element_from_template(
1209
+ self,
1210
+ path_name: str,
1211
+ folder_name: str,
1212
+ file_system: str,
1213
+ description: Optional[str] = None,
1214
+ version: Optional[str] = None,
1215
+ ) -> str:
1216
+ """Create a File folder element from a template.
1217
+
1218
+ Parameters
1219
+ ----------
1220
+ path_name : str
1221
+ The path including the folder..
1222
+
1223
+ folder_name : str
1224
+ The name of the folder to create.
1225
+
1226
+ file_system : str
1227
+ The unique name for the file system that the folder belongs to. It may be a machine name or URL to a
1228
+ remote file store.
1229
+
1230
+ description: str, opt
1231
+ A description of the element.
1232
+
1233
+ version: str, opt
1234
+ version of the element - typically of the form x.y.z
1235
+
1236
+
1237
+
1238
+ Returns
1239
+ -------
1240
+ str
1241
+ The GUID of the File Folder element.
1242
+ """
1243
+ loop = asyncio.get_event_loop()
1244
+ response = loop.run_until_complete(
1245
+ self._async_create_folder_element_from_template(
1246
+ path_name, folder_name, file_system, description, version
1247
+ )
1248
+ )
1249
+ return response
1250
+
1251
+ async def _async_create_uc_server_element_from_template(
1252
+ self,
1253
+ server_name: str,
1254
+ host_url: str,
1255
+ port: str,
1256
+ description: Optional[str] = None,
1257
+ version: Optional[str] = None,
1258
+ ) -> str:
1259
+ """Create a Unity Catalog Server element from a template. Async version.
1260
+
1261
+ Parameters
1262
+ ----------
1263
+ server_name : str
1264
+ The name of the Unity Catalog server we are configuring.
1265
+
1266
+ host_url : str
1267
+ The URL of the server.
1268
+
1269
+ port : str
1270
+ The port number of the server.
1271
+
1272
+ description: str, opt
1273
+ A description of the server.
1274
+
1275
+ version: str, opt
1276
+ version of the element - typically of the form x.y.z
1277
+
1278
+
1279
+
1280
+ Returns
1281
+ -------
1282
+ str
1283
+ The GUID of the File Folder element.
1284
+ """
1285
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Server")
1286
+
1287
+ body = {
1288
+ "class": "TemplateRequestBody",
1289
+ "templateGUID": template_guid,
1290
+ "isOwnAnchor": "true",
1291
+ "placeholderPropertyValues": {
1292
+ "serverName": server_name,
1293
+ "hostURL": host_url,
1294
+ "versionIdentifier": version,
1295
+ "portNumber": port,
1296
+ "description": description,
1297
+ },
1298
+ }
1299
+ body_s = body_slimmer(body)
1300
+ response = await self._async_create_elem_from_template(body_s)
1301
+ return str(response)
1302
+
1303
+ def create_uc_server_element_from_template(
1304
+ self,
1305
+ server_name: str,
1306
+ host_url: str,
1307
+ port: str,
1308
+ description: Optional[str] = None,
1309
+ version: Optional[str] = None,
1310
+ ) -> str:
1311
+ """Create a Unity Catalog Server element from a template. Async version.
1312
+
1313
+ Parameters
1314
+ ----------
1315
+ server_name : str
1316
+ The name of the Unity Catalog server we are configuring.
1317
+
1318
+ host_url : str
1319
+ The URL of the server.
1320
+
1321
+ port : str
1322
+ The port number of the server.
1323
+
1324
+ description: str, opt
1325
+ A description of the server.
1326
+
1327
+ version: str, opt
1328
+ version of the element - typically of the form x.y.z
1329
+
1330
+
1331
+
1332
+ Returns
1333
+ -------
1334
+ str
1335
+ The GUID of the File Folder element.
1336
+ """
1337
+ loop = asyncio.get_event_loop()
1338
+ response = loop.run_until_complete(
1339
+ self._async_create_uc_server_element_from_template(
1340
+ server_name, host_url, port, description, version
1341
+ )
1342
+ )
1343
+ return response
1344
+
1345
+ async def _async_create_uc_catalog_element_from_template(
1346
+ self,
1347
+ uc_catalog: str,
1348
+ network_address: str,
1349
+ description: Optional[str] = None,
1350
+ version: Optional[str] = None,
1351
+ ) -> str:
1352
+ """Create a Unity Catalog Catalog element from a template. Async version.
1353
+
1354
+ Parameters
1355
+ ----------
1356
+ uc_catalog : str
1357
+ The name of the UC catalog we are configuring.
1358
+
1359
+ network_address : str
1360
+ The endpoint of the catalog.
1361
+
1362
+ description: str, opt
1363
+ A description of the server.
1364
+
1365
+ version: str, opt
1366
+ version of the element - typically of the form x.y.z
1367
+
1368
+
1369
+
1370
+ Returns
1371
+ -------
1372
+ str
1373
+ The GUID of the File Folder element.
1374
+ """
1375
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Catalog")
1376
+
1377
+ body = {
1378
+ "class": "TemplateRequestBody",
1379
+ "templateGUID": template_guid,
1380
+ "isOwnAnchor": "true",
1381
+ "placeholderPropertyValues": {
1382
+ "ucCatalogName": uc_catalog,
1383
+ "serverNetworkAddress": network_address,
1384
+ "versionIdentifier": version,
1385
+ "description": description,
1386
+ },
1387
+ }
1388
+ body_s = body_slimmer(body)
1389
+ response = await self._async_create_elem_from_template(body_s)
1390
+ return str(response)
1391
+
1392
+ def create_uc_catalog_element_from_template(
1393
+ self,
1394
+ uc_catalog: str,
1395
+ network_address: str,
1396
+ description: Optional[str] = None,
1397
+ version: Optional[str] = None,
1398
+ ) -> str:
1399
+ """Create a Unity Catalog Catalog element from a template.
1400
+
1401
+ Parameters
1402
+ ----------
1403
+ uc_catalog : str
1404
+ The name of the UC catalog we are configuring.
1405
+
1406
+ network_address : str
1407
+ The endpoint of the catalog.
1408
+
1409
+ description: str, opt
1410
+ A description of the server.
1411
+
1412
+ version: str, opt
1413
+ version of the element - typically of the form x.y.z
1414
+
1415
+
1416
+
1417
+ Returns
1418
+ -------
1419
+ str
1420
+ The GUID of the File Folder element.
1421
+ """
1422
+ loop = asyncio.get_event_loop()
1423
+ response = loop.run_until_complete(
1424
+ self._async_create_uc_catalog_element_from_template(
1425
+ uc_catalog, network_address, description, version
1426
+ )
1427
+ )
1428
+ return response
1429
+
1430
+ async def _async_create_uc_schema_element_from_template(
1431
+ self,
1432
+ uc_catalog: str,
1433
+ uc_schema: str,
1434
+ network_address: str,
1435
+ description: Optional[str] = None,
1436
+ version: Optional[str] = None,
1437
+ ) -> str:
1438
+ """Create a Unity Catalog schema element from a template. Async version.
1439
+
1440
+ Parameters
1441
+ ----------
1442
+ uc_catalog : str
1443
+ The name of the UC catalog we are configuring.
1444
+
1445
+ uc_schema: str
1446
+ The name of the UC schema we are configuring.
1447
+
1448
+ network_address : str
1449
+ The endpoint of the catalog.
1450
+
1451
+ description: str, opt
1452
+ A description of the server.
1453
+
1454
+ version: str, opt
1455
+ version of the element - typically of the form x.y.z
1456
+
1457
+
1458
+
1459
+ Returns
1460
+ -------
1461
+ str
1462
+ The GUID of the File Folder element.
1463
+ """
1464
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Schema")
1465
+
1466
+ body = {
1467
+ "class": "TemplateRequestBody",
1468
+ "templateGUID": template_guid,
1469
+ "isOwnAnchor": "true",
1470
+ "placeholderPropertyValues": {
1471
+ "ucCatalogName": uc_catalog,
1472
+ "ucSchemaName": uc_schema,
1473
+ "serverNetworkAddress": network_address,
1474
+ "versionIdentifier": version,
1475
+ "description": description,
1476
+ },
1477
+ }
1478
+ body_s = body_slimmer(body)
1479
+ response = await self._async_create_elem_from_template(body_s)
1480
+ return str(response)
1481
+
1482
+ def create_uc_schema_element_from_template(
1483
+ self,
1484
+ uc_catalog: str,
1485
+ uc_schema: str,
1486
+ network_address: str,
1487
+ description: Optional[str] = None,
1488
+ version: Optional[str] = None,
1489
+ ) -> str:
1490
+ """Create a Unity Catalog schema element from a template. Async version.
1491
+
1492
+ Parameters
1493
+ ----------
1494
+ uc_catalog : str
1495
+ The name of the UC catalog we are configuring.
1496
+
1497
+ uc_schema: str
1498
+ The name of the UC schema we are configuring.
1499
+
1500
+ network_address : str
1501
+ The endpoint of the catalog.
1502
+
1503
+ description: str, opt
1504
+ A description of the server.
1505
+
1506
+ version: str, opt
1507
+ version of the element - typically of the form x.y.z
1508
+
1509
+
1510
+
1511
+ Returns
1512
+ -------
1513
+ str
1514
+ The GUID of the File Folder element.
1515
+ """
1516
+ loop = asyncio.get_event_loop()
1517
+ response = loop.run_until_complete(
1518
+ self._async_create_uc_schema_element_from_template(
1519
+ uc_catalog, uc_schema, network_address, description, version
1520
+ )
1521
+ )
1522
+ return response
1523
+
1524
+ async def _async_create_uc_table_element_from_template(
1525
+ self,
1526
+ uc_catalog: str,
1527
+ uc_schema: str,
1528
+ uc_table: str,
1529
+ uc_table_type: str,
1530
+ uc_storage_loc: str,
1531
+ uc_data_source_format: str,
1532
+ network_address: str,
1533
+ description: Optional[str] = None,
1534
+ version: Optional[str] = None,
1535
+ ) -> str:
1536
+ """Create a Unity Catalog table element from a template. Async version.
1537
+
1538
+ Parameters
1539
+ ----------
1540
+ uc_catalog : str
1541
+ The name of the UC catalog we are configuring.
1542
+
1543
+ uc_schema: str
1544
+ The name of the UC schema we are configuring.
1545
+
1546
+ uc_table: str
1547
+ The name of the UC table we are configuring.
1548
+ uc_table_type: str
1549
+ The type of table - expect either Managed or External.
1550
+ uc_storage_loc: str
1551
+ The location where the data associated with this element is stored.
1552
+ uc_data_source_format: str
1553
+ The format of the data source - currently DELTA, CSV, JSON, AVRO, PARQUET, ORC, TEXT.
1554
+
1555
+ network_address : str
1556
+ The endpoint of the catalog.
1557
+
1558
+ description: str, opt
1559
+ A description of the server.
1560
+
1561
+ version: str, opt
1562
+ version of the element - typically of the form x.y.z
1563
+
1564
+
1565
+
1566
+ Returns
1567
+ -------
1568
+ str
1569
+ The GUID of the File Folder element.
1570
+ """
1571
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Table")
1572
+
1573
+ body = {
1574
+ "class": "TemplateRequestBody",
1575
+ "templateGUID": template_guid,
1576
+ "isOwnAnchor": "true",
1577
+ "placeholderPropertyValues": {
1578
+ "ucCatalogName": uc_catalog,
1579
+ "ucSchemaName": uc_schema,
1580
+ "ucTableName": uc_table,
1581
+ "ucTableType": uc_table_type,
1582
+ "ucStorageLocation": uc_storage_loc,
1583
+ "ucDataSourceFormat": uc_data_source_format,
1584
+ "serverNetworkAddress": network_address,
1585
+ "versionIdentifier": version,
1586
+ "description": description,
1587
+ },
1588
+ }
1589
+ body_s = body_slimmer(body)
1590
+ response = await self._async_create_elem_from_template(body_s)
1591
+ return str(response)
1592
+
1593
+ def create_uc_table_element_from_template(
1594
+ self,
1595
+ uc_catalog: str,
1596
+ uc_schema: str,
1597
+ uc_table: str,
1598
+ uc_table_type: str,
1599
+ uc_storage_loc: str,
1600
+ uc_data_source_format: str,
1601
+ network_address: str,
1602
+ description: Optional[str] = None,
1603
+ version: Optional[str] = None,
1604
+ ) -> str:
1605
+ """Create a Unity Catalog table element from a template.
1606
+
1607
+ Parameters
1608
+ ----------
1609
+ uc_catalog : str
1610
+ The name of the UC catalog we are configuring.
1611
+
1612
+ uc_schema: str
1613
+ The name of the UC schema we are configuring.
1614
+
1615
+ uc_table: str
1616
+ The name of the UC table we are configuring.
1617
+ uc_table_type: str
1618
+ The type of table - expect either Managed or External.
1619
+ uc_storage_loc: str
1620
+ The location where the data associated with this element is stored.
1621
+ uc_data_source_format: str
1622
+ The format of the data source - currently DELTA, CSV, JSON, AVRO, PARQUET, ORC, TEXT.
1623
+
1624
+ network_address : str
1625
+ The endpoint of the catalog.
1626
+
1627
+ description: str, opt
1628
+ A description of the server.
1629
+
1630
+ version: str, opt
1631
+ version of the element - typically of the form x.y.z
1632
+
1633
+
1634
+
1635
+ Returns
1636
+ -------
1637
+ str
1638
+ The GUID of the File Folder element.
1639
+ """
1640
+ loop = asyncio.get_event_loop()
1641
+ response = loop.run_until_complete(
1642
+ self._async_create_uc_table_element_from_template(
1643
+ uc_catalog,
1644
+ uc_schema,
1645
+ uc_table,
1646
+ uc_table_type,
1647
+ uc_storage_loc,
1648
+ uc_data_source_format,
1649
+ network_address,
1650
+ description,
1651
+ version,
1652
+ )
1653
+ )
1654
+ return response
1655
+
1656
+ async def _async_create_uc_function_element_from_template(
1657
+ self,
1658
+ uc_catalog: str,
1659
+ uc_schema: str,
1660
+ uc_function: str,
1661
+ network_address: str,
1662
+ description: Optional[str] = None,
1663
+ version: Optional[str] = None,
1664
+ ) -> str:
1665
+ """Create a Unity Catalog function element from a template. Async version.
1666
+
1667
+ Parameters
1668
+ ----------
1669
+ uc_catalog : str
1670
+ The name of the UC catalog we are configuring.
1671
+
1672
+ uc_schema: str
1673
+ The name of the UC schema we are configuring.
1674
+
1675
+ uc_function: str
1676
+ The name of the UC function we are configuring.
1677
+
1678
+ network_address : str
1679
+ The endpoint of the catalog.
1680
+
1681
+ description: str, opt
1682
+ A description of the server.
1683
+
1684
+ version: str, opt
1685
+ version of the element - typically of the form x.y.z
1686
+
1687
+
1688
+
1689
+ Returns
1690
+ -------
1691
+ str
1692
+ The GUID of the File Folder element.
1693
+ """
1694
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Function")
1695
+
1696
+ body = {
1697
+ "class": "TemplateRequestBody",
1698
+ "templateGUID": template_guid,
1699
+ "isOwnAnchor": "true",
1700
+ "placeholderPropertyValues": {
1701
+ "ucCatalogName": uc_catalog,
1702
+ "ucSchemaName": uc_schema,
1703
+ "ucFunctionName": uc_function,
1704
+ "serverNetworkAddress": network_address,
1705
+ "versionIdentifier": version,
1706
+ "description": description,
1707
+ },
1708
+ }
1709
+ body_s = body_slimmer(body)
1710
+ response = await self._async_create_elem_from_template(body_s)
1711
+ return str(response)
1712
+
1713
+ def create_uc_function_element_from_template(
1714
+ self,
1715
+ uc_catalog: str,
1716
+ uc_schema: str,
1717
+ uc_function: str,
1718
+ network_address: str,
1719
+ description: Optional[str] = None,
1720
+ version: Optional[str] = None,
1721
+ ) -> str:
1722
+ """Create a Unity Catalog function element from a template.
1723
+
1724
+ Parameters
1725
+ ----------
1726
+ uc_catalog : str
1727
+ The name of the UC catalog we are configuring.
1728
+
1729
+ uc_schema: str
1730
+ The name of the UC schema we are configuring.
1731
+
1732
+ uc_function: str
1733
+ The name of the UC function we are configuring.
1734
+
1735
+ network_address : str
1736
+ The endpoint of the catalog.
1737
+
1738
+ description: str, opt
1739
+ A description of the server.
1740
+
1741
+ version: str, opt
1742
+ version of the element - typically of the form x.y.z
1743
+
1744
+
1745
+
1746
+ Returns
1747
+ -------
1748
+ str
1749
+ The GUID of the File Folder element.
1750
+ """
1751
+ loop = asyncio.get_event_loop()
1752
+ response = loop.run_until_complete(
1753
+ self._async_create_uc_function_element_from_template(
1754
+ uc_catalog,
1755
+ uc_schema,
1756
+ uc_function,
1757
+ network_address,
1758
+ description,
1759
+ version,
1760
+ )
1761
+ )
1762
+ return response
1763
+
1764
+ async def _async_create_uc_volume_element_from_template(
1765
+ self,
1766
+ uc_catalog: str,
1767
+ uc_schema: str,
1768
+ uc_volume: str,
1769
+ uc_vol_type: str,
1770
+ uc_storage_loc: str,
1771
+ network_address: str,
1772
+ description: Optional[str] = None,
1773
+ version: Optional[str] = None,
1774
+ ) -> str:
1775
+ """Create a Unity Catalog volume element from a template. Async version.
1776
+
1777
+ Parameters
1778
+ ----------
1779
+ uc_catalog : str
1780
+ The name of the UC catalog we are configuring.
1781
+
1782
+ uc_schema: str
1783
+ The name of the UC schema we are configuring.
1784
+
1785
+ uc_volume: str
1786
+ The name of the UC volume we are configuring.
1787
+
1788
+ uc_vol_type: str
1789
+ The volume type of the UC volume we are configuring. Currently Managed or External.
1790
+ uc_storage_loc: str
1791
+ The location with the data associated with this element is stored.
1792
+
1793
+ network_address : str
1794
+ The endpoint of the catalog.
1795
+
1796
+ description: str, opt
1797
+ A description of the server.
1798
+
1799
+ version: str, opt
1800
+ version of the element - typically of the form x.y.z
1801
+
1802
+
1803
+
1804
+ Returns
1805
+ -------
1806
+ str
1807
+ The GUID of the File Folder element.
1808
+ """
1809
+ template_guid = await self._async_get_template_guid_for_technology_type("Unity Catalog Volume")
1810
+
1811
+ body = {
1812
+ "class": "TemplateRequestBody",
1813
+ "templateGUID": template_guid,
1814
+ "isOwnAnchor": "true",
1815
+ "placeholderPropertyValues": {
1816
+ "ucCatalogName": uc_catalog,
1817
+ "ucSchemaName": uc_schema,
1818
+ "ucVolumeName": uc_volume,
1819
+ "ucVolumeType": uc_vol_type,
1820
+ "ucStorageLocation": uc_storage_loc,
1821
+ "serverNetworkAddress": network_address,
1822
+ "versionIdentifier": version,
1823
+ "description": description,
1824
+ },
1825
+ }
1826
+ body_s = body_slimmer(body)
1827
+ response = await self._async_create_elem_from_template(body_s)
1828
+ return str(response)
1829
+
1830
+ def create_uc_volume_element_from_template(
1831
+ self,
1832
+ uc_catalog: str,
1833
+ uc_schema: str,
1834
+ uc_volume: str,
1835
+ uc_vol_type: str,
1836
+ uc_storage_loc: str,
1837
+ network_address: str,
1838
+ description: Optional[str] = None,
1839
+ version: Optional[str] = None,
1840
+ ) -> str:
1841
+ """Create a Unity Catalog volume element from a template. Async version.
1842
+
1843
+ Parameters
1844
+ ----------
1845
+ uc_catalog : str
1846
+ The name of the UC catalog we are configuring.
1847
+
1848
+ uc_schema: str
1849
+ The name of the UC schema we are configuring.
1850
+
1851
+ uc_volume: str
1852
+ The name of the UC volume we are configuring.
1853
+
1854
+ uc_vol_type: str
1855
+ The volume type of the UC volume we are configuring. Currently Managed or External.
1856
+
1857
+ uc_storage_loc: str
1858
+ The location with the data associated with this element is stored.
1859
+
1860
+ network_address : str
1861
+ The endpoint of the catalog.
1862
+
1863
+ description: str, opt
1864
+ A description of the server.
1865
+
1866
+ version: str, opt
1867
+ version of the element - typically of the form x.y.z
1868
+
1869
+
1870
+
1871
+ Returns
1872
+ -------
1873
+ str
1874
+ The GUID of the File Folder element.
1875
+ """
1876
+ loop = asyncio.get_event_loop()
1877
+ response = loop.run_until_complete(
1878
+ self._async_create_uc_volume_element_from_template(
1879
+ uc_catalog,
1880
+ uc_schema,
1881
+ uc_volume,
1882
+ uc_vol_type,
1883
+ uc_storage_loc,
1884
+ network_address,
1885
+ description,
1886
+ version,
1887
+ )
1888
+ )
1889
+ return response
1890
+
1891
+ #
1892
+ # Engine Actions
1893
+ #
1894
+
1895
+ async def _async_cancel_engine_action(self, engine_action_guid: str) -> None:
1896
+ """Request that an engine action request is cancelled and any running governance service is stopped. Async Ver.
1897
+ Parameters
1898
+ ----------
1899
+ engine_action_guid : str
1900
+ The GUID of the engine action to retrieve.
1901
+
1902
+
1903
+
1904
+ Returns
1905
+ -------
1906
+ dict
1907
+ The JSON representation of the engine action.
1908
+
1909
+ Raises
1910
+ ------
1911
+ PyegeriaException
1912
+ Notes
1913
+ -----
1914
+ For more information see: https://egeria-project.org/concepts/engine-action
1915
+ """
1916
+
1917
+ validate_guid(engine_action_guid)
1918
+
1919
+ url = (
1920
+ f"{self.curation_command_root}/engine-actions/"
1921
+ f"{engine_action_guid}/cancel"
1922
+ )
1923
+
1924
+ await self._async_make_request("POST", url)
1925
+
1926
+ def cancel_engine_action(self, engine_action_guid: str) -> None:
1927
+ """Request that an engine action request is cancelled and any running governance service is stopped.
1928
+ Parameters
1929
+ ----------
1930
+ engine_action_guid : str
1931
+ The GUID of the engine action to retrieve.
1932
+
1933
+
1934
+
1935
+ Returns
1936
+ -------
1937
+ dict
1938
+ The JSON representation of the engine action.
1939
+
1940
+ Raises
1941
+ ------
1942
+ PyegeriaException
1943
+ Notes
1944
+ -----
1945
+ For more information see: https://egeria-project.org/concepts/engine-action
1946
+ """
1947
+ loop = asyncio.get_event_loop()
1948
+ loop.run_until_complete(self._async_cancel_engine_action(engine_action_guid))
1949
+ return
1950
+
1951
+ async def _async_get_active_engine_actions(
1952
+ self, start_from: int = 0, page_size: int = 0,
1953
+ output_format: str = "JSON", report_spec: str | dict = "Engine-Actions") -> list | str:
1954
+ """Retrieve the engine actions that are still in process. Async Version.
1955
+
1956
+ Parameters:
1957
+ ----------
1958
+
1959
+ start_from : int, optional
1960
+ The starting index of the actions to retrieve. Default is 0.
1961
+ page_size : int, optional
1962
+ The maximum number of actions to retrieve per page. Default is the global maximum paging size.
1963
+
1964
+ Returns:
1965
+ -------
1966
+ List[dict]: A list of JSON representations of governance action processes matching the provided name.
1967
+
1968
+ Raises:
1969
+ ------
1970
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
1971
+ this exception is raised with details from the response content.
1972
+
1973
+ Notes
1974
+ -----
1975
+ For more information see: https://egeria-project.org/concepts/engine-action
1976
+
1977
+ """
1978
+
1979
+ url = (
1980
+ f"{self.curation_command_root}/engine-actions/active"
1981
+ )
1982
+
1983
+ response = await self._async_make_request("GET", url)
1984
+ elements = response.json().get("elements", "No actions found")
1985
+ if type(elements) is str:
1986
+ logger.info("No Actions Found")
1987
+ return "No Actions Found"
1988
+
1989
+ if output_format.upper() != 'JSON': # return a simplified markdown representation
1990
+ # logger.info(f"Found elements, output format: {output_format} and report_spec: {report_spec}")
1991
+ return self._generate_engine_action_output(elements, None, "EngineAction",
1992
+ output_format, report_spec)
1993
+ return elements
1994
+
1995
+ def get_active_engine_actions(
1996
+ self, start_from: int = 0, page_size: int = 0,
1997
+ output_format: str = "JSON", report_spec: str | dict = "EngineAction",
1998
+ ) -> list | str:
1999
+ """Retrieve the engine actions that are still in process.
2000
+
2001
+ Parameters:
2002
+ ----------
2003
+
2004
+ start_from : int, optional
2005
+ The starting index of the actions to retrieve. Default is 0.
2006
+ page_size : int, optional
2007
+ The maximum number of actions to retrieve per page. Default is the global maximum paging size.
2008
+
2009
+ Returns
2010
+ -------
2011
+ List[dict]: A list of JSON representations of governance action processes matching the provided name.
2012
+
2013
+ Raises
2014
+ ------
2015
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
2016
+ this exception is raised with details from the response content.
2017
+ Notes
2018
+ -----
2019
+ For more information see: https://egeria-project.org/concepts/engine-action
2020
+
2021
+ """
2022
+ loop = asyncio.get_event_loop()
2023
+ response = loop.run_until_complete(
2024
+ self._async_get_active_engine_actions(start_from, page_size, output_format=output_format,
2025
+ report_spec=report_spec)
2026
+ )
2027
+ return response
2028
+
2029
+ async def _async_get_engine_actions_by_name(
2030
+ self,
2031
+ name: str,
2032
+ start_from: int = 0,
2033
+ page_size: int = 0,
2034
+ ) -> list | str:
2035
+ """Retrieve the list of engine action metadata elements with a matching qualified or display name.
2036
+ There are no wildcards supported on this request. Async Version.
2037
+ Parameters
2038
+ ----------
2039
+ name : str
2040
+ The name of the engine action to retrieve.
2041
+
2042
+ start_from : int, optional
2043
+ The index to start retrieving engine actions from. If not provided, the default value will be used.
2044
+ page_size : int, optional
2045
+ The maximum number of engine actions to retrieve in a single request. If not provided, the default global
2046
+ maximum paging size will be used.
2047
+
2048
+ Returns
2049
+ -------
2050
+ list of dict | str
2051
+ A list of dictionaries representing the retrieved engine actions, or "no actions" if no engine actions were
2052
+ found with the given name.
2053
+ Raises:
2054
+ ------
2055
+ PyegeriaException
2056
+ Notes
2057
+ -----
2058
+ For more information see: https://egeria-project.org/concepts/engine-action
2059
+
2060
+ """
2061
+
2062
+ validate_name(name)
2063
+
2064
+ url = (
2065
+ f"{self.curation_command_root}/engine-actions/by-name"
2066
+ )
2067
+ body = {"filter": name}
2068
+ response = await self._async_make_request("POST", url, body)
2069
+ return response.json().get("elements", "no actions")
2070
+
2071
+ def get_engine_actions_by_name(
2072
+ self,
2073
+ name: str,
2074
+ start_from: int = 0,
2075
+ page_size: int = 0,
2076
+ ) -> list | str:
2077
+ """Retrieve the list of engine action metadata elements with a matching qualified or display name.
2078
+ There are no wildcards supported on this request.
2079
+
2080
+ Parameters
2081
+ ----------
2082
+ name : str
2083
+ The name of the engine action to retrieve.
2084
+
2085
+ start_from : int, optional
2086
+ The index to start retrieving engine actions from. If not provided, the default value will be used.
2087
+ page_size : int, optional
2088
+ The maximum number of engine actions to retrieve in a single request. If not provided, the default global
2089
+ maximum paging size will be used.
2090
+
2091
+ Returns
2092
+ -------
2093
+ list of dict | str
2094
+ A list of dictionaries representing the retrieved engine actions, or "no actions" if no engine actions were
2095
+ found with the given name.
2096
+ Raises:
2097
+ ------
2098
+ PyegeriaException
2099
+ Notes
2100
+ -----
2101
+ For more information see: https://egeria-project.org/concepts/engine-action
2102
+
2103
+ """
2104
+ loop = asyncio.get_event_loop()
2105
+ response = loop.run_until_complete(
2106
+ self._async_get_engine_actions_by_name(name, start_from, page_size)
2107
+ )
2108
+ return response
2109
+
2110
+ @dynamic_catch
2111
+ async def _async_find_engine_actions(self, search_string: str = "*",
2112
+ starts_with: bool = True, ends_with: bool = False,
2113
+ ignore_case: bool = False,
2114
+ anchor_domain: Optional[str] = None,
2115
+ metadata_element_type: Optional[str] = None,
2116
+ metadata_element_subtypes: Optional[list[str]] = None,
2117
+ skip_relationships: Optional[list[str]] = None,
2118
+ include_only_relationships: Optional[list[str]] = None,
2119
+ skip_classified_elements: Optional[list[str]] = None,
2120
+ include_only_classified_elements: Optional[list[str]] = None,
2121
+ graph_query_depth: int = 3,
2122
+ governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
2123
+ effective_time: Optional[str] = None, relationship_page_size: int = 0,
2124
+ limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
2125
+ sequencing_property: Optional[str] = None,
2126
+ output_format: str = "JSON",
2127
+ report_spec: str | dict = "EngineAction",
2128
+ start_from: int = 0, page_size: int = 100,
2129
+ property_names: Optional[list[str]] = None,
2130
+ body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
2131
+ """ Retrieve the list of engine action metadata elements that contain the search string. Async Version.
2132
+
2133
+ Parameters
2134
+ ----------
2135
+ search_string: str
2136
+ Search string to match against - None or '*' indicate match against all engine actions.
2137
+ starts_with : bool, [default=True], optional
2138
+ Starts with the supplied string.
2139
+ ends_with : bool, [default=False], optional
2140
+ Ends with the supplied string
2141
+ ignore_case : bool, [default=False], optional
2142
+ Ignore case when searching
2143
+ anchor_domain: str, optional
2144
+ The anchor domain to search in.
2145
+ metadata_element_type: str, optional
2146
+ The type of metadata element to search for.
2147
+ metadata_element_subtypes: list[str], optional
2148
+ The subtypes of metadata element to search for.
2149
+ skip_relationships: list[str], optional
2150
+ The types of relationships to skip.
2151
+ include_only_relationships: list[str], optional
2152
+ The types of relationships to include.
2153
+ skip_classified_elements: list[str], optional
2154
+ The types of classified elements to skip.
2155
+ include_only_classified_elements: list[str], optional
2156
+ The types of classified elements to include.
2157
+ graph_query_depth: int, [default=3], optional
2158
+ The depth of the graph query.
2159
+ governance_zone_filter: list[str], optional
2160
+ The governance zones to search in.
2161
+ as_of_time: str, optional
2162
+ The time to search as of.
2163
+ effective_time: str, optional
2164
+ The effective time to search at.
2165
+ relationship_page_size: int, [default=0], optional
2166
+ The page size for relationships.
2167
+ limit_results_by_status: list[str], optional
2168
+ The statuses to limit results by.
2169
+ sequencing_order: str, optional
2170
+ The order to sequence results by.
2171
+ sequencing_property: str, optional
2172
+ The property to sequence results by.
2173
+ output_format: str, default = "JSON"
2174
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
2175
+ report_spec: str | dict , optional, default = "EngineAction"
2176
+ - The desired output columns/fields to include.
2177
+ start_from: int, [default=0], optional
2178
+ When multiple pages of results are available, the page number to start from.
2179
+ page_size: int, [default=100]
2180
+ The number of items to return in a single page.
2181
+ property_names: list[str], optional
2182
+ The names of properties to search for.
2183
+ body: dict | SearchStringRequestBody, optional, default = None
2184
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
2185
+
2186
+ Returns
2187
+ -------
2188
+ List | str
2189
+
2190
+ Output depends on the output format specified.
2191
+
2192
+ Raises
2193
+ -------
2194
+
2195
+ ValidationError
2196
+ If the client passes incorrect parameters on the request that don't conform to the data model.
2197
+ PyegeriaException
2198
+ Issues raised in communicating or server side processing.
2199
+ NotAuthorizedException
2200
+ The principle specified by the user_id does not have authorization for the requested action
2201
+
2202
+ """
2203
+ url = str(HttpUrl(f"{self.curation_command_root}/assets/by-search-string"))
2204
+ response = await self._async_find_request(url, _type=self.ENGINE_ACTION_LABEL, _gen_output=self._generate_engine_action_output,
2205
+ search_string=search_string, starts_with=starts_with,
2206
+ ends_with=ends_with, ignore_case=ignore_case,
2207
+ anchor_domain=anchor_domain,
2208
+ metadata_element_type=metadata_element_type,
2209
+ metadata_element_subtypes=metadata_element_subtypes,
2210
+ skip_relationships=skip_relationships,
2211
+ include_only_relationships=include_only_relationships,
2212
+ skip_classified_elements=skip_classified_elements,
2213
+ include_only_classified_elements=include_only_classified_elements,
2214
+ graph_query_depth=graph_query_depth,
2215
+ governance_zone_filter=governance_zone_filter,
2216
+ as_of_time=as_of_time, effective_time=effective_time,
2217
+ relationship_page_size=relationship_page_size,
2218
+ limit_results_by_status=limit_results_by_status,
2219
+ sequencing_order=sequencing_order,
2220
+ sequencing_property=sequencing_property,
2221
+ output_format=output_format, report_spec=report_spec,
2222
+ start_from=start_from, page_size=page_size,
2223
+ property_names=property_names, body=body)
2224
+
2225
+ return response
2226
+
2227
+ @dynamic_catch
2228
+ def find_engine_actions(self, search_string: str = "*",
2229
+ starts_with: bool = True, ends_with: bool = False,
2230
+ ignore_case: bool = False,
2231
+ anchor_domain: Optional[str] = None,
2232
+ metadata_element_type: Optional[str] = None,
2233
+ metadata_element_subtypes: Optional[list[str]] = None,
2234
+ skip_relationships: Optional[list[str]] = None,
2235
+ include_only_relationships: Optional[list[str]] = None,
2236
+ skip_classified_elements: Optional[list[str]] = None,
2237
+ include_only_classified_elements: Optional[list[str]] = None,
2238
+ graph_query_depth: int = 3,
2239
+ governance_zone_filter: Optional[list[str]] = None, as_of_time: Optional[str] = None,
2240
+ effective_time: Optional[str] = None, relationship_page_size: int = 0,
2241
+ limit_results_by_status: Optional[list[str]] = None, sequencing_order: Optional[str] = None,
2242
+ sequencing_property: Optional[str] = None,
2243
+ output_format: str = "JSON",
2244
+ report_spec: str | dict = "EngineAction",
2245
+ start_from: int = 0, page_size: int = 100,
2246
+ property_names: Optional[list[str]] = None,
2247
+ body: Optional[dict | SearchStringRequestBody] = None) -> list | str:
2248
+ """ Retrieve the list of engine action metadata elements that contain the search string.
2249
+
2250
+ Parameters
2251
+ ----------
2252
+ search_string: str
2253
+ Search string to match against - None or '*' indicate match against all engine actions.
2254
+ starts_with : bool, [default=True], optional
2255
+ Starts with the supplied string.
2256
+ ends_with : bool, [default=False], optional
2257
+ Ends with the supplied string
2258
+ ignore_case : bool, [default=False], optional
2259
+ Ignore case when searching
2260
+ anchor_domain: str, optional
2261
+ The anchor domain to search in.
2262
+ metadata_element_type: str, optional
2263
+ The type of metadata element to search for.
2264
+ metadata_element_subtypes: list[str], optional
2265
+ The subtypes of metadata element to search for.
2266
+ skip_relationships: list[str], optional
2267
+ The types of relationships to skip.
2268
+ include_only_relationships: list[str], optional
2269
+ The types of relationships to include.
2270
+ skip_classified_elements: list[str], optional
2271
+ The types of classified elements to skip.
2272
+ include_only_classified_elements: list[str], optional
2273
+ The types of classified elements to include.
2274
+ graph_query_depth: int, [default=3], optional
2275
+ The depth of the graph query.
2276
+ governance_zone_filter: list[str], optional
2277
+ The governance zones to search in.
2278
+ as_of_time: str, optional
2279
+ The time to search as of.
2280
+ effective_time: str, optional
2281
+ The effective time to search at.
2282
+ relationship_page_size: int, [default=0], optional
2283
+ The page size for relationships.
2284
+ limit_results_by_status: list[str], optional
2285
+ The statuses to limit results by.
2286
+ sequencing_order: str, optional
2287
+ The order to sequence results by.
2288
+ sequencing_property: str, optional
2289
+ The property to sequence results by.
2290
+ output_format: str, default = "JSON"
2291
+ - one of "MD", "LIST", "FORM", "REPORT", "DICT", "MERMAID" or "JSON"
2292
+ report_spec: str | dict , optional, default = "EngineAction"
2293
+ - The desired output columns/fields to include.
2294
+ start_from: int, [default=0], optional
2295
+ When multiple pages of results are available, the page number to start from.
2296
+ page_size: int, [default=100]
2297
+ The number of items to return in a single page.
2298
+ property_names: list[str], optional
2299
+ The names of properties to search for.
2300
+ body: dict | SearchStringRequestBody, optional, default = None
2301
+ - if provided, the search parameters in the body will supercede other attributes, such as "search_string"
2302
+
2303
+ Returns
2304
+ -------
2305
+ List | str
2306
+
2307
+ Output depends on the output format specified.
2308
+
2309
+ Raises
2310
+ -------
2311
+
2312
+ ValidationError
2313
+ If the client passes incorrect parameters on the request that don't conform to the data model.
2314
+ PyegeriaException
2315
+ Issues raised in communicating or server side processing.
2316
+ NotAuthorizedException
2317
+ The principle specified by the user_id does not have authorization for the requested action
2318
+
2319
+ """
2320
+ loop = asyncio.get_event_loop()
2321
+ return loop.run_until_complete(self._async_find_engine_actions(search_string=search_string,
2322
+ starts_with=starts_with,
2323
+ ends_with=ends_with,
2324
+ ignore_case=ignore_case,
2325
+ anchor_domain=anchor_domain,
2326
+ metadata_element_type=metadata_element_type,
2327
+ metadata_element_subtypes=metadata_element_subtypes,
2328
+ skip_relationships=skip_relationships,
2329
+ include_only_relationships=include_only_relationships,
2330
+ skip_classified_elements=skip_classified_elements,
2331
+ include_only_classified_elements=include_only_classified_elements,
2332
+ graph_query_depth=graph_query_depth,
2333
+ governance_zone_filter=governance_zone_filter,
2334
+ as_of_time=as_of_time,
2335
+ effective_time=effective_time,
2336
+ relationship_page_size=relationship_page_size,
2337
+ limit_results_by_status=limit_results_by_status,
2338
+ sequencing_order=sequencing_order,
2339
+ sequencing_property=sequencing_property,
2340
+ output_format=output_format,
2341
+ report_spec=report_spec,
2342
+ start_from=start_from,
2343
+ page_size=page_size,
2344
+ property_names=property_names,
2345
+ body=body))
2346
+
2347
+ #
2348
+ # Governance action processes
2349
+ #
2350
+
2351
+
2352
+ async def _async_initiate_gov_action_process(
2353
+ self,
2354
+ action_type_qualified_name: str,
2355
+ request_source_guids: [str] = None,
2356
+ action_targets: list = None,
2357
+ start_time: datetime = None,
2358
+ request_parameters: dict = None,
2359
+ orig_service_name: Optional[str] = None,
2360
+ orig_engine_name: Optional[str] = None,
2361
+ ) -> str:
2362
+ """Using the named governance action process as a template, initiate a chain of engine actions. Async version.
2363
+
2364
+ Parameters
2365
+ ----------
2366
+ action_type_qualified_name: str
2367
+ - unique name for the governance process
2368
+ request_source_guids: [str], optional
2369
+ - request source elements for the resulting governance action service
2370
+ action_targets: [str], optional
2371
+ -list of action target names to GUIDs for the resulting governance action service
2372
+ start_time: datetime, optional
2373
+ - time to start the process
2374
+ request_parameters: [str], optional
2375
+ - parameters passed into the process
2376
+ orig_service_name: str, optional
2377
+ - unique name of the requesting governance service (if initiated by a governance engine)
2378
+ orig_engine_name: str, optional
2379
+ - optional unique name of the governance engine (if initiated by a governance engine).
2380
+
2381
+ Returns
2382
+ -------
2383
+ Unique id (guid) of the newly started governance engine process
2384
+
2385
+ Raises
2386
+ ------
2387
+ PyegeriaException
2388
+ """
2389
+
2390
+ start_time: datetime = (
2391
+ datetime.datetime.now() if start_time is None else start_time
2392
+ )
2393
+
2394
+ url = f"{self.curation_command_root}/governance-action-processes/initiate"
2395
+ body = {
2396
+ "class": "GovernanceActionProcessRequestBody",
2397
+ "processQualifiedName": action_type_qualified_name,
2398
+ "requestSourceGUIDs": request_source_guids,
2399
+ "actionTargets": action_targets,
2400
+ "startTime": int(start_time.timestamp() * 1000),
2401
+ "requestParameters": request_parameters,
2402
+ "originatorServiceName": orig_service_name,
2403
+ "originatorEngineName": orig_engine_name,
2404
+ }
2405
+ new_body = body_slimmer(body)
2406
+ response = await self._async_make_request("POST", url, new_body)
2407
+ return response.json().get("guid", "Action not initiated")
2408
+
2409
+ def initiate_gov_action_process(
2410
+ self,
2411
+ action_type_qualified_name: str,
2412
+ request_source_guids: [str] = None,
2413
+ action_targets: [str] = None,
2414
+ start_time: datetime = None,
2415
+ request_parameters: dict = None,
2416
+ orig_service_name: Optional[str] = None,
2417
+ orig_engine_name: Optional[str] = None,
2418
+ ) -> str:
2419
+ """Using the named governance action process as a template, initiate a chain of engine actions.
2420
+
2421
+ Parameters
2422
+ ----------
2423
+ action_type_qualified_name: str
2424
+ - unique name for the governance process
2425
+ request_source_guids: [str], optional
2426
+ - request source elements for the resulting governance action service
2427
+ action_targets: [str], optional
2428
+ -list of action target names to GUIDs for the resulting governance action service
2429
+ start_time: datetime, optional
2430
+ - time to start the process
2431
+ request_parameters: [str], optional
2432
+ - parameters passed into the process
2433
+ orig_service_name: str, optional
2434
+ - unique name of the requesting governance service (if initiated by a governance engine)
2435
+ orig_engine_name: str, optional
2436
+ - optional unique name of the governance engine (if initiated by a governance engine).
2437
+
2438
+ Returns
2439
+ -------
2440
+ Unique id (guid) of the newly started governance engine process
2441
+
2442
+ Raises
2443
+ ------
2444
+ PyegeriaException
2445
+ """
2446
+ loop = asyncio.get_event_loop()
2447
+ response = loop.run_until_complete(
2448
+ self._async_initiate_gov_action_process(
2449
+ action_type_qualified_name,
2450
+ request_source_guids,
2451
+ action_targets,
2452
+ start_time,
2453
+ request_parameters,
2454
+ orig_service_name,
2455
+ orig_engine_name,
2456
+ )
2457
+ )
2458
+ return response
2459
+
2460
+
2461
+
2462
+ async def _async_initiate_gov_action_type(
2463
+ self,
2464
+ action_type_qualified_name: str,
2465
+ request_source_guids: [str],
2466
+ action_targets: list,
2467
+ start_time: datetime = None,
2468
+ request_parameters: dict = None,
2469
+ orig_service_name: Optional[str] = None,
2470
+ orig_engine_name: Optional[str] = None,
2471
+ ) -> str:
2472
+ """Using the named governance action type as a template, initiate an engine action. Async version.
2473
+
2474
+ Parameters
2475
+ ----------
2476
+ action_type_qualified_name: str
2477
+ - unique name for the governance process
2478
+ request_source_guids: [str]
2479
+ - request source elements for the resulting governance action service
2480
+ action_targets: [str]
2481
+ -list of action target names to GUIDs for the resulting governance action service
2482
+ start_time: datetime, default = None
2483
+ - time to start the process, no earlier than start time. None means now.
2484
+ request_parameters: [str]
2485
+ - parameters passed into the process
2486
+ orig_service_name: str
2487
+ - unique name of the requesting governance service (if initiated by a governance engine)
2488
+ orig_engine_name: str
2489
+ - optional unique name of the governance engine (if initiated by a governance engine).
2490
+
2491
+ Returns
2492
+ -------
2493
+ Unique id (guid) of the newly started governance engine process
2494
+
2495
+ Raises
2496
+ ------
2497
+ PyegeriaException
2498
+ """
2499
+
2500
+ url = f"{self.curation_command_root}/governance-action-types/initiate"
2501
+ start = int(start_time.timestamp() * 1000) if start_time else None
2502
+ body = {
2503
+ "class": "InitiateGovernanceActionTypeRequestBody",
2504
+ "governanceActionTypeQualifiedName": action_type_qualified_name,
2505
+ "requestSourceGUIDs": request_source_guids,
2506
+ "actionTargets": action_targets,
2507
+ "startDate": start,
2508
+ "requestParameters": request_parameters,
2509
+ "originatorServiceName": orig_service_name,
2510
+ "originatorEngineName": orig_engine_name,
2511
+ }
2512
+ new_body = body_slimmer(body)
2513
+ response = await self._async_make_request("POST", url, new_body)
2514
+ return response.json().get("guid", "Action not initiated")
2515
+
2516
+ def initiate_gov_action_type(
2517
+ self,
2518
+ action_type_qualified_name: str,
2519
+ request_source_guids: [str],
2520
+ action_targets: list,
2521
+ start_time: datetime = None,
2522
+ request_parameters: dict = None,
2523
+ orig_service_name: Optional[str] = None,
2524
+ orig_engine_name: Optional[str] = None,
2525
+ ) -> str:
2526
+ """Using the named governance action type as a template, initiate an engine action.
2527
+
2528
+ Parameters
2529
+ ----------
2530
+ action_type_qualified_name: str
2531
+ - unique name for the governance process
2532
+ request_source_guids: [str]
2533
+ - request source elements for the resulting governance action service
2534
+ action_targets: [str]
2535
+ -list of action target names to GUIDs for the resulting governance action service
2536
+ start_time: datetime, default = None
2537
+ - time to start the process, no earlier than start time. None means now.
2538
+ request_parameters: [str]
2539
+ - parameters passed into the process
2540
+ orig_service_name: str
2541
+ - unique name of the requesting governance service (if initiated by a governance engine)
2542
+ orig_engine_name: str
2543
+ - optional unique name of the governance engine (if initiated by a governance engine).
2544
+
2545
+ Returns
2546
+ -------
2547
+ Unique id (guid) of the newly started governance engine process
2548
+
2549
+ Raises
2550
+ ------
2551
+ PyegeriaException """
2552
+ loop = asyncio.get_event_loop()
2553
+ response = loop.run_until_complete(
2554
+ self._async_initiate_gov_action_type(
2555
+ action_type_qualified_name,
2556
+ request_source_guids,
2557
+ action_targets,
2558
+ start_time,
2559
+ request_parameters,
2560
+ orig_service_name,
2561
+ orig_engine_name,
2562
+ )
2563
+ )
2564
+ return response
2565
+
2566
+ #
2567
+ # Initiate surveys
2568
+ #
2569
+
2570
+ async def _async_initiate_survey(self, survey_name: str, resource_guid: str) -> str:
2571
+ """Initiate a survey of the survey_name on the target resource. Async Version.
2572
+
2573
+ Parameters
2574
+ ----------
2575
+ survey_name: str
2576
+ The name of the survey to initiate.
2577
+ resource_guid : str
2578
+ The GUID of the resource to be surveyed.
2579
+
2580
+ Returns
2581
+ -------
2582
+ str
2583
+ The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2584
+
2585
+ """
2586
+
2587
+ url = f"{self.curation_command_root}/governance-action-types/initiate"
2588
+
2589
+ body = {
2590
+ "class": "InitiateGovernanceActionTypeRequestBody",
2591
+ "governanceActionTypeQualifiedName": survey_name,
2592
+ "actionTargets": [
2593
+ {
2594
+ "class": "NewActionTarget",
2595
+ "actionTargetName": "serverToSurvey",
2596
+ "actionTargetGUID": resource_guid.strip(),
2597
+ }
2598
+ ],
2599
+ }
2600
+ response = await self._async_make_request("POST", url, body)
2601
+ return response.json().get("guid", "Action not initiated")
2602
+
2603
+ def initiate_postgres_database_survey(self, postgres_database_guid: str) -> str:
2604
+ """Initiate a postgres database survey"""
2605
+ loop = asyncio.get_event_loop()
2606
+ response = loop.run_until_complete(
2607
+ self._async_initiate_survey(
2608
+ "PostgreSQLSurvey:survey-postgres-database", postgres_database_guid
2609
+ )
2610
+ )
2611
+ return response
2612
+
2613
+ def initiate_postgres_server_survey(self, postgres_server_guid: str) -> str:
2614
+ """Initiate a postgres server survey"""
2615
+ loop = asyncio.get_event_loop()
2616
+ response = loop.run_until_complete(
2617
+ self._async_initiate_survey(
2618
+ "PostgreSQLSurvey:survey-postgres-server", postgres_server_guid
2619
+ )
2620
+ )
2621
+ return response
2622
+
2623
+ def initiate_file_folder_survey(
2624
+ self,
2625
+ file_folder_guid: str,
2626
+ survey_name: str = "FileSurveys:survey-folder",
2627
+ ) -> str:
2628
+ """Initiate a file folder survey - async version
2629
+
2630
+ Parameters:
2631
+ ----------
2632
+ file_folder_guid: str
2633
+ The GUID of the File Folder that we wish to survey.
2634
+ survey_name: str, optional
2635
+ The unique name of the survey routine to execute. Default surveys all folders.
2636
+
2637
+ Returns:
2638
+ -------
2639
+ str:
2640
+ The guid of the survey being run.
2641
+
2642
+ Raises:
2643
+ ------
2644
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
2645
+ this exception is raised with details from the response content.
2646
+ PyegeriaAPIException: If the API response indicates a server side error.
2647
+ PyegeriaUnauthorizedException:
2648
+
2649
+ Notes:
2650
+ There are multiple kinds of file folder surveys available, each with their own purpose. They are described
2651
+ in the Core Content Brain.
2652
+
2653
+ File Folder Survey Names currently include::
2654
+ - Egeria:GovernanceActionType:AssetSurvey:survey-folders
2655
+ - Egeria:GovernanceActionType:AssetSurvey:survey-folder-and-files
2656
+ - Egeria:GovernanceActionType:AssetSurvey:survey-all-folders
2657
+ - Egeria:GovernanceActionType:AssetSurvey:survey-all-folders-and-files
2658
+
2659
+
2660
+ """
2661
+ loop = asyncio.get_event_loop()
2662
+ response = loop.run_until_complete(
2663
+ self._async_initiate_survey(
2664
+ survey_name,
2665
+ file_folder_guid,
2666
+ )
2667
+ )
2668
+ return response
2669
+
2670
+ def initiate_file_survey(self, file_guid: str) -> str:
2671
+ """Initiate a file survey"""
2672
+ loop = asyncio.get_event_loop()
2673
+ response = loop.run_until_complete(
2674
+ self._async_initiate_survey("FileSurveys:survey-data-file", file_guid)
2675
+ )
2676
+ return response
2677
+
2678
+ def initiate_kafka_server_survey(self, kafka_server_guid: str) -> str:
2679
+ """Initiate survey of a kafka server.
2680
+ Parameters
2681
+ ----------
2682
+ kafka_server_guid : str
2683
+ The GUID of the Kafka server to be surveyed.
2684
+
2685
+
2686
+ Returns
2687
+ -------
2688
+ str
2689
+ The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2690
+
2691
+ """
2692
+ loop = asyncio.get_event_loop()
2693
+ response = loop.run_until_complete(
2694
+ self._async_initiate_survey(
2695
+ "ApacheKafkaSurveys:survey-kafka-server", kafka_server_guid
2696
+ )
2697
+ )
2698
+ return response
2699
+
2700
+ def initiate_uc_server_survey(self, uc_server_guid: str) -> str:
2701
+ """Initiate survey of a Unity Catalog server. Async Version.
2702
+ Parameters
2703
+ ----------
2704
+ uc_server_guid : str
2705
+ The GUID of the Kafka server to be surveyed.
2706
+
2707
+
2708
+ Returns
2709
+ -------
2710
+ str
2711
+ The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2712
+
2713
+ """
2714
+ loop = asyncio.get_event_loop()
2715
+ response = loop.run_until_complete(
2716
+ self._async_initiate_survey(
2717
+ "UnityCatalogSurveys:survey-unity-catalog-server", uc_server_guid
2718
+ )
2719
+ )
2720
+ return response
2721
+
2722
+ def initiate_uc_schema_survey(self, uc_schema_guid: str) -> str:
2723
+ """Initiate survey of a Unity Catalog schema. Async Version.
2724
+ Parameters
2725
+ ----------
2726
+ uc_schema_guid : str
2727
+ The GUID of the Kafka server to be surveyed.
2728
+
2729
+
2730
+
2731
+ Returns
2732
+ -------
2733
+ str
2734
+ The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2735
+
2736
+ """
2737
+ loop = asyncio.get_event_loop()
2738
+ response = loop.run_until_complete(
2739
+ self._async_initiate_survey(
2740
+ "UnityCatalogSurveys:survey-unity-catalog-schema", uc_schema_guid
2741
+ )
2742
+ )
2743
+ return response
2744
+
2745
+ # async def _async_initiate_uc_function_survey(self, uc_server_guid: str) -> str:
2746
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2747
+ # Parameters
2748
+ # ----------
2749
+ # Unity Catalog_server_guid : str
2750
+ # The GUID of the Kafka server to be surveyed.
2751
+ #
2752
+ # server : str, optional
2753
+ # The name of the server. If not provided, the default server name is used.
2754
+ #
2755
+ # Returns
2756
+ # -------
2757
+ # str
2758
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2759
+ #
2760
+ # """
2761
+ # server = self.view_server if server is None else server
2762
+ # url = (f"{self.curation_command_root}/governance-action-types/"
2763
+ # f"initiate")
2764
+ #
2765
+ # body = {"class": "InitiateGovernanceActionTypeRequestBody",
2766
+ # "governanceActionTypeQualifiedName": "AssetSurvey:survey-unity-catalog-server", "actionTargets": [
2767
+ # {"class": "NewActionTarget", "actionTargetName": "serverToSurvey", "actionTargetGUID": uc_server_guid}]}
2768
+ # response = await self._async_make_request("POST", url, body)
2769
+ # return response.json().get("guid", "Action not initiated")
2770
+ #
2771
+ # def initiate_uc_function_survey(self, uc_server_guid: str) -> str:
2772
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2773
+ # Parameters
2774
+ # ----------
2775
+ # Unity Catalog_server_guid : str
2776
+ # The GUID of the Kafka server to be surveyed.
2777
+ #
2778
+ # server : str, optional
2779
+ # The name of the server. If not provided, the default server name is used.
2780
+ #
2781
+ # Returns
2782
+ # -------
2783
+ # str
2784
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2785
+ #
2786
+ # """
2787
+ # loop = asyncio.get_event_loop()
2788
+ # response = loop.run_until_complete(self._async_initiate_uc_server_survey(uc_server_guid))
2789
+ # return response
2790
+ #
2791
+ # async def _async_initiate_uc_server_survey(self, uc_server_guid: str) -> str:
2792
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2793
+ # Parameters
2794
+ # ----------
2795
+ # Unity Catalog_server_guid : str
2796
+ # The GUID of the Kafka server to be surveyed.
2797
+ #
2798
+ # server : str, optional
2799
+ # The name of the server. If not provided, the default server name is used.
2800
+ #
2801
+ # Returns
2802
+ # -------
2803
+ # str
2804
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2805
+ #
2806
+ # """
2807
+ # server = self.view_server if server is None else server
2808
+ # url = (f"{self.curation_command_root}/governance-action-types/"
2809
+ # f"initiate")
2810
+ #
2811
+ # body = {"class": "InitiateGovernanceActionTypeRequestBody",
2812
+ # "governanceActionTypeQualifiedName": "AssetSurvey:survey-unity-catalog-server", "actionTargets": [
2813
+ # {"class": "NewActionTarget", "actionTargetName": "serverToSurvey", "actionTargetGUID": uc_server_guid}]}
2814
+ # response = await self._async_make_request("POST", url, body)
2815
+ # return response.json().get("guid", "Action not initiated")
2816
+ #
2817
+ # def initiate_uc_server_survey(self, uc_server_guid: str) -> str:
2818
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2819
+ # Parameters
2820
+ # ----------
2821
+ # Unity Catalog_server_guid : str
2822
+ # The GUID of the Kafka server to be surveyed.
2823
+ #
2824
+ # server : str, optional
2825
+ # The name of the server. If not provided, the default server name is used.
2826
+ #
2827
+ # Returns
2828
+ # -------
2829
+ # str
2830
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2831
+ #
2832
+ # """
2833
+ # loop = asyncio.get_event_loop()
2834
+ # response = loop.run_until_complete(self._async_initiate_uc_server_survey(uc_server_guid))
2835
+ # return response
2836
+ #
2837
+ # async def _async_initiate_uc_server_survey(self, uc_server_guid: str) -> str:
2838
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2839
+ # Parameters
2840
+ # ----------
2841
+ # Unity Catalog_server_guid : str
2842
+ # The GUID of the Kafka server to be surveyed.
2843
+ #
2844
+ # server : str, optional
2845
+ # The name of the server. If not provided, the default server name is used.
2846
+ #
2847
+ # Returns
2848
+ # -------
2849
+ # str
2850
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2851
+ #
2852
+ # """
2853
+ # server = self.view_server if server is None else server
2854
+ # url = (f"{self.curation_command_root}/governance-action-types/"
2855
+ # f"initiate")
2856
+ #
2857
+ # body = {"class": "InitiateGovernanceActionTypeRequestBody",
2858
+ # "governanceActionTypeQualifiedName": "AssetSurvey:survey-unity-catalog-server", "actionTargets": [
2859
+ # {"class": "NewActionTarget", "actionTargetName": "serverToSurvey", "actionTargetGUID": uc_server_guid}]}
2860
+ # response = await self._async_make_request("POST", url, body)
2861
+ # return response.json().get("guid", "Action not initiated")
2862
+ #
2863
+ # def initiate_uc_server_survey(self, uc_server_guid: str) -> str:
2864
+ # """ Initiate survey of a Unity Catalog server. Async Version.
2865
+ # Parameters
2866
+ # ----------
2867
+ # Unity Catalog_server_guid : str
2868
+ # The GUID of the Kafka server to be surveyed.
2869
+ #
2870
+ # server : str, optional
2871
+ # The name of the server. If not provided, the default server name is used.
2872
+ #
2873
+ # Returns
2874
+ # -------
2875
+ # str
2876
+ # The GUID of the initiated action or "Action not initiated" if the action was not initiated.
2877
+ #
2878
+ # """
2879
+ # loop = asyncio.get_event_loop()
2880
+ # response = loop.run_until_complete(self._async_initiate_uc_server_survey(uc_server_guid))
2881
+ # return response
2882
+
2883
+ #
2884
+ # Initiate general engine action
2885
+ #
2886
+
2887
+ async def _async_initiate_engine_action(
2888
+ self,
2889
+ qualified_name: str,
2890
+ domain_identifier: int,
2891
+ display_name: str,
2892
+ description: str,
2893
+ request_source_guids: str,
2894
+ action_targets: str,
2895
+ received_guards: [str],
2896
+ start_time: datetime,
2897
+ request_type: str,
2898
+ request_parameters: dict,
2899
+ process_name: str,
2900
+ request_src_name: Optional[str] = None,
2901
+ originator_svc_name: Optional[str] = None,
2902
+ originator_eng_name: Optional[str] = None,
2903
+ ) -> str:
2904
+ """Create an engine action in the metadata store that will trigger the governance service associated with
2905
+ the supplied request type. The engine action remains to act as a record of the actions taken for auditing.
2906
+ Async version.
2907
+
2908
+ Parameters
2909
+ ----------
2910
+ qualified_name (str): The qualified name of the governance action.
2911
+ domain_identifier (int): The domain identifier for the governance action.
2912
+ display_name (str): The display name of the governance action.
2913
+ description (str): The description of the governance action.
2914
+ request_source_guids (str): GUIDs of the sources initiating the request.
2915
+ action_targets (str): Targets of the governance action.
2916
+ received_guards (List[str]): List of guards received for the action.
2917
+ start_time (datetime): The start time for the governance action.
2918
+ request_type (str): The type of the governance action request.
2919
+ request_parameters (dict): Additional parameters for the governance action.
2920
+ process_name (str): The name of the associated governance action process.
2921
+ request_src_name (str, optional): The name of the request source. Defaults to None.
2922
+ originator_svc_name (str, optional): The name of the originator service. Defaults to None.
2923
+ originator_eng_name (str, optional): The name of the originator engine. Defaults to None.
2924
+
2925
+ Returns
2926
+ -------
2927
+ str: The GUID (Globally Unique Identifier) of the initiated governance action.
2928
+
2929
+ Raises
2930
+ ------
2931
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
2932
+ this exception is raised with details from the response content.
2933
+
2934
+ Note
2935
+ ----
2936
+ The `start_time` parameter should be a `datetime` object representing the start time of the
2937
+ governance action.
2938
+
2939
+
2940
+ """
2941
+
2942
+ url = (
2943
+ f"{self.curation_command_root}/governance-engines/"
2944
+ f"engine-actions/initiate"
2945
+ )
2946
+ body = {
2947
+ "class": "GovernanceActionRequestBody",
2948
+ "qualifiedName": qualified_name + str(int(start_time.timestamp())),
2949
+ "domainIdentifier": domain_identifier,
2950
+ "displayName": display_name,
2951
+ "description": description,
2952
+ "requestSourceGUIDs": request_source_guids,
2953
+ "actionTargets": action_targets,
2954
+ "receivedGuards": received_guards,
2955
+ "startTime": int(start_time.timestamp() * 1000),
2956
+ "requestType": request_type,
2957
+ "requestParameters": request_parameters,
2958
+ "processName": process_name,
2959
+ "requestSourceName": request_src_name,
2960
+ "originatorServiceName": originator_svc_name,
2961
+ "originatorEngineName": originator_eng_name,
2962
+ }
2963
+ new_body = body_slimmer(body)
2964
+ response = await self._async_make_request("POST", url, new_body)
2965
+ return response.json().get("guid", "Action not initiated")
2966
+
2967
+ def initiate_engine_action(
2968
+ self,
2969
+ qualified_name: str,
2970
+ domain_identifier: int,
2971
+ display_name: str,
2972
+ description: str,
2973
+ request_source_guids: str,
2974
+ action_targets: str,
2975
+ received_guards: [str],
2976
+ start_time: datetime,
2977
+ request_type: str,
2978
+ request_parameters: dict,
2979
+ process_name: str,
2980
+ request_src_name: Optional[str] = None,
2981
+ originator_svc_name: Optional[str] = None,
2982
+ originator_eng_name: Optional[str] = None,
2983
+ ) -> str:
2984
+ """Create an engine action in the metadata store that will trigger the governance service associated with
2985
+ the supplied request type. The engine action remains to act as a record of the actions taken for auditing.
2986
+
2987
+ Parameters
2988
+ ----------
2989
+ qualified_name (str): The qualified name of the governance action.
2990
+ domain_identifier (int): The domain identifier for the governance action.
2991
+ display_name (str): The display name of the governance action.
2992
+ description (str): The description of the governance action.
2993
+ request_source_guids (str): GUIDs of the sources initiating the request.
2994
+ action_targets (str): Targets of the governance action.
2995
+ received_guards (List[str]): List of guards received for the action.
2996
+ start_time (datetime): The start time for the governance action.
2997
+ gov_engine_name (str): The name of the governance engine associated with the action.
2998
+ request_type (str): The type of the governance action request.
2999
+ request_parameters (dict): Additional parameters for the governance action.
3000
+ process_name (str): The name of the associated governance action process.
3001
+ request_src_name (str, optional): The name of the request source. Defaults to None.
3002
+ originator_svc_name (str, optional): The name of the originator service. Defaults to None.
3003
+ originator_eng_name (str, optional): The name of the originator engine. Defaults to None.
3004
+
3005
+ Returns
3006
+ -------
3007
+ str: The GUID (Globally Unique Identifier) of the initiated governance action.
3008
+
3009
+ Raises
3010
+ ------
3011
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3012
+ this exception is raised with details from the response content.
3013
+
3014
+ Note
3015
+ ----
3016
+ The `start_time` parameter should be a `datetime` object representing the start time of the
3017
+ governance action.
3018
+ """
3019
+ loop = asyncio.get_event_loop()
3020
+ response = loop.run_until_complete(
3021
+ self._async_initiate_engine_action(
3022
+ qualified_name,
3023
+ domain_identifier,
3024
+ display_name,
3025
+ description,
3026
+ request_source_guids,
3027
+ action_targets,
3028
+ received_guards,
3029
+ start_time,
3030
+ request_type,
3031
+ request_parameters,
3032
+ process_name,
3033
+ request_src_name,
3034
+ originator_svc_name,
3035
+ originator_eng_name,
3036
+ )
3037
+ )
3038
+ return response
3039
+
3040
+ async def _async_get_catalog_targets(
3041
+ self,
3042
+ integ_connector_guid: str,
3043
+ start_from: int = 0,
3044
+ page_size: int = 0,
3045
+ output_format: str = "JSON",
3046
+ report_spec: str | dict = "CatalogTarget",
3047
+ ) -> list | str:
3048
+ """Retrieve the details of the metadata elements identified as catalog targets with an integration connector.
3049
+ Async version.
3050
+
3051
+ Parameters:
3052
+ ----------
3053
+ integ_connector_guid: str
3054
+ The GUID (Globally Unique Identifier) of the integration connector used to retrieve catalog targets.
3055
+ Returns:
3056
+ -------
3057
+ [dict]: The list of catalog targets JSON objects.
3058
+
3059
+ Raises:
3060
+ ------
3061
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3062
+ this exception is raised with details from the response content.
3063
+ PyegeriaAPIException: If the API response indicates a server side error.
3064
+ PyegeriaUnauthorizedException:
3065
+ """
3066
+
3067
+ validate_guid(integ_connector_guid)
3068
+
3069
+ url = f"{self.curation_command_root}/integration-connectors/{integ_connector_guid}/catalog-targets"
3070
+
3071
+
3072
+ response = await self._async_make_request("GET", url)
3073
+ elements = response.json().get("elements", "no targets")
3074
+ if isinstance(elements, str):
3075
+ logger.info("No catalog targets found for this integration connector.")
3076
+ return elements
3077
+ if output_format != "JSON":
3078
+ logger.info(f"Found targets, output_format: {output_format}, and report_spec: {report_spec}")
3079
+ return self._generate_catalog_target_output(elements, None, self.CATALOG_TARGET_LABEL,
3080
+ output_format=output_format,report_spec=report_spec)
3081
+ return elements
3082
+
3083
+ def get_catalog_targets(
3084
+ self,
3085
+ integ_connector_guid: str,
3086
+ start_from: int = 0,
3087
+ page_size: int = 0,
3088
+ output_format: str = "JSON",
3089
+ report_spec: str | dict = "CatalogTarget",
3090
+ ) -> list | str:
3091
+ """Retrieve the details of the metadata elements identified as catalog targets with an integration connector.
3092
+
3093
+ Parameters:
3094
+ ----------
3095
+ integ_connector_guid: str
3096
+ The GUID (Globally Unique Identifier) of the integration connector used to retrieve catalog targets.
3097
+ Returns:
3098
+ -------
3099
+ [dict]: The list of catalog targets JSON objects.
3100
+
3101
+ Raises:
3102
+ ------
3103
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3104
+ this exception is raised with details from the response content.
3105
+ PyegeriaAPIException: If the API response indicates a server side error.
3106
+ PyegeriaUnauthorizedException:
3107
+ """
3108
+
3109
+ loop = asyncio.get_event_loop()
3110
+ response = loop.run_until_complete(
3111
+ self._async_get_catalog_targets(integ_connector_guid, start_from, page_size,
3112
+ output_format=output_format,
3113
+ report_spec=report_spec)
3114
+ )
3115
+ return response
3116
+
3117
+ async def _async_get_catalog_target(self, relationship_guid: str,
3118
+ output_format: str = "JSON",
3119
+ report_spec: str | dict = "CatalogTarget",
3120
+ body: Optional[dict | GetRequestBody] = None) -> dict | str:
3121
+ """Retrieve a specific catalog target associated with an integration connector. Further Information:
3122
+ https://egeria-project.org/concepts/integration-connector/ . Async version.
3123
+
3124
+ Parameters:
3125
+ ----------
3126
+ relationship_guid: str
3127
+ The GUID (Globally Unique Identifier) identifying the catalog targets for an integration connector.
3128
+
3129
+ Returns:
3130
+ -------
3131
+ dict: JSON structure of the catalog target.
3132
+
3133
+ Raises:
3134
+ ------
3135
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3136
+ this exception is raised with details from the response content.
3137
+ PyegeriaAPIException: If the API response indicates a server side error.
3138
+ PyegeriaUnauthorizedException:
3139
+ """
3140
+
3141
+ validate_guid(relationship_guid)
3142
+
3143
+ url = str(HttpUrl(f"{self.curation_command_root}/catalog-targets/{relationship_guid}"))
3144
+ response = await self._async_get_guid_request(
3145
+ url,
3146
+ _type=self.CATALOG_TARGET_LABEL,
3147
+ _gen_output=self._generate_catalog_target_output,
3148
+ output_format=output_format,
3149
+ report_spec=report_spec,
3150
+ body=body,
3151
+ )
3152
+ return response
3153
+
3154
+ def get_catalog_target(self, relationship_guid: str,
3155
+ output_format: str = "JSON",
3156
+ report_spec: str | dict = "CatalogTarget",
3157
+ body: Optional[dict | GetRequestBody] = None) -> dict | str:
3158
+ """Retrieve a specific catalog target associated with an integration connector. Further Information:
3159
+ https://egeria-project.org/concepts/integration-connector/ .
3160
+
3161
+ Parameters:
3162
+ ----------
3163
+ relationship_guid: str
3164
+ The GUID (Globally Unique Identifier) identifying the catalog targets for an integration connector.
3165
+
3166
+ Returns:
3167
+ -------
3168
+ dict: JSON structure of the catalog target.
3169
+
3170
+ Raises:
3171
+ ------
3172
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3173
+ this exception is raised with details from the response content.
3174
+ PyegeriaAPIException: If the API response indicates a server side error.
3175
+ PyegeriaUnauthorizedException:
3176
+ """
3177
+
3178
+ loop = asyncio.get_event_loop()
3179
+ response = loop.run_until_complete(
3180
+ self._async_get_catalog_target(relationship_guid,
3181
+ output_format=output_format,
3182
+ report_spec=report_spec,
3183
+ body=body)
3184
+ )
3185
+ return response
3186
+
3187
+ async def _async_add_catalog_target(
3188
+ self,
3189
+ integ_connector_guid: str,
3190
+ metadata_element_guid: str,
3191
+ catalog_target_name: str,
3192
+ connection_name: Optional[str] = None,
3193
+ metadata_src_qual_name: Optional[str] = None,
3194
+ config_properties: dict = None,
3195
+ template_properties: dict = None,
3196
+ permitted_sync: str = "BOTH_DIRECTIONS",
3197
+ delete_method: str = "ARCHIVE",
3198
+ ) -> str:
3199
+ """Add a catalog target to an integration connector and .
3200
+ Async version.
3201
+
3202
+ Parameters:
3203
+ ----------
3204
+ integ_connector_guid: str
3205
+ The GUID (Globally Unique Identifier) of the integration connector used to retrieve catalog targets.
3206
+ metadata_element_guid: str
3207
+ The specific metadata element target we want to retrieve.
3208
+ catalog_target_name : dict
3209
+ Name of the catalog target to add.
3210
+ connection_name: str, default = None
3211
+ Optional name of connection to use for this catalog target when multiple connections defined.
3212
+ metadata_src_qual_name: str
3213
+ The qualified name of the metadata source for the catalog target
3214
+ config_properties: dict
3215
+ Configuration properties for the catalog target
3216
+ template_properties: dict
3217
+ Template properties to pass
3218
+ permitted_sync: str, default = BOTH_DIRECTIONS
3219
+ Direction the metadata is allowed to flow (BOTH_DIRECTIONS, FROM_THIRD_PARTH, TO_THIRD_PARTY
3220
+ delete_method: str, default = ARCHIVE
3221
+ Controls the type of delete. Use ARCHIVE for lineage considerations. Alternative is SOFT_DELETE.
3222
+ Returns:
3223
+ -------
3224
+ Relationship GUID for the catalog target,
3225
+
3226
+ Raises:
3227
+ ------
3228
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3229
+ this exception is raised with details from the response content.
3230
+ PyegeriaAPIException: If the API response indicates a server side error.
3231
+ PyegeriaUnauthorizedException:
3232
+ """
3233
+
3234
+ validate_guid(integ_connector_guid)
3235
+ validate_guid(metadata_element_guid)
3236
+
3237
+ url = (
3238
+ f"{self.curation_command_root}/integration-connectors/"
3239
+ f"{integ_connector_guid}/catalog-targets/{metadata_element_guid}"
3240
+ )
3241
+ body = {
3242
+ "catalogTargetName": catalog_target_name,
3243
+ "metadataSourceQualifiedName": metadata_src_qual_name,
3244
+ "configProperties": config_properties,
3245
+ "templateProperties": template_properties,
3246
+ "connectionName": connection_name,
3247
+ "permittedSynchronization": permitted_sync,
3248
+ "deleteMethod": delete_method,
3249
+ }
3250
+
3251
+ response = await self._async_make_request("POST", url, body)
3252
+ return response.json().get("guid", "No Guid returned")
3253
+
3254
+ def add_catalog_target(
3255
+ self,
3256
+ integ_connector_guid: str,
3257
+ metadata_element_guid: str,
3258
+ catalog_target_name: str,
3259
+ connection_name: Optional[str] = None,
3260
+ metadata_src_qual_name: Optional[str] = None,
3261
+ config_properties: dict = None,
3262
+ template_properties: dict = None,
3263
+ permitted_sync: str = "BOTH_DIRECTIONS",
3264
+ delete_method: str = "ARCHIVE",
3265
+ ) -> str:
3266
+ """Add a catalog target to an integration connector and .
3267
+
3268
+ Parameters:
3269
+ ----------
3270
+ integ_connector_guid: str
3271
+ The GUID (Globally Unique Identifier) of the integration connector used to retrieve catalog targets.
3272
+ metadata_element_guid: str
3273
+ The specific metadata element target we want to retrieve.
3274
+ catalog_target_name : dict
3275
+ Name of the catalog target to add.
3276
+ connection_name: str, default = None
3277
+ Optional name of connection to use for this catalog target when multiple connections defined.
3278
+ metadata_src_qual_name: str
3279
+ The qualified name of the metadata source for the catalog target
3280
+ config_properties: dict
3281
+ Configuration properties for the catalog target
3282
+ template_properties: dict
3283
+ Template properties to pass
3284
+ permitted_sync: str, default = BOTH_DIRECTIONS
3285
+ Direction the metadata is allowed to flow (BOTH_DIRECTIONS, FROM_THIRD_PARTH, TO_THIRD_PARTY
3286
+ delete_method: str, default = ARCHIVE
3287
+ Controls the type of delete. Use ARCHIVE for lineage considerations. Alternative is SOFT_DELETE.
3288
+ Returns:
3289
+ -------
3290
+ Relationship GUID for the catalog target,
3291
+
3292
+ Raises:
3293
+ ------
3294
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3295
+ this exception is raised with details from the response content.
3296
+ PyegeriaAPIException: If the API response indicates a server side error.
3297
+ PyegeriaUnauthorizedException:
3298
+ """
3299
+ loop = asyncio.get_event_loop()
3300
+ response = loop.run_until_complete(
3301
+ self._async_add_catalog_target(
3302
+ integ_connector_guid,
3303
+ metadata_element_guid,
3304
+ catalog_target_name,
3305
+ connection_name,
3306
+ metadata_src_qual_name,
3307
+ config_properties,
3308
+ template_properties,
3309
+ permitted_sync,
3310
+ delete_method,
3311
+ )
3312
+ )
3313
+ return response
3314
+
3315
+ async def _async_update_catalog_target(
3316
+ self,
3317
+ relationship_guid: str,
3318
+ catalog_target_name: str,
3319
+ connection_name: Optional[str] = None,
3320
+ metadata_src_qual_name: Optional[str] = None,
3321
+ config_properties: dict = None,
3322
+ template_properties: dict = None,
3323
+ permitted_sync: str = "BOTH_DIRECTIONS",
3324
+ delete_method: str = "ARCHIVE",
3325
+ ) -> None:
3326
+ """Update a catalog target to an integration connector.
3327
+ Async version.
3328
+
3329
+ Parameters:
3330
+ ----------
3331
+ relationship_guid: str
3332
+ The GUID (Globally Unique Identifier) of the relationship used to retrieve catalog targets.
3333
+ catalog_target_name : dict
3334
+ Name of the catalog target to add.
3335
+ connection_name: str, default = None
3336
+ Optional name of connection to use for this catalog target when multiple connections defined.
3337
+ metadata_src_qual_name: str
3338
+ The qualified name of the metadata source for the catalog target
3339
+ config_properties: dict
3340
+ Configuration properties for the catalog target
3341
+ template_properties: dict
3342
+ Template properties to pass
3343
+ permitted_sync: str, default = BOTH_DIRECTIONS
3344
+ Direction the metadata is allowed to flow (BOTH_DIRECTIONS, FROM_THIRD_PARTH, TO_THIRD_PARTY
3345
+ delete_method: str, default = ARCHIVE
3346
+ Controls the type of delete. Use ARCHIVE for lineage considerations. Alternative is SOFT_DELETE.
3347
+ Returns:
3348
+ -------
3349
+ None
3350
+
3351
+ Raises:
3352
+ ------
3353
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3354
+ this exception is raised with details from the response content.
3355
+ PyegeriaAPIException: If the API response indicates a server side error.
3356
+ PyegeriaUnauthorizedException:
3357
+ """
3358
+
3359
+ validate_guid(relationship_guid)
3360
+
3361
+ url = (
3362
+ f"{self.curation_command_root}/catalog-targets/"
3363
+ f"{relationship_guid}/update"
3364
+ )
3365
+ body = {
3366
+ "catalogTargetName": catalog_target_name,
3367
+ "metadataSourceQualifiedName": metadata_src_qual_name,
3368
+ "configProperties": config_properties,
3369
+ "templateProperties": template_properties,
3370
+ "connectionName": connection_name,
3371
+ "permittedSynchronization": permitted_sync,
3372
+ "deleteMethod": delete_method,
3373
+ }
3374
+ await self._async_make_request("POST", url, body)
3375
+ return
3376
+
3377
+ def update_catalog_target(
3378
+ self,
3379
+ relationship_guid: str,
3380
+ catalog_target_name: str,
3381
+ connection_name: Optional[str] = None,
3382
+ metadata_src_qual_name: Optional[str] = None,
3383
+ config_properties: dict = None,
3384
+ template_properties: dict = None,
3385
+ permitted_sync: str = "BOTH_DIRECTIONS",
3386
+ delete_method: str = "ARCHIVE",
3387
+ ) -> None:
3388
+ """Update a catalog target to an integration connector.
3389
+
3390
+ Parameters:
3391
+ ----------
3392
+ relationship_guid: str
3393
+ The GUID (Globally Unique Identifier) of the relationship used to retrieve catalog targets.
3394
+ catalog_target_name : dict
3395
+ Name of the catalog target to add.
3396
+ connection_name: str, default = None
3397
+ Optional name of connection to use for this catalog target when multiple connections defined.
3398
+ metadata_src_qual_name: str
3399
+ The qualified name of the metadata source for the catalog target
3400
+ config_properties: dict
3401
+ Configuration properties for the catalog target
3402
+ template_properties: dict
3403
+ Template properties to pass
3404
+ permitted_sync: str, default = BOTH_DIRECTIONS
3405
+ Direction the metadata is allowed to flow (BOTH_DIRECTIONS, FROM_THIRD_PARTH, TO_THIRD_PARTY
3406
+ delete_method: str, default = ARCHIVE
3407
+ Controls the type of delete. Use ARCHIVE for lineage considerations. Alternative is SOFT_DELETE.
3408
+ server: str, optional
3409
+ """
3410
+
3411
+ loop = asyncio.get_event_loop()
3412
+ loop.run_until_complete(
3413
+ self._async_update_catalog_target(
3414
+ relationship_guid,
3415
+ catalog_target_name,
3416
+ connection_name,
3417
+ metadata_src_qual_name,
3418
+ config_properties,
3419
+ template_properties,
3420
+ permitted_sync,
3421
+ delete_method,
3422
+ )
3423
+ )
3424
+ return
3425
+
3426
+ async def _async_remove_catalog_target(self, relationship_guid: str) -> None:
3427
+ """Remove a catalog target to an integration connector. Async version.
3428
+
3429
+ Parameters:
3430
+ ----------
3431
+ relationship_guid: str
3432
+ The GUID (Globally Unique Identifier) identifying the catalog target relationship.
3433
+
3434
+ Returns:
3435
+ -------
3436
+ None
3437
+
3438
+ Raises:
3439
+ ------
3440
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3441
+ this exception is raised with details from the response content.
3442
+ PyegeriaAPIException: If the API response indicates a server side error.
3443
+ PyegeriaUnauthorizedException:
3444
+ """
3445
+
3446
+ validate_guid(relationship_guid)
3447
+
3448
+ url = (
3449
+ f"{self.curation_command_root}/catalog-targets/"
3450
+ f"{relationship_guid}/remove"
3451
+ )
3452
+
3453
+ await self._async_make_request("POST", url)
3454
+ return
3455
+
3456
+ def remove_catalog_target(self, relationship_guid: str) -> None:
3457
+ """Remove a catalog target to an integration connector.
3458
+
3459
+ Parameters:
3460
+ ----------
3461
+ relationship_guid: str
3462
+ The GUID (Globally Unique Identifier) identifying the catalog target relationship.
3463
+
3464
+ Returns:
3465
+ -------
3466
+ None
3467
+
3468
+ Raises:
3469
+ ------
3470
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3471
+ this exception is raised with details from the response content.
3472
+ PyegeriaAPIException: If the API response indicates a server side error.
3473
+ PyegeriaUnauthorizedException:
3474
+ """
3475
+
3476
+ loop = asyncio.get_event_loop()
3477
+ loop.run_until_complete(self._async_remove_catalog_target(relationship_guid))
3478
+ return
3479
+
3480
+ #
3481
+ # Get information about technologies
3482
+ #
3483
+
3484
+ async def _async_get_tech_types_for_open_metadata_type(
3485
+ self,
3486
+ type_name: str,
3487
+ tech_name: str,
3488
+ start_from: int = 0,
3489
+ page_size: int = 0,
3490
+ ) -> list | str:
3491
+ """Retrieve the list of deployed implementation type metadata elements linked to a particular
3492
+ open metadata type.. Async version.
3493
+
3494
+ Parameters:
3495
+ ----------
3496
+ type_name: str
3497
+ The technology type we are looking for.
3498
+ tech_name: str
3499
+ The technology name we are looking for.
3500
+
3501
+ Returns:
3502
+ -------
3503
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
3504
+
3505
+ Raises:
3506
+ ------
3507
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3508
+ this exception is raised with details from the response content.
3509
+ PyegeriaAPIException: If the API response indicates a server side error.
3510
+ PyegeriaUnauthorizedException:
3511
+
3512
+ Notes
3513
+ -----
3514
+ More information can be found at: https://egeria-project.org/types
3515
+ """
3516
+
3517
+ # validate_name(type_name)
3518
+ url = (
3519
+ f"{self.curation_command_root}/open-metadata-types/"
3520
+ f"{type_name}/technology-types"
3521
+ )
3522
+ body = {"filter": tech_name}
3523
+
3524
+ response = await self._async_make_request("POST", url, body)
3525
+ return response.json().get("elements", "no tech found")
3526
+
3527
+ def get_tech_types_for_open_metadata_type(
3528
+ self,
3529
+ type_name: str,
3530
+ tech_name: str,
3531
+ start_from: int = 0,
3532
+ page_size: int = 0,
3533
+ ) -> list | str:
3534
+ """Retrieve the list of deployed implementation type metadata elements linked to a particular
3535
+ open metadata type.
3536
+
3537
+ Parameters:
3538
+ ----------
3539
+ type_name: str
3540
+ The technology type we are looking for.
3541
+ tech_name: str
3542
+ The technology name we are looking for.
3543
+
3544
+ Returns:
3545
+ -------
3546
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
3547
+
3548
+ Raises:
3549
+ ------
3550
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3551
+ this exception is raised with details from the response content.
3552
+ PyegeriaAPIException: If the API response indicates a server side error.
3553
+ PyegeriaUnauthorizedException:
3554
+
3555
+ Notes
3556
+ -----
3557
+ More information can be found at: https://egeria-project.org/types
3558
+ """
3559
+ loop = asyncio.get_event_loop()
3560
+ response = loop.run_until_complete(
3561
+ self._async_get_tech_types_for_open_metadata_type(
3562
+ type_name, tech_name, start_from, page_size
3563
+ )
3564
+ )
3565
+ return response
3566
+
3567
+ async def _async_get_tech_type_detail(self, filter_string: Optional[str] = None, body: Optional[dict | FilterRequestBody] = None,
3568
+ output_format: str = "JSON", report_spec: str | dict = "TechType",
3569
+ **kwargs) -> list | str:
3570
+ """Retrieve the details of the named technology type. This name should be the name of the technology type
3571
+ and contain no wild cards. Async version.
3572
+ Parameters
3573
+ ----------
3574
+ filter_string : str
3575
+ The name of the technology type to retrieve detailed information for.
3576
+ body: dict | FilterRequestBody
3577
+ If provided, the information in the body supersedes the other parameters and allows more advanced requests.
3578
+
3579
+ Returns
3580
+ -------
3581
+ list[dict] | str
3582
+ A list of dictionaries containing the detailed information for the specified technology type.
3583
+ If the technology type is not found, returns the string "no type found".
3584
+ Raises
3585
+ ------
3586
+ PyegeriaException
3587
+ ValidationError
3588
+
3589
+ Notes
3590
+ -----
3591
+ More information can be found at: https://egeria-project.org/concepts/deployed-implementation-type
3592
+ Sample body:
3593
+ {
3594
+ "class" : "FilterRequestBody",
3595
+ "filter" : "Root Technology Type",
3596
+ "startFrom": 0,
3597
+ "pageSize": 10,
3598
+ "asOfTime" : "{{$isoTimestamp}}",
3599
+ "effectiveTime" : "{{$isoTimestamp}}",
3600
+ "includeOnlyClassifiedElements" : ["Template"]
3601
+ "forLineage" : false,
3602
+ "forDuplicateProcessing" : false,
3603
+ "limitResultsByStatus" : ["ACTIVE"],
3604
+ "sequencingOrder" : "PROPERTY_ASCENDING",
3605
+ "sequencingProperty" : "qualifiedName"
3606
+ }
3607
+ """
3608
+
3609
+ # validate_name(type_name)
3610
+ url = str(HttpUrl(f"{self.curation_command_root}/technology-types/by-name"))
3611
+ if body is None:
3612
+ body = {
3613
+ "class": "FilterRequestBody",
3614
+ "filter": filter_string
3615
+ }
3616
+
3617
+ response = await self._async_make_request("POST", url, body)
3618
+ element = response.json().get("element", NO_ELEMENTS_FOUND)
3619
+ if type(element) is str:
3620
+ logger.info(NO_ELEMENTS_FOUND)
3621
+ return NO_ELEMENTS_FOUND
3622
+
3623
+ if output_format != 'JSON': # return a simplified markdown representation
3624
+ logger.info(f"Found elements, output format: {output_format} and report_spec: {report_spec}")
3625
+ return self._generate_tech_type_output(element, filter_string, "ValidMetadataValue",
3626
+ output_format, report_spec)
3627
+ return element
3628
+
3629
+ def get_tech_type_detail(self, filter_string: Optional[str] = None, body: Optional[dict | FilterRequestBody] = None,
3630
+ output_format: str = "JSON", report_spec: str | dict = "TechType", **kwargs) -> list | str:
3631
+ """Retrieve the details of the named technology type. This name should be the name of the technology type
3632
+ and contain no wild cards.
3633
+ Parameters
3634
+ ----------
3635
+ filter_string : str
3636
+ The name of the technology type to retrieve detailed information for.
3637
+ body: dict | FilterRequestBody
3638
+ If provided, the information in the body supersedes the other parameters and allows more advanced requests.
3639
+
3640
+ Returns
3641
+ -------
3642
+ list[dict] | str
3643
+ A list of dictionaries containing the detailed information for the specified technology type.
3644
+ If the technology type is not found, returns the string "no type found".
3645
+ Raises
3646
+ ------
3647
+ PyegeriaException
3648
+ ValidationError
3649
+
3650
+ Notes
3651
+ -----
3652
+ More information can be found at: https://egeria-project.org/concepts/deployed-implementation-type
3653
+ Sample body:
3654
+ {
3655
+ "class" : "FilterRequestBody",
3656
+ "filter" : "Root Technology Type",
3657
+ "startFrom": 0,
3658
+ "pageSize": 10,
3659
+ "asOfTime" : "{{$isoTimestamp}}",
3660
+ "effectiveTime" : "{{$isoTimestamp}}",
3661
+ "includeOnlyClassifiedElements" : ["Template"]
3662
+ "forLineage" : false,
3663
+ "forDuplicateProcessing" : false,
3664
+ "limitResultsByStatus" : ["ACTIVE"],
3665
+ "sequencingOrder" : "PROPERTY_ASCENDING",
3666
+ "sequencingProperty" : "qualifiedName"
3667
+ }
3668
+ """
3669
+
3670
+ loop = asyncio.get_event_loop()
3671
+ response = loop.run_until_complete(
3672
+ self._async_get_tech_type_detail(filter_string, body=body, output_format=output_format, report_spec=report_spec)
3673
+ )
3674
+ return response
3675
+
3676
+
3677
+ async def _async_get_tech_type_hierarchy(self, filter_string: Optional[str] = None, body: Optional[dict | FilterRequestBody] = None,
3678
+ output_format: str = "JSON", report_spec: str | dict = "TechType",
3679
+ **kwargs) -> list | str:
3680
+ """Retrieve the details of the named technology type. This name should be the name of the technology type
3681
+ and contain no wild cards. Async version.
3682
+ Parameters
3683
+ ----------
3684
+ filter_string : str
3685
+ The name of the technology type to retrieve detailed information for.
3686
+ body: dict | FilterRequestBody
3687
+ If provided, the information in the body supersedes the other parameters and allows more advanced requests.
3688
+
3689
+ Returns
3690
+ -------
3691
+ list[dict] | str
3692
+ A list of dictionaries containing the detailed information for the specified technology type.
3693
+ If the technology type is not found, returns the string "no type found".
3694
+ Raises
3695
+ ------
3696
+ PyegeriaException
3697
+ ValidationError
3698
+
3699
+ Notes
3700
+ -----
3701
+ More information can be found at: https://egeria-project.org/concepts/deployed-implementation-type
3702
+ Sample body:
3703
+ {
3704
+ "class" : "FilterRequestBody",
3705
+ "filter" : "Root Technology Type",
3706
+ "startFrom": 0,
3707
+ "pageSize": 10,
3708
+ "asOfTime" : "{{$isoTimestamp}}",
3709
+ "effectiveTime" : "{{$isoTimestamp}}",
3710
+ "includeOnlyClassifiedElements" : ["Template"]
3711
+ "forLineage" : false,
3712
+ "forDuplicateProcessing" : false,
3713
+ "limitResultsByStatus" : ["ACTIVE"],
3714
+ "sequencingOrder" : "PROPERTY_ASCENDING",
3715
+ "sequencingProperty" : "qualifiedName"
3716
+ }
3717
+ """
3718
+
3719
+ # validate_name(type_name)
3720
+ if filter_string == "*":
3721
+ filter_string = "Root Technology Type"
3722
+
3723
+ url = str(HttpUrl(f"{self.curation_command_root}/technology-types/hierarchy"))
3724
+ if body is None:
3725
+ body = {
3726
+ "class": "FilterRequestBody",
3727
+ "filter": filter_string
3728
+ }
3729
+ body_s = body_slimmer(body)
3730
+ response = await self._async_make_request("POST", url, body_s)
3731
+ element = response.json().get("element", NO_ELEMENTS_FOUND)
3732
+ if type(element) is str:
3733
+ logger.info(NO_ELEMENTS_FOUND)
3734
+ return NO_ELEMENTS_FOUND
3735
+
3736
+ if output_format != 'JSON': # return a simplified markdown representation
3737
+ logger.info(f"Found elements, output format: {output_format} and report_spec: {report_spec}")
3738
+ return self._generate_tech_type_output(element, filter_string, "ValidMetadataValue",
3739
+ output_format, report_spec)
3740
+ return element
3741
+
3742
+ def get_tech_type_hierarchy(self, filter_string: Optional[str] = None, body: Optional[dict | FilterRequestBody] = None,
3743
+ output_format: str = "JSON", report_spec: str | dict = "TechType", **kwargs) -> list | str:
3744
+ """Retrieve the details of the named technology type. This name should be the name of the technology type
3745
+ and contain no wild cards.
3746
+ Parameters
3747
+ ----------
3748
+ filter_string : str
3749
+ The name of the technology type to retrieve detailed information for.
3750
+ body: dict | FilterRequestBody
3751
+ If provided, the information in the body supersedes the other parameters and allows more advanced requests.
3752
+
3753
+ Returns
3754
+ -------
3755
+ list[dict] | str
3756
+ A list of dictionaries containing the detailed information for the specified technology type.
3757
+ If the technology type is not found, returns the string "no type found".
3758
+ Raises
3759
+ ------
3760
+ PyegeriaException
3761
+ ValidationError
3762
+
3763
+ Notes
3764
+ -----
3765
+ More information can be found at: https://egeria-project.org/concepts/deployed-implementation-type
3766
+ Sample body:
3767
+ {
3768
+ "class" : "FilterRequestBody",
3769
+ "filter" : "Root Technology Type",
3770
+ "startFrom": 0,
3771
+ "pageSize": 10,
3772
+ "asOfTime" : "{{$isoTimestamp}}",
3773
+ "effectiveTime" : "{{$isoTimestamp}}",
3774
+ "includeOnlyClassifiedElements" : ["Template"]
3775
+ "forLineage" : false,
3776
+ "forDuplicateProcessing" : false,
3777
+ "limitResultsByStatus" : ["ACTIVE"],
3778
+ "sequencingOrder" : "PROPERTY_ASCENDING",
3779
+ "sequencingProperty" : "qualifiedName"
3780
+ }
3781
+ """
3782
+
3783
+ loop = asyncio.get_event_loop()
3784
+ response = loop.run_until_complete(
3785
+ self._async_get_tech_type_hierarchy(filter_string, body=body, output_format=output_format, report_spec=report_spec)
3786
+ )
3787
+ return response
3788
+
3789
+
3790
+
3791
+
3792
+
3793
+ async def _async_get_template_guid_for_technology_type(self, type_name: str) -> str:
3794
+ details = await self._async_get_tech_type_detail(type_name)
3795
+ if isinstance(details, dict):
3796
+ return details.get("catalogTemplates", {})[0].get("relatedElement", {}).get("elementHeader", {}).get("guid",
3797
+ None)
3798
+ else:
3799
+ return None
3800
+
3801
+ def get_template_guid_for_technology_type(self, type_name: str) -> str:
3802
+ loop = asyncio.get_event_loop()
3803
+ response = loop.run_until_complete(
3804
+ self._async_get_template_guid_for_technology_type(type_name)
3805
+ )
3806
+ return response
3807
+
3808
+ async def async_find_technology_types(
3809
+ self,
3810
+ search_string: str = "*",
3811
+ starts_with: bool = False,
3812
+ ends_with: bool = False,
3813
+ ignore_case: bool = True,
3814
+ anchor_domain: Optional[str] = None,
3815
+ metadata_element_type: Optional[str] = None,
3816
+ metadata_element_subtypes: Optional[list[str]] = None,
3817
+ skip_relationships: Optional[list[str]] = None,
3818
+ include_only_relationships: Optional[list[str]] = None,
3819
+ skip_classified_elements: Optional[list[str]] = None,
3820
+ include_only_classified_elements: Optional[list[str]] = None,
3821
+ graph_query_depth: int = 3,
3822
+ governance_zone_filter: Optional[list[str]] = None,
3823
+ as_of_time: Optional[str] = None,
3824
+ effective_time: Optional[str] = None,
3825
+ relationship_page_size: int = 0,
3826
+ limit_results_by_status: list[str] = ["ACTIVE"],
3827
+ sequencing_order: str = "PROPERTY_ASCENDING",
3828
+ sequencing_property: str = "qualifiedName",
3829
+ output_format: str = "JSON",
3830
+ report_spec: str | dict = "TechType",
3831
+ start_from: int = 0,
3832
+ page_size: int = 0,
3833
+ property_names: Optional[list[str]] = None,
3834
+ body: Optional[dict | SearchStringRequestBody] = None,
3835
+ ) -> list | str:
3836
+ """Retrieve the list of technology types that contain the search string. Async version.
3837
+
3838
+ Parameters:
3839
+ ----------
3840
+ search_string: str
3841
+ The search string we are looking for.
3842
+ starts_with : bool, optional
3843
+ Whether to search engine actions that start with the given search string. Default is False.
3844
+ ends_with : bool, optional
3845
+ Whether to search engine actions that end with the given search string. Default is False.
3846
+ ignore_case : bool, optional
3847
+ Whether to ignore case while searching engine actions. Default is True.
3848
+ start_from : int, optional
3849
+ The index from which to start fetching the engine actions. Default is 0.
3850
+ page_size : int, optional
3851
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
3852
+ output_format: str, optional
3853
+ The format of the output. Default is "JSON".
3854
+ report_spec: str | dict, optional
3855
+ The report specification. Default is "TechType".
3856
+ body: dict | SearchStringRequestBody, optional
3857
+ The request body. Default is None.
3858
+
3859
+ Returns:
3860
+ -------
3861
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
3862
+
3863
+ Raises:
3864
+ ------
3865
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3866
+ this exception is raised with details from the response content.
3867
+ PyegeriaAPIException: If the API response indicates a server side error.
3868
+ PyegeriaUnauthorizedException:
3869
+
3870
+ Notes
3871
+ -----
3872
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
3873
+ """
3874
+
3875
+ if search_string == "*":
3876
+ search_string = None
3877
+
3878
+ url = f"{self.curation_command_root}/technology-types/by-search-string"
3879
+
3880
+ return await self._async_find_request(
3881
+ url,
3882
+ _type="TechType",
3883
+ _gen_output=self._generate_tech_type_output,
3884
+ search_string=search_string,
3885
+ starts_with=starts_with,
3886
+ ends_with=ends_with,
3887
+ ignore_case=ignore_case,
3888
+ anchor_domain=anchor_domain,
3889
+ metadata_element_type=metadata_element_type,
3890
+ metadata_element_subtypes=metadata_element_subtypes,
3891
+ skip_relationships=skip_relationships,
3892
+ include_only_relationships=include_only_relationships,
3893
+ skip_classified_elements=skip_classified_elements,
3894
+ include_only_classified_elements=include_only_classified_elements,
3895
+ graph_query_depth=graph_query_depth,
3896
+ governance_zone_filter=governance_zone_filter,
3897
+ as_of_time=as_of_time,
3898
+ effective_time=effective_time,
3899
+ relationship_page_size=relationship_page_size,
3900
+ limit_results_by_status=limit_results_by_status,
3901
+ sequencing_order=sequencing_order,
3902
+ sequencing_property=sequencing_property,
3903
+ output_format=output_format,
3904
+ report_spec=report_spec,
3905
+ start_from=start_from,
3906
+ page_size=page_size,
3907
+ property_names=property_names,
3908
+ body=body,
3909
+ )
3910
+
3911
+ def find_technology_types(
3912
+ self,
3913
+ search_string: str = "*",
3914
+ starts_with: bool = False,
3915
+ ends_with: bool = False,
3916
+ ignore_case: bool = True,
3917
+ anchor_domain: Optional[str] = None,
3918
+ metadata_element_type: Optional[str] = None,
3919
+ metadata_element_subtypes: Optional[list[str]] = None,
3920
+ skip_relationships: Optional[list[str]] = None,
3921
+ include_only_relationships: Optional[list[str]] = None,
3922
+ skip_classified_elements: Optional[list[str]] = None,
3923
+ include_only_classified_elements: Optional[list[str]] = None,
3924
+ graph_query_depth: int = 3,
3925
+ governance_zone_filter: Optional[list[str]] = None,
3926
+ as_of_time: Optional[str] = None,
3927
+ effective_time: Optional[str] = None,
3928
+ relationship_page_size: int = 0,
3929
+ limit_results_by_status: list[str] = ["ACTIVE"],
3930
+ sequencing_order: str = "PROPERTY_ASCENDING",
3931
+ sequencing_property: str = "qualifiedName",
3932
+ output_format: str = "JSON",
3933
+ report_spec: str | dict = "TechType",
3934
+ start_from: int = 0,
3935
+ page_size: int = 0,
3936
+ property_names: Optional[list[str]] = None,
3937
+ body: Optional[dict | SearchStringRequestBody] = None,
3938
+ ) -> list | str:
3939
+ """Retrieve the list of technology types that contain the search string.
3940
+
3941
+ Parameters:
3942
+ ----------
3943
+ search_string: str
3944
+ The search string we are looking for.
3945
+ starts_with : bool, optional
3946
+ Whether to search engine actions that start with the given search string. Default is False.
3947
+ ends_with : bool, optional
3948
+ Whether to search engine actions that end with the given search string. Default is False.
3949
+ ignore_case : bool, optional
3950
+ Whether to ignore case while searching engine actions. Default is True.
3951
+ start_from : int, optional
3952
+ The index from which to start fetching the engine actions. Default is 0.
3953
+ page_size : int, optional
3954
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
3955
+ output_format: str, optional
3956
+ The format of the output. Default is "JSON".
3957
+ report_spec: str | dict, optional
3958
+ The report specification. Default is "TechType".
3959
+ body: dict | SearchStringRequestBody, optional
3960
+ The request body. Default is None.
3961
+
3962
+ Returns:
3963
+ -------
3964
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
3965
+
3966
+ Raises:
3967
+ ------
3968
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
3969
+ this exception is raised with details from the response content.
3970
+ PyegeriaAPIException: If the API response indicates a server side error.
3971
+ PyegeriaUnauthorizedException:
3972
+
3973
+ Notes
3974
+ -----
3975
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
3976
+ """
3977
+
3978
+ loop = asyncio.get_event_loop()
3979
+ response = loop.run_until_complete(
3980
+ self.async_find_technology_types(
3981
+ search_string=search_string,
3982
+ starts_with=starts_with,
3983
+ ends_with=ends_with,
3984
+ ignore_case=ignore_case,
3985
+ anchor_domain=anchor_domain,
3986
+ metadata_element_type=metadata_element_type,
3987
+ metadata_element_subtypes=metadata_element_subtypes,
3988
+ skip_relationships=skip_relationships,
3989
+ include_only_relationships=include_only_relationships,
3990
+ skip_classified_elements=skip_classified_elements,
3991
+ include_only_classified_elements=include_only_classified_elements,
3992
+ graph_query_depth=graph_query_depth,
3993
+ governance_zone_filter=governance_zone_filter,
3994
+ as_of_time=as_of_time,
3995
+ effective_time=effective_time,
3996
+ relationship_page_size=relationship_page_size,
3997
+ limit_results_by_status=limit_results_by_status,
3998
+ sequencing_order=sequencing_order,
3999
+ sequencing_property=sequencing_property,
4000
+ output_format=output_format,
4001
+ report_spec=report_spec,
4002
+ start_from=start_from,
4003
+ page_size=page_size,
4004
+ property_names=property_names,
4005
+ body=body,
4006
+ )
4007
+ )
4008
+ return response
4009
+
4010
+ async def async_find_technology_types_body(
4011
+ self,
4012
+ search_string: str = "*",
4013
+ starts_with: bool = False,
4014
+ ends_with: bool = False,
4015
+ ignore_case: bool = True,
4016
+ anchor_domain: Optional[str] = None,
4017
+ metadata_element_type: Optional[str] = None,
4018
+ metadata_element_subtypes: Optional[list[str]] = None,
4019
+ skip_relationships: Optional[list[str]] = None,
4020
+ include_only_relationships: Optional[list[str]] = None,
4021
+ skip_classified_elements: Optional[list[str]] = None,
4022
+ include_only_classified_elements: Optional[list[str]] = None,
4023
+ graph_query_depth: int = 3,
4024
+ governance_zone_filter: Optional[list[str]] = None,
4025
+ as_of_time: Optional[str] = None,
4026
+ effective_time: Optional[str] = None,
4027
+ relationship_page_size: int = 0,
4028
+ limit_results_by_status: list[str] = ["ACTIVE"],
4029
+ sequencing_order: str = "PROPERTY_ASCENDING",
4030
+ sequencing_property: str = "qualifiedName",
4031
+ output_format: str = "JSON",
4032
+ report_spec: str | dict = "TechType",
4033
+ start_from: int = 0,
4034
+ page_size: int = 0,
4035
+ property_names: Optional[list[str]] = None,
4036
+ body: Optional[dict | SearchStringRequestBody] = None,
4037
+ ) -> list | str:
4038
+ """Retrieve the list of technology types that contain the search string. Async version.
4039
+
4040
+ Parameters:
4041
+ ----------
4042
+ search_string: str
4043
+ The search string we are looking for.
4044
+ starts_with : bool, optional
4045
+ Whether to search engine actions that start with the given search string. Default is False.
4046
+ ends_with : bool, optional
4047
+ Whether to search engine actions that end with the given search string. Default is False.
4048
+ ignore_case : bool, optional
4049
+ Whether to ignore case while searching engine actions. Default is True.
4050
+ start_from : int, optional
4051
+ The index from which to start fetching the engine actions. Default is 0.
4052
+ page_size : int, optional
4053
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
4054
+ output_format: str, optional
4055
+ The format of the output. Default is "JSON".
4056
+ report_spec: str | dict, optional
4057
+ The report specification. Default is "TechType".
4058
+ body: dict | SearchStringRequestBody, optional
4059
+ The request body. Default is None.
4060
+
4061
+ Returns:
4062
+ -------
4063
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
4064
+
4065
+ Raises:
4066
+ ------
4067
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
4068
+ this exception is raised with details from the response content.
4069
+ PyegeriaAPIException: If the API response indicates a server side error.
4070
+ PyegeriaUnauthorizedException:
4071
+
4072
+ Notes
4073
+ -----
4074
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
4075
+ """
4076
+
4077
+ return await self.async_find_technology_types(
4078
+ search_string=search_string,
4079
+ starts_with=starts_with,
4080
+ ends_with=ends_with,
4081
+ ignore_case=ignore_case,
4082
+ anchor_domain=anchor_domain,
4083
+ metadata_element_type=metadata_element_type,
4084
+ metadata_element_subtypes=metadata_element_subtypes,
4085
+ skip_relationships=skip_relationships,
4086
+ include_only_relationships=include_only_relationships,
4087
+ skip_classified_elements=skip_classified_elements,
4088
+ include_only_classified_elements=include_only_classified_elements,
4089
+ graph_query_depth=graph_query_depth,
4090
+ governance_zone_filter=governance_zone_filter,
4091
+ as_of_time=as_of_time,
4092
+ effective_time=effective_time,
4093
+ relationship_page_size=relationship_page_size,
4094
+ limit_results_by_status=limit_results_by_status,
4095
+ sequencing_order=sequencing_order,
4096
+ sequencing_property=sequencing_property,
4097
+ output_format=output_format,
4098
+ report_spec=report_spec,
4099
+ start_from=start_from,
4100
+ page_size=page_size,
4101
+ property_names=property_names,
4102
+ body=body,
4103
+ )
4104
+
4105
+ def find_technology_types_body(
4106
+ self,
4107
+ search_string: str = "*",
4108
+ starts_with: bool = False,
4109
+ ends_with: bool = False,
4110
+ ignore_case: bool = True,
4111
+ anchor_domain: Optional[str] = None,
4112
+ metadata_element_type: Optional[str] = None,
4113
+ metadata_element_subtypes: Optional[list[str]] = None,
4114
+ skip_relationships: Optional[list[str]] = None,
4115
+ include_only_relationships: Optional[list[str]] = None,
4116
+ skip_classified_elements: Optional[list[str]] = None,
4117
+ include_only_classified_elements: Optional[list[str]] = None,
4118
+ graph_query_depth: int = 3,
4119
+ governance_zone_filter: Optional[list[str]] = None,
4120
+ as_of_time: Optional[str] = None,
4121
+ effective_time: Optional[str] = None,
4122
+ relationship_page_size: int = 0,
4123
+ limit_results_by_status: list[str] = ["ACTIVE"],
4124
+ sequencing_order: str = "PROPERTY_ASCENDING",
4125
+ sequencing_property: str = "qualifiedName",
4126
+ output_format: str = "JSON",
4127
+ report_spec: str | dict = "TechType",
4128
+ start_from: int = 0,
4129
+ page_size: int = 0,
4130
+ property_names: Optional[list[str]] = None,
4131
+ body: Optional[dict | SearchStringRequestBody] = None,
4132
+ ) -> list | str:
4133
+ """Retrieve the list of technology types that contain the search string.
4134
+
4135
+ Parameters:
4136
+ ----------
4137
+ search_string: str
4138
+ The search string we are looking for.
4139
+ starts_with : bool, optional
4140
+ Whether to search engine actions that start with the given search string. Default is False.
4141
+ ends_with : bool, optional
4142
+ Whether to search engine actions that end with the given search string. Default is False.
4143
+ ignore_case : bool, optional
4144
+ Whether to ignore case while searching engine actions. Default is True.
4145
+ start_from : int, optional
4146
+ The index from which to start fetching the engine actions. Default is 0.
4147
+ page_size : int, optional
4148
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
4149
+ output_format: str, optional
4150
+ The format of the output. Default is "JSON".
4151
+ report_spec: str | dict, optional
4152
+ The report specification. Default is "TechType".
4153
+ body: dict | SearchStringRequestBody, optional
4154
+ The request body. Default is None.
4155
+
4156
+ Returns:
4157
+ -------
4158
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
4159
+
4160
+ Raises:
4161
+ ------
4162
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
4163
+ this exception is raised with details from the response content.
4164
+ PyegeriaAPIException: If the API response indicates a server side error.
4165
+ PyegeriaUnauthorizedException:
4166
+
4167
+ Notes
4168
+ -----
4169
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
4170
+ """
4171
+
4172
+ loop = asyncio.get_event_loop()
4173
+ response = loop.run_until_complete(
4174
+ self.async_find_technology_types_body(
4175
+ search_string=search_string,
4176
+ starts_with=starts_with,
4177
+ ends_with=ends_with,
4178
+ ignore_case=ignore_case,
4179
+ anchor_domain=anchor_domain,
4180
+ metadata_element_type=metadata_element_type,
4181
+ metadata_element_subtypes=metadata_element_subtypes,
4182
+ skip_relationships=skip_relationships,
4183
+ include_only_relationships=include_only_relationships,
4184
+ skip_classified_elements=skip_classified_elements,
4185
+ include_only_classified_elements=include_only_classified_elements,
4186
+ graph_query_depth=graph_query_depth,
4187
+ governance_zone_filter=governance_zone_filter,
4188
+ as_of_time=as_of_time,
4189
+ effective_time=effective_time,
4190
+ relationship_page_size=relationship_page_size,
4191
+ limit_results_by_status=limit_results_by_status,
4192
+ sequencing_order=sequencing_order,
4193
+ sequencing_property=sequencing_property,
4194
+ output_format=output_format,
4195
+ report_spec=report_spec,
4196
+ start_from=start_from,
4197
+ page_size=page_size,
4198
+ property_names=property_names,
4199
+ body=body,
4200
+ )
4201
+ )
4202
+ return response
4203
+
4204
+ async def _async_get_all_technology_types(
4205
+ self, start_from: int = 0, page_size: int = 0, output_format: str = "JSON", report_spec: str = "TechType"
4206
+ ) -> list | str:
4207
+ """Get all technology types - async version"""
4208
+ return await self._async_find_technology_types(search_string = "*", start_from = start_from,
4209
+ page_size = page_size, output_format = output_format,
4210
+ report_spec = report_spec)
4211
+
4212
+ def get_all_technology_types(
4213
+ self, start_from: int = 0, page_size: int = 0, output_format: str = "JSON", report_spec: str = "TechType"
4214
+ ) -> list | str:
4215
+ """Get all technology types"""
4216
+ return self.find_technology_types(search_string = "*", start_from = start_from, page_size = page_size,
4217
+ output_format = output_format, report_spec = report_spec)
4218
+
4219
+ def print_engine_action_summary(self, governance_action: dict):
4220
+ """print_governance_action_summary
4221
+
4222
+ Print all the governance actions with their status, in the server.
4223
+
4224
+ Parameters
4225
+ ----------
4226
+
4227
+ Returns
4228
+ -------
4229
+
4230
+ Raises
4231
+ ------
4232
+ PyegeriaException """
4233
+ if governance_action:
4234
+ name = governance_action.get("displayName")
4235
+ if not name:
4236
+ name = governance_action.get("qualifiedName")
4237
+ action_status = governance_action.get("action_status")
4238
+ if governance_action.get("completion_guards"):
4239
+ completion_guards = governance_action.get("completion_guards")
4240
+ else:
4241
+ completion_guards = "\t"
4242
+ if governance_action.get("process_name"):
4243
+ process_name = governance_action.get("process_name")
4244
+ else:
4245
+ process_name = "\t"
4246
+ if governance_action.get("completion_message"):
4247
+ completion_message = governance_action.get("completion_message")
4248
+ else:
4249
+ completion_message = ""
4250
+ print(
4251
+ action_status
4252
+ + "\n\t| "
4253
+ + name
4254
+ + "\t| "
4255
+ + process_name
4256
+ + "\t| "
4257
+ + "%s" % ", ".join(map(str, completion_guards))
4258
+ + "\t| "
4259
+ + completion_message
4260
+ )
4261
+
4262
+ def print_engine_actions(self):
4263
+ """print_governance_actions
4264
+
4265
+ Print all the governance actions with their status, in the server.
4266
+
4267
+ Parameters
4268
+ ----------
4269
+
4270
+ Returns
4271
+ -------
4272
+
4273
+ Raises
4274
+ ------
4275
+ PyegeriaException
4276
+ """
4277
+ governance_actions = self.get_engine_actions()
4278
+ if governance_actions is not None:
4279
+ for x in range(len(governance_actions)):
4280
+ self.print_engine_action_summary(governance_actions[x])
4281
+
4282
+ async def _async_get_technology_type_elements(
4283
+ self,
4284
+ filter_string: str,
4285
+ effective_time: Optional[str] = None,
4286
+ start_from: int = 0,
4287
+ page_size: int = 0,
4288
+ get_templates: bool = False,
4289
+ output_format: str = "JSON", report_spec: str = "Tech-Type-Elements",
4290
+ body: Optional[dict | FilterRequestBody] = None,
4291
+ ) -> list | str:
4292
+ """Retrieve the elements for the requested deployed implementation type. There are no wildcards allowed
4293
+ in the name. Async version.
4294
+
4295
+ Parameters:
4296
+ output_format ():
4297
+ report_spec ():
4298
+ body ():
4299
+ ----------
4300
+ filter_string: str
4301
+ The name of the deployed technology implementation type to retrieve elements for.
4302
+ effective_time: datetime, [default=None], optional
4303
+ Effective time of the query. If not specified will default to any effective time. Time format is
4304
+ "YYYY-MM-DDTHH:MM:SS" (ISO 8601)
4305
+
4306
+ start_from : int, optional
4307
+ The index from which to start fetching the engine actions. Default is 0.
4308
+
4309
+ page_size : int, optional
4310
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
4311
+
4312
+ Returns:
4313
+ -------
4314
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
4315
+
4316
+ Raises:
4317
+ ------
4318
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
4319
+ this exception is raised with details from the response content.
4320
+ PyegeriaAPIException: If the API response indicates a server side error.
4321
+ PyegeriaUnauthorizedException:
4322
+
4323
+ Notes
4324
+ -----
4325
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
4326
+ """
4327
+
4328
+ skip_templates = "Template" if not get_templates else ""
4329
+ validate_name(filter_string)
4330
+
4331
+ url = (
4332
+ f"{self.curation_command_root}/technology-types/elements"
4333
+ )
4334
+ if body is None:
4335
+ body = {
4336
+ "class" : "FilterRequestBody",
4337
+ "filter": filter_string,
4338
+ "effective_time": effective_time,
4339
+ "skipClassifiedElements": [skip_templates],
4340
+ "startFrom": start_from,
4341
+ "pageSize": page_size
4342
+ }
4343
+
4344
+ response = await self._async_get_name_request(url, "TechTypeElement", self._generate_tech_type_element_output, filter_string, None, start_from, page_size, output_format, report_spec, body)
4345
+ return response
4346
+
4347
+
4348
+ def get_technology_type_elements(
4349
+ self,
4350
+ filter_string: str,
4351
+ effective_time: Optional[str] = None,
4352
+ start_from: int = 0,
4353
+ page_size: int = 0,
4354
+ get_templates: bool = False,
4355
+ output_format: str = "JSON", report_spec: str = "Tech-Type-Elements",
4356
+ body: Optional[dict | FilterRequestBody] = None,
4357
+ ) -> list | str:
4358
+ """Retrieve the elements for the requested deployed implementation type. There are no wildcards allowed
4359
+ in the name.
4360
+
4361
+ Parameters:
4362
+ output_format ():
4363
+ report_spec ():
4364
+ body ():
4365
+ ----------
4366
+ filter_string: str
4367
+ The name of the deployed technology implementation type to retrieve elements for.
4368
+ effective_time: datetime, [default=None], optional
4369
+ Effective time of the query. If not specified will default to any effective time. Time format is
4370
+ "YYYY-MM-DDTHH:MM:SS" (ISO 8601)
4371
+
4372
+ start_from : int, optional
4373
+ The index from which to start fetching the engine actions. Default is 0.
4374
+
4375
+ page_size : int, optional
4376
+ The maximum number of engine actions to fetch in a single request. Default is `0`.
4377
+
4378
+ Returns:
4379
+ -------
4380
+ [dict] | str: List of elements describing the technology - or "no tech found" if not found.
4381
+
4382
+ Raises:
4383
+ ------
4384
+ PyegeriaInvalidParameterException: If the API response indicates an error (non-200 status code),
4385
+ this exception is raised with details from the response content.
4386
+ PyegeriaAPIException: If the API response indicates a server side error.
4387
+ PyegeriaUnauthorizedException:
4388
+
4389
+ Notes
4390
+ -----
4391
+ For more information see: https://egeria-project.org/concepts/deployed-implementation-type
4392
+ """
4393
+
4394
+ loop = asyncio.get_event_loop()
4395
+ response = loop.run_until_complete(
4396
+ self._async_get_technology_type_elements(filter_string, effective_time, start_from, page_size, get_templates, output_format,
4397
+ report_spec, body)
4398
+ )
4399
+ return response
4400
+
4401
+
4402
+ if __name__ == "__main__":
4403
+ print("Main-Automated Curation")