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,1825 @@
1
+ """
2
+ SPDX-License-Identifier: Apache-2.0
3
+ Copyright Contributors to the ODPi Egeria project.
4
+
5
+ This module provides access to the Product Manager OMVS module.
6
+
7
+ The Product Manager OMVS provides APIs for managing digital products and their
8
+ relationships, including product dependencies and product managers.
9
+ """
10
+
11
+ import asyncio
12
+ from typing import Optional
13
+
14
+ from pyegeria.omvs.collection_manager import CollectionManager
15
+ from pyegeria.core._server_client import ServerClient
16
+ from pyegeria.core.config import settings as app_settings
17
+ from pyegeria.models import (
18
+ NewElementRequestBody,
19
+ UpdateElementRequestBody,
20
+ NewRelationshipRequestBody,
21
+ DeleteRelationshipRequestBody,
22
+ DeleteElementRequestBody,
23
+ )
24
+ from pyegeria.core.utils import dynamic_catch, body_slimmer
25
+ from loguru import logger
26
+
27
+ EGERIA_LOCAL_QUALIFIER = app_settings.User_Profile.egeria_local_qualifier
28
+
29
+
30
+ class ProductManager(CollectionManager):
31
+ """
32
+ Manage digital products, digital product catalogs, and their relationships.
33
+
34
+ This client provides methods to create, update, and manage digital products and
35
+ digital product catalogs, including linking product dependencies and product manager roles.
36
+
37
+ Attributes
38
+ ----------
39
+ view_server : str
40
+ The name of the View Server to connect to.
41
+ platform_url : str
42
+ URL of the server platform to connect to.
43
+ user_id : str
44
+ The identity of the user calling the method - this sets a default optionally
45
+ used by the methods when the user doesn't pass the user_id on a method call.
46
+ user_pwd : str, optional
47
+ The password associated with the user_id. Defaults to None.
48
+ token : str, optional
49
+ An optional bearer token for authentication.
50
+
51
+ Methods
52
+ -------
53
+ create_digital_product(body)
54
+ Create a new digital product collection.
55
+ update_digital_product(digital_product_guid, body)
56
+ Update the properties of a digital product.
57
+ delete_digital_product(digital_product_guid, body, cascade)
58
+ Delete a digital product.
59
+ get_digital_product_by_guid(digital_product_guid, body, output_format, report_spec)
60
+ Return the properties of a specific digital product by GUID.
61
+ get_digital_products_by_name(filter_string, body, start_from, page_size, output_format, report_spec)
62
+ Returns the list of digital products with a particular name.
63
+ find_digital_products(search_string, starts_with, ends_with, ignore_case, start_from, page_size, output_format, report_spec, body)
64
+ Returns the list of digital products matching the search string.
65
+ create_digital_product_catalog(body)
66
+ Create a new digital product catalog collection.
67
+ update_digital_product_catalog(digital_product_catalog_guid, body)
68
+ Update the properties of a digital product catalog.
69
+ delete_digital_product_catalog(digital_product_catalog_guid, body, cascade)
70
+ Delete a digital product catalog.
71
+ get_digital_product_catalog_by_guid(digital_product_catalog_guid, body, output_format, report_spec)
72
+ Return the properties of a specific digital product catalog by GUID.
73
+ get_digital_product_catalogs_by_name(filter_string, body, start_from, page_size, output_format, report_spec)
74
+ Returns the list of digital product catalogs with a particular name.
75
+ find_digital_product_catalogs(search_string, starts_with, ends_with, ignore_case, start_from, page_size, output_format, report_spec, body)
76
+ Returns the list of digital product catalogs matching the search string.
77
+ link_digital_product_dependency(consumer_product_guid, consumed_product_guid, body)
78
+ Link two dependent digital products.
79
+ detach_digital_product_dependency(consumer_product_guid, consumed_product_guid, body)
80
+ Unlink dependent digital products.
81
+ link_product_manager(digital_product_guid, product_manager_role_guid, body)
82
+ Attach a product manager role to a digital product.
83
+ detach_product_manager(digital_product_guid, product_manager_role_guid, body)
84
+ Detach a product manager from a digital product.
85
+ """
86
+
87
+ def __init__(
88
+ self,
89
+ view_server: str,
90
+ platform_url: str,
91
+ user_id: str,
92
+ user_pwd: Optional[str] = None,
93
+ token: Optional[str] = None,
94
+ ):
95
+ self.view_server = view_server
96
+ self.platform_url = platform_url
97
+ self.user_id = user_id
98
+ self.user_pwd = user_pwd
99
+ self.product_manager_command_root: str = (
100
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/product-manager"
101
+ )
102
+ ServerClient.__init__(self, view_server, platform_url, user_id, user_pwd, token)
103
+
104
+ def _prepare_body(self, body: Optional[dict | NewElementRequestBody | UpdateElementRequestBody |
105
+ NewRelationshipRequestBody | DeleteRelationshipRequestBody]) -> dict:
106
+ """Convert Pydantic models to dict and slim the body."""
107
+ if body is None:
108
+ return {}
109
+ if isinstance(body, dict):
110
+ return body_slimmer(body)
111
+ # It's a Pydantic model
112
+ return body_slimmer(body.model_dump(mode='json', by_alias=True, exclude_none=True))
113
+
114
+ #
115
+ # Digital Product Management
116
+ #
117
+
118
+ @dynamic_catch
119
+ async def _async_create_digital_product(
120
+ self,
121
+ body: Optional[dict | NewElementRequestBody] = None,
122
+ ) -> str:
123
+ """Create a new digital product collection. Async version.
124
+
125
+ Parameters
126
+ ----------
127
+ body : dict | NewElementRequestBody, optional
128
+ Request body containing digital product properties.
129
+
130
+ Returns
131
+ -------
132
+ str
133
+ The GUID of the created digital product.
134
+
135
+ Raises
136
+ ------
137
+ PyegeriaException
138
+ If there are issues in communications, message format, or Egeria errors.
139
+ ValidationError
140
+ If the body does not conform to NewElementRequestBody.
141
+ PyegeriaNotAuthorizedException
142
+ If the user is not authorized for the requested action.
143
+
144
+ Notes
145
+ -----
146
+ Sample JSON body:
147
+ ```json
148
+ {
149
+ "class" : "NewElementRequestBody",
150
+ "isOwnAnchor" : true,
151
+ "properties": {
152
+ "class" : "DigitalProductProperties",
153
+ "qualifiedName": "DigitalProduct::Product Name",
154
+ "displayName" : "Product Display Name",
155
+ "description" : "Description of the product",
156
+ "identifier" : "Product ID",
157
+ "productName" : "Product Name",
158
+ "introductionDate" : "2024-01-01T00:00:00.000+00:00"
159
+ }
160
+ }
161
+ ```
162
+ """
163
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/product-manager/collections"
164
+ return await self._async_create_element_body_request(url, ["DigitalProductProperties"], body)
165
+
166
+ def create_digital_product(
167
+ self,
168
+ body: Optional[dict | NewElementRequestBody] = None,
169
+ ) -> str:
170
+ """Create a new digital product collection.
171
+
172
+ Parameters
173
+ ----------
174
+ body : dict | NewElementRequestBody, optional
175
+ Request body containing digital product properties.
176
+
177
+ Returns
178
+ -------
179
+ str
180
+ The GUID of the created digital product.
181
+
182
+ Raises
183
+ ------
184
+ PyegeriaException
185
+ If there are issues in communications, message format, or Egeria errors.
186
+
187
+ Notes
188
+ -----
189
+ Sample JSON body:
190
+ ```json
191
+ {
192
+ "class" : "NewElementRequestBody",
193
+ "isOwnAnchor" : true,
194
+ "properties": {
195
+ "class" : "DigitalProductProperties",
196
+ "qualifiedName": "DigitalProduct::Product Name",
197
+ "displayName" : "Product Display Name",
198
+ "description" : "Description of the product",
199
+ "identifier" : "Product ID",
200
+ "productName" : "Product Name",
201
+ "introductionDate" : "2024-01-01T00:00:00.000+00:00"
202
+ }
203
+ }
204
+ ```
205
+ """
206
+ loop = asyncio.get_event_loop()
207
+ return loop.run_until_complete(self._async_create_digital_product(body))
208
+
209
+ @dynamic_catch
210
+ async def _async_update_digital_product(
211
+ self,
212
+ digital_product_guid: str,
213
+ body: Optional[dict | UpdateElementRequestBody] = None,
214
+ ) -> None:
215
+ """Update the properties of a digital product. Async version.
216
+
217
+ Parameters
218
+ ----------
219
+ digital_product_guid : str
220
+ The GUID of the digital product to update.
221
+ body : dict | UpdateElementRequestBody, optional
222
+ Request body containing updated properties.
223
+
224
+ Returns
225
+ -------
226
+ None
227
+
228
+ Raises
229
+ ------
230
+ PyegeriaException
231
+ If there are issues in communications, message format, or Egeria errors.
232
+
233
+ Notes
234
+ -----
235
+ Sample JSON body:
236
+ ```json
237
+ {
238
+ "class" : "UpdateElementRequestBody",
239
+ "mergeUpdate": true,
240
+ "properties": {
241
+ "class" : "DigitalProductProperties",
242
+ "displayName" : "New Display Name"
243
+ }
244
+ }
245
+ ```
246
+ """
247
+ url = f"{self.product_manager_command_root}/collections/{digital_product_guid}/update"
248
+ await self._async_update_element_body_request(url, ["DigitalProductProperties"], body)
249
+
250
+ def update_digital_product(
251
+ self,
252
+ digital_product_guid: str,
253
+ body: Optional[dict | UpdateElementRequestBody] = None,
254
+ ) -> None:
255
+ """Update the properties of a digital product.
256
+
257
+ Parameters
258
+ ----------
259
+ digital_product_guid : str
260
+ The GUID of the digital product to update.
261
+ body : dict | UpdateElementRequestBody, optional
262
+ Request body containing updated properties.
263
+
264
+ Returns
265
+ -------
266
+ None
267
+
268
+ Raises
269
+ ------
270
+ PyegeriaException
271
+ If there are issues in communications, message format, or Egeria errors.
272
+
273
+ Notes
274
+ -----
275
+ Sample JSON body:
276
+ ```json
277
+ {
278
+ "class" : "UpdateElementRequestBody",
279
+ "mergeUpdate": true,
280
+ "properties": {
281
+ "class" : "DigitalProductProperties",
282
+ "displayName" : "New Display Name"
283
+ }
284
+ }
285
+ ```
286
+ """
287
+ loop = asyncio.get_event_loop()
288
+ loop.run_until_complete(
289
+ self._async_update_digital_product(digital_product_guid, body)
290
+ )
291
+
292
+ @dynamic_catch
293
+ async def _async_delete_digital_product(
294
+ self,
295
+ digital_product_guid: str,
296
+ body: Optional[dict | DeleteElementRequestBody] = None,
297
+ cascade: bool = False,
298
+ ) -> None:
299
+ """Delete a digital product. Async version.
300
+
301
+ Parameters
302
+ ----------
303
+ digital_product_guid : str
304
+ The GUID of the digital product to delete.
305
+ body : dict | DeleteElementRequestBody, optional
306
+ Request body for deletion.
307
+ cascade : bool, optional, default=False
308
+ If true, performs a cascade delete.
309
+
310
+ Returns
311
+ -------
312
+ None
313
+
314
+ Raises
315
+ ------
316
+ PyegeriaException
317
+ If there are issues in communications, message format, or Egeria errors.
318
+
319
+ Notes
320
+ -----
321
+ Sample JSON body:
322
+ ```json
323
+ {
324
+ "class": "DeleteElementRequestBody",
325
+ "cascadedDelete": false
326
+ }
327
+ ```
328
+ """
329
+ if body is None:
330
+ body = {"class": "DeleteElementRequestBody"}
331
+ url = f"{self.product_manager_command_root}/collections/{digital_product_guid}/delete"
332
+ await self._async_delete_element_request(url, body, cascade)
333
+ logger.info(f"Deleted digital product {digital_product_guid} with cascade {cascade}")
334
+
335
+ def delete_digital_product(
336
+ self,
337
+ digital_product_guid: str,
338
+ body: Optional[dict | DeleteElementRequestBody] = None,
339
+ cascade: bool = False,
340
+ ) -> None:
341
+ """Delete a digital product.
342
+
343
+ Parameters
344
+ ----------
345
+ digital_product_guid : str
346
+ The GUID of the digital product to delete.
347
+ body : dict | DeleteElementRequestBody, optional
348
+ Request body for deletion.
349
+ cascade : bool, optional, default=False
350
+ If true, performs a cascade delete.
351
+
352
+ Returns
353
+ -------
354
+ None
355
+
356
+ Raises
357
+ ------
358
+ PyegeriaException
359
+ If there are issues in communications, message format, or Egeria errors.
360
+
361
+ Notes
362
+ -----
363
+ Sample JSON body:
364
+ ```json
365
+ {
366
+ "class": "DeleteElementRequestBody",
367
+ "cascadedDelete": false
368
+ }
369
+ ```
370
+ """
371
+ loop = asyncio.get_event_loop()
372
+ loop.run_until_complete(
373
+ self._async_delete_digital_product(digital_product_guid, body, cascade)
374
+ )
375
+
376
+ @dynamic_catch
377
+ async def _async_get_digital_product_by_guid(
378
+ self,
379
+ digital_product_guid: str,
380
+ body: Optional[dict] = None,
381
+ output_format: str = "JSON",
382
+ report_spec: Optional[str | dict] = None,
383
+ ) -> dict | str:
384
+ """Return the properties of a specific digital product. Async version.
385
+
386
+ Parameters
387
+ ----------
388
+ digital_product_guid : str
389
+ Unique identifier of the digital product.
390
+ body : dict, optional
391
+ Full request body.
392
+ output_format : str, default="JSON"
393
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
394
+ report_spec : str | dict, optional
395
+ The desired output columns/fields to include.
396
+
397
+ Returns
398
+ -------
399
+ dict | str
400
+ A JSON dict representing the specified digital product.
401
+
402
+ Raises
403
+ ------
404
+ PyegeriaException
405
+ If there are issues in communications, message format, or Egeria errors.
406
+
407
+ Notes
408
+ -----
409
+ Body sample:
410
+ {
411
+ "class": "GetRequestBody",
412
+ "asOfTime": "{{$isoTimestamp}}",
413
+ "effectiveTime": "{{$isoTimestamp}}",
414
+ "forLineage": false,
415
+ "forDuplicateProcessing": false
416
+ }
417
+ """
418
+ url = f"{self.product_manager_command_root}/collections/{digital_product_guid}/retrieve"
419
+ response = await self._async_get_guid_request(
420
+ url,
421
+ _type="DigitalProduct",
422
+ _gen_output=self._generate_collection_output,
423
+ output_format=output_format,
424
+ report_spec=report_spec,
425
+ body=body,
426
+ )
427
+ return response
428
+
429
+ def get_digital_product_by_guid(
430
+ self,
431
+ digital_product_guid: str,
432
+ body: Optional[dict] = None,
433
+ output_format: str = "JSON",
434
+ report_spec: Optional[str | dict] = None,
435
+ ) -> dict | str:
436
+ """Return the properties of a specific digital product. Sync version.
437
+
438
+ Parameters
439
+ ----------
440
+ digital_product_guid : str
441
+ Unique identifier of the digital product.
442
+ body : dict, optional
443
+ Full request body.
444
+ output_format : str, default="JSON"
445
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
446
+ report_spec : str | dict, optional
447
+ The desired output columns/fields to include.
448
+
449
+ Returns
450
+ -------
451
+ dict | str
452
+ A JSON dict representing the specified digital product.
453
+
454
+ Raises
455
+ ------
456
+ PyegeriaException
457
+ If there are issues in communications, message format, or Egeria errors.
458
+ """
459
+ loop = asyncio.get_event_loop()
460
+ return loop.run_until_complete(
461
+ self._async_get_digital_product_by_guid(
462
+ digital_product_guid, body, output_format, report_spec
463
+ )
464
+ )
465
+
466
+ @dynamic_catch
467
+ async def _async_get_digital_products_by_name(
468
+ self,
469
+ filter_string: str,
470
+ classification_names: Optional[list[str]] = None,
471
+ body: Optional[dict] = None,
472
+ start_from: int = 0,
473
+ page_size: int = 0,
474
+ output_format: str = "JSON",
475
+ report_spec: Optional[str | dict] = None,
476
+ ) -> list | str:
477
+ """Returns the list of digital products with a particular name. Async version.
478
+
479
+ Parameters
480
+ ----------
481
+ filter_string : str
482
+ Name to use to find matching digital products.
483
+ classification_names : list[str], optional
484
+ List of classification names to filter on.
485
+ body : dict, optional
486
+ Provides a full request body. If specified, supersedes the filter_string parameter.
487
+ start_from : int, default=0
488
+ When multiple pages of results are available, the page number to start from.
489
+ page_size : int, default=0
490
+ The number of items to return in a single page.
491
+ output_format : str, default="JSON"
492
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
493
+ report_spec : str | dict, optional
494
+ The desired output columns/fields to include.
495
+
496
+ Returns
497
+ -------
498
+ list | str
499
+ A list of digital products matching the name.
500
+
501
+ Raises
502
+ ------
503
+ PyegeriaException
504
+ If there are issues in communications, message format, or Egeria errors.
505
+ """
506
+ url = f"{self.product_manager_command_root}/collections/by-name"
507
+ response = await self._async_get_name_request(
508
+ url,
509
+ _type="DigitalProduct",
510
+ _gen_output=self._generate_collection_output,
511
+ filter_string=filter_string,
512
+ classification_names=classification_names,
513
+ start_from=start_from,
514
+ page_size=page_size,
515
+ output_format=output_format,
516
+ report_spec=report_spec,
517
+ body=body,
518
+ )
519
+ return response
520
+
521
+ def get_digital_products_by_name(
522
+ self,
523
+ filter_string: str,
524
+ classification_names: Optional[list[str]] = None,
525
+ body: Optional[dict] = None,
526
+ start_from: int = 0,
527
+ page_size: int = 0,
528
+ output_format: str = "JSON",
529
+ report_spec: Optional[str | dict] = None,
530
+ ) -> list | str:
531
+ """Returns the list of digital products with a particular name. Sync version.
532
+
533
+ Parameters
534
+ ----------
535
+ filter_string : str
536
+ Name to use to find matching digital products.
537
+ classification_names : list[str], optional
538
+ List of classification names to filter on.
539
+ body : dict, optional
540
+ Provides a full request body. If specified, supersedes the filter_string parameter.
541
+ start_from : int, default=0
542
+ When multiple pages of results are available, the page number to start from.
543
+ page_size : int, default=0
544
+ The number of items to return in a single page.
545
+ output_format : str, default="JSON"
546
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
547
+ report_spec : str | dict, optional
548
+ The desired output columns/fields to include.
549
+
550
+ Returns
551
+ -------
552
+ list | str
553
+ A list of digital products matching the name.
554
+
555
+ Raises
556
+ ------
557
+ PyegeriaException
558
+ If there are issues in communications, message format, or Egeria errors.
559
+ """
560
+ loop = asyncio.get_event_loop()
561
+ return loop.run_until_complete(
562
+ self._async_get_digital_products_by_name(
563
+ filter_string, classification_names, body, start_from, page_size, output_format, report_spec
564
+ )
565
+ )
566
+
567
+ @dynamic_catch
568
+ async def _async_find_digital_products(
569
+ self,
570
+ search_string: str = "*",
571
+ starts_with: bool = True,
572
+ ends_with: bool = False,
573
+ ignore_case: bool = False,
574
+ anchor_domain: Optional[str] = None,
575
+ metadata_element_type: Optional[str] = None,
576
+ metadata_element_subtype: Optional[list[str]] = None,
577
+ skip_relationships: Optional[list[str]] = None,
578
+ include_only_relationships: Optional[list[str]] = None,
579
+ skip_classified_elements: Optional[list[str]] = None,
580
+ include_only_classified_elements: Optional[list[str]] = None,
581
+ graph_query_depth: int = 3,
582
+ governance_zone_filter: Optional[list[str]] = None,
583
+ as_of_time: Optional[str] = None,
584
+ effective_time: Optional[str] = None,
585
+ relationship_page_size: int = 0,
586
+ limit_results_by_status: Optional[list[str]] = None,
587
+ sequencing_order: Optional[str] = None,
588
+ sequencing_property: Optional[str] = None,
589
+ start_from: int = 0,
590
+ page_size: int = 100,
591
+ output_format: str = "JSON",
592
+ report_spec: Optional[str | dict] = None,
593
+ property_names: Optional[list[str]] = None,
594
+ body: Optional[dict] = None,
595
+ ) -> list | str:
596
+ """Returns the list of digital products matching the search string. Async version.
597
+
598
+ Parameters
599
+ ----------
600
+ search_string : str, default="*"
601
+ Search string to match against. '*' matches all digital products.
602
+ starts_with : bool, default=True
603
+ Starts with the supplied string.
604
+ ends_with : bool, default=False
605
+ Ends with the supplied string.
606
+ ignore_case : bool, default=False
607
+ Ignore case when searching.
608
+ anchor_domain : str, optional
609
+ Anchor domain to filter on.
610
+ metadata_element_type : str, optional
611
+ Metadata element type name to filter on.
612
+ metadata_element_subtype : list[str], optional
613
+ List of metadata element subtypes to filter on.
614
+ skip_relationships : list[str], optional
615
+ List of relationship types to skip.
616
+ include_only_relationships : list[str], optional
617
+ List of relationship types to include only.
618
+ skip_classified_elements : list[str], optional
619
+ List of classification names to skip.
620
+ include_only_classified_elements : list[str], optional
621
+ List of classification names to include only.
622
+ graph_query_depth : int, default=3
623
+ Depth of graph query.
624
+ governance_zone_filter : list[str], optional
625
+ List of governance zones to filter on.
626
+ as_of_time : str, optional
627
+ Time for historical queries.
628
+ effective_time : str, optional
629
+ Effective time for the query.
630
+ relationship_page_size : int, default=0
631
+ Page size for relationships.
632
+ limit_results_by_status : list[str], optional
633
+ List of statuses to limit results by.
634
+ sequencing_order : str, optional
635
+ Sequencing order for results.
636
+ sequencing_property : str, optional
637
+ Property to sequence by.
638
+ start_from : int, default=0
639
+ When multiple pages of results are available, the page number to start from.
640
+ page_size : int, default=100
641
+ The number of items to return in a single page.
642
+ output_format : str, default="JSON"
643
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
644
+ report_spec : str | dict, optional
645
+ The desired output columns/fields to include.
646
+ property_names: list[str], optional
647
+ The names of properties to search for.
648
+ body : dict, optional
649
+ If provided, the search parameters in the body supersede other attributes.
650
+
651
+ Returns
652
+ -------
653
+ list | str
654
+ Output depends on the output format specified.
655
+
656
+ Raises
657
+ ------
658
+ PyegeriaException
659
+ If there are issues in communications, message format, or Egeria errors.
660
+ """
661
+ if metadata_element_subtype is None:
662
+ metadata_element_subtype = ["DigitalProduct"]
663
+
664
+ url = f"{self.product_manager_command_root}/collections/by-search-string"
665
+ response = await self._async_find_request(
666
+ url,
667
+ _type="DigitalProduct",
668
+ _gen_output=self._generate_collection_output,
669
+ search_string=search_string,
670
+ starts_with=starts_with,
671
+ ends_with=ends_with,
672
+ ignore_case=ignore_case,
673
+ anchor_domain=anchor_domain,
674
+ metadata_element_type=metadata_element_type,
675
+ metadata_element_subtypes=metadata_element_subtype,
676
+ skip_relationships=skip_relationships,
677
+ include_only_relationships=include_only_relationships,
678
+ skip_classified_elements=skip_classified_elements,
679
+ include_only_classified_elements=include_only_classified_elements,
680
+ graph_query_depth=graph_query_depth,
681
+ governance_zone_filter=governance_zone_filter,
682
+ as_of_time=as_of_time,
683
+ effective_time=effective_time,
684
+ relationship_page_size=relationship_page_size,
685
+ limit_results_by_status=limit_results_by_status,
686
+ sequencing_order=sequencing_order,
687
+ sequencing_property=sequencing_property,
688
+ start_from=start_from,
689
+ page_size=page_size,
690
+ output_format=output_format,
691
+ report_spec=report_spec,
692
+ property_names=property_names,
693
+ body=body,
694
+ )
695
+ return response
696
+
697
+ def find_digital_products(
698
+ self,
699
+ search_string: str = "*",
700
+ starts_with: bool = True,
701
+ ends_with: bool = False,
702
+ ignore_case: bool = False,
703
+ anchor_domain: Optional[str] = None,
704
+ metadata_element_type: Optional[str] = None,
705
+ metadata_element_subtype: Optional[list[str]] = None,
706
+ skip_relationships: Optional[list[str]] = None,
707
+ include_only_relationships: Optional[list[str]] = None,
708
+ skip_classified_elements: Optional[list[str]] = None,
709
+ include_only_classified_elements: Optional[list[str]] = None,
710
+ graph_query_depth: int = 3,
711
+ governance_zone_filter: Optional[list[str]] = None,
712
+ as_of_time: Optional[str] = None,
713
+ effective_time: Optional[str] = None,
714
+ relationship_page_size: int = 0,
715
+ limit_results_by_status: Optional[list[str]] = None,
716
+ sequencing_order: Optional[str] = None,
717
+ sequencing_property: Optional[str] = None,
718
+ start_from: int = 0,
719
+ page_size: int = 100,
720
+ output_format: str = "JSON",
721
+ report_spec: Optional[str | dict] = None,
722
+ property_names: Optional[list[str]] = None,
723
+ body: Optional[dict] = None,
724
+ ) -> list | str:
725
+ """Returns the list of digital products matching the search string. Sync version.
726
+
727
+ Parameters
728
+ ----------
729
+ search_string : str, default="*"
730
+ Search string to match against. '*' matches all digital products.
731
+ starts_with : bool, default=True
732
+ Starts with the supplied string.
733
+ ends_with : bool, default=False
734
+ Ends with the supplied string.
735
+ ignore_case : bool, default=False
736
+ Ignore case when searching.
737
+ anchor_domain : str, optional
738
+ Anchor domain to filter on.
739
+ metadata_element_type : str, optional
740
+ Metadata element type name to filter on.
741
+ metadata_element_subtype : list[str], optional
742
+ List of metadata element subtypes to filter on.
743
+ skip_relationships : list[str], optional
744
+ List of relationship types to skip.
745
+ include_only_relationships : list[str], optional
746
+ List of relationship types to include only.
747
+ skip_classified_elements : list[str], optional
748
+ List of classification names to skip.
749
+ include_only_classified_elements : list[str], optional
750
+ List of classification names to include only.
751
+ graph_query_depth : int, default=3
752
+ Depth of graph query.
753
+ governance_zone_filter : list[str], optional
754
+ List of governance zones to filter on.
755
+ as_of_time : str, optional
756
+ Time for historical queries.
757
+ effective_time : str, optional
758
+ Effective time for the query.
759
+ relationship_page_size : int, default=0
760
+ Page size for relationships.
761
+ limit_results_by_status : list[str], optional
762
+ List of statuses to limit results by.
763
+ sequencing_order : str, optional
764
+ Sequencing order for results.
765
+ sequencing_property : str, optional
766
+ Property to sequence by.
767
+ start_from : int, default=0
768
+ When multiple pages of results are available, the page number to start from.
769
+ page_size : int, default=100
770
+ The number of items to return in a single page.
771
+ output_format : str, default="JSON"
772
+ One of "JSON", "DICT", "MD", "FORM", "REPORT", or "MERMAID".
773
+ report_spec : str | dict, optional
774
+ The desired output columns/fields to include.
775
+ property_names: list[str], optional
776
+ The names of properties to search for.
777
+ body : dict, optional
778
+ If provided, the search parameters in the body supersede other attributes.
779
+
780
+ Returns
781
+ -------
782
+ list | str
783
+ Output depends on the output format specified.
784
+
785
+ Raises
786
+ ------
787
+ PyegeriaException
788
+ If there are issues in communications, message format, or Egeria errors.
789
+ """
790
+ loop = asyncio.get_event_loop()
791
+ return loop.run_until_complete(
792
+ self._async_find_digital_products(
793
+ search_string,
794
+ starts_with,
795
+ ends_with,
796
+ ignore_case,
797
+ anchor_domain,
798
+ metadata_element_type,
799
+ metadata_element_subtype,
800
+ skip_relationships,
801
+ include_only_relationships,
802
+ skip_classified_elements,
803
+ include_only_classified_elements,
804
+ graph_query_depth,
805
+ governance_zone_filter,
806
+ as_of_time,
807
+ effective_time,
808
+ relationship_page_size,
809
+ limit_results_by_status,
810
+ sequencing_order,
811
+ sequencing_property,
812
+ start_from,
813
+ page_size,
814
+ output_format,
815
+ report_spec,
816
+ property_names,
817
+ body,
818
+ )
819
+ )
820
+
821
+ #
822
+ # Digital Product Dependency Management
823
+ #
824
+
825
+ @dynamic_catch
826
+ async def _async_link_digital_product_dependency(
827
+ self,
828
+ consumer_product_guid: str,
829
+ consumed_product_guid: str,
830
+ body: Optional[dict | NewRelationshipRequestBody] = None,
831
+ ) -> None:
832
+ """Link two dependent digital products. Async version.
833
+
834
+ Parameters
835
+ ----------
836
+ consumer_product_guid : str
837
+ The GUID of the digital product that consumes another.
838
+ consumed_product_guid : str
839
+ The GUID of the digital product being consumed.
840
+ body : dict | NewRelationshipRequestBody, optional
841
+ Request body containing relationship properties.
842
+
843
+ Returns
844
+ -------
845
+ None
846
+
847
+ Raises
848
+ ------
849
+ PyegeriaException
850
+ If there are issues in communications, message format, or Egeria errors.
851
+
852
+ Notes
853
+ -----
854
+ Sample JSON body:
855
+ ```json
856
+ {
857
+ "class" : "NewRelationshipRequestBody",
858
+ "properties": {
859
+ "class": "DigitalProductDependencyProperties",
860
+ "label": "add label here",
861
+ "description": "add description here"
862
+ }
863
+ }
864
+ ```
865
+ """
866
+ url = (
867
+ f"{self.product_manager_command_root}/digital-products/"
868
+ f"{consumer_product_guid}/product-dependencies/{consumed_product_guid}/attach"
869
+ )
870
+ await self._async_new_relationship_request(url, ["DigitalProductDependencyProperties"], body)
871
+ logger.info(f"Linked {consumed_product_guid} -> {consumer_product_guid}")
872
+
873
+ def link_digital_product_dependency(
874
+ self,
875
+ consumer_product_guid: str,
876
+ consumed_product_guid: str,
877
+ body: Optional[dict | NewRelationshipRequestBody] = None,
878
+ ) -> None:
879
+ """Link two dependent digital products.
880
+
881
+ Parameters
882
+ ----------
883
+ consumer_product_guid : str
884
+ The GUID of the digital product that consumes another.
885
+ consumed_product_guid : str
886
+ The GUID of the digital product being consumed.
887
+ body : dict | NewRelationshipRequestBody, optional
888
+ Request body containing relationship properties.
889
+
890
+ Returns
891
+ -------
892
+ None
893
+
894
+ Raises
895
+ ------
896
+ PyegeriaException
897
+ If there are issues in communications, message format, or Egeria errors.
898
+
899
+ Notes
900
+ -----
901
+ Sample JSON body:
902
+ ```json
903
+ {
904
+ "class" : "NewRelationshipRequestBody",
905
+ "properties": {
906
+ "class": "DigitalProductDependencyProperties",
907
+ "label": "add label here",
908
+ "description": "add description here"
909
+ }
910
+ }
911
+ ```
912
+ """
913
+ loop = asyncio.get_event_loop()
914
+ loop.run_until_complete(
915
+ self._async_link_digital_product_dependency(
916
+ consumer_product_guid, consumed_product_guid, body
917
+ )
918
+ )
919
+
920
+ @dynamic_catch
921
+ async def _async_detach_digital_product_dependency(
922
+ self,
923
+ consumer_product_guid: str,
924
+ consumed_product_guid: str,
925
+ body: Optional[dict | DeleteRelationshipRequestBody] = None,
926
+ ) -> None:
927
+ """Unlink dependent digital products. Async version.
928
+
929
+ Parameters
930
+ ----------
931
+ consumer_product_guid : str
932
+ The GUID of the consumer digital product.
933
+ consumed_product_guid : str
934
+ The GUID of the consumed digital product to detach.
935
+ body : dict | DeleteRelationshipRequestBody, optional
936
+ Request body for deletion.
937
+
938
+ Returns
939
+ -------
940
+ None
941
+
942
+ Raises
943
+ ------
944
+ PyegeriaException
945
+ If there are issues in communications, message format, or Egeria errors.
946
+
947
+ Notes
948
+ -----
949
+ Sample JSON body:
950
+ ```json
951
+ {
952
+ "class" : "DeleteRelationshipRequestBody"
953
+ }
954
+ ```
955
+ """
956
+ url = (
957
+ f"{self.product_manager_command_root}/digital-products/"
958
+ f"{consumer_product_guid}/product-dependencies/{consumed_product_guid}/detach"
959
+ )
960
+ await self._async_delete_relationship_request(url, body)
961
+ logger.info(f"Detached digital product dependency {consumer_product_guid} -> {consumed_product_guid}")
962
+
963
+ def detach_digital_product_dependency(
964
+ self,
965
+ consumer_product_guid: str,
966
+ consumed_product_guid: str,
967
+ body: Optional[dict | DeleteRelationshipRequestBody] = None,
968
+ ) -> None:
969
+ """Unlink dependent digital products.
970
+
971
+ Parameters
972
+ ----------
973
+ consumer_product_guid : str
974
+ The GUID of the consumer digital product.
975
+ consumed_product_guid : str
976
+ The GUID of the consumed digital product to detach.
977
+ body : dict | DeleteRelationshipRequestBody, optional
978
+ Request body for deletion.
979
+
980
+ Returns
981
+ -------
982
+ None
983
+
984
+ Raises
985
+ ------
986
+ PyegeriaException
987
+ If there are issues in communications, message format, or Egeria errors.
988
+
989
+ Notes
990
+ -----
991
+ Sample JSON body:
992
+ ```json
993
+ {
994
+ "class" : "DeleteRelationshipRequestBody"
995
+ }
996
+ ```
997
+ """
998
+ loop = asyncio.get_event_loop()
999
+ loop.run_until_complete(
1000
+ self._async_detach_digital_product_dependency(
1001
+ consumer_product_guid, consumed_product_guid, body
1002
+ )
1003
+ )
1004
+
1005
+ #
1006
+ # Product Manager Role Management
1007
+ #
1008
+
1009
+ @dynamic_catch
1010
+ async def _async_link_product_manager(
1011
+ self,
1012
+ digital_product_guid: str,
1013
+ product_manager_role_guid: str,
1014
+ body: Optional[dict | NewRelationshipRequestBody] = None,
1015
+ ) -> None:
1016
+ """Attach a product manager role to a digital product. Async version.
1017
+
1018
+ Parameters
1019
+ ----------
1020
+ digital_product_guid : str
1021
+ The GUID of the digital product.
1022
+ product_manager_role_guid : str
1023
+ The GUID of the product manager role.
1024
+ body : dict | NewRelationshipRequestBody, optional
1025
+ Request body containing relationship properties.
1026
+
1027
+ Returns
1028
+ -------
1029
+ None
1030
+
1031
+ Raises
1032
+ ------
1033
+ PyegeriaException
1034
+ If there are issues in communications, message format, or Egeria errors.
1035
+
1036
+ Notes
1037
+ -----
1038
+ Sample JSON body:
1039
+ ```json
1040
+ {
1041
+ "class": "NewRelationshipRequestBody",
1042
+ "properties": {
1043
+ "class" : "AssignmentScopeProperties",
1044
+ "assignmentType": "Product Manager",
1045
+ "description": "The person or role responsible for the product"
1046
+ }
1047
+ }
1048
+ ```
1049
+ """
1050
+ url = (
1051
+ f"{self.product_manager_command_root}/digital-products/"
1052
+ f"{digital_product_guid}/product-managers/{product_manager_role_guid}/attach"
1053
+ )
1054
+ await self._async_new_relationship_request(url, ["AssignmentScopeProperties"], body)
1055
+ logger.info(f"Attached digital product manager {digital_product_guid} -> {product_manager_role_guid}")
1056
+
1057
+ def link_product_manager(
1058
+ self,
1059
+ digital_product_guid: str,
1060
+ product_manager_role_guid: str,
1061
+ body: Optional[dict | NewRelationshipRequestBody] = None,
1062
+ ) -> None:
1063
+ """Attach a product manager role to a digital product.
1064
+
1065
+ Parameters
1066
+ ----------
1067
+ digital_product_guid : str
1068
+ The GUID of the digital product.
1069
+ product_manager_role_guid : str
1070
+ The GUID of the product manager role.
1071
+ body : dict | NewRelationshipRequestBody, optional
1072
+ Request body containing relationship properties.
1073
+
1074
+ Returns
1075
+ -------
1076
+ None
1077
+
1078
+ Raises
1079
+ ------
1080
+ PyegeriaException
1081
+ If there are issues in communications, message format, or Egeria errors.
1082
+
1083
+ Notes
1084
+ -----
1085
+ Sample JSON body:
1086
+ ```json
1087
+ {
1088
+ "class": "NewRelationshipRequestBody",
1089
+ "properties": {
1090
+ "class" : "AssignmentScopeProperties",
1091
+ "assignmentType": "Product Manager",
1092
+ "description": "The person or role responsible for the product"
1093
+ }
1094
+ }
1095
+ ```
1096
+ """
1097
+ loop = asyncio.get_event_loop()
1098
+ loop.run_until_complete(
1099
+ self._async_link_product_manager(
1100
+ digital_product_guid, product_manager_role_guid, body
1101
+ )
1102
+ )
1103
+
1104
+ @dynamic_catch
1105
+ async def _async_detach_product_manager(
1106
+ self,
1107
+ digital_product_guid: str,
1108
+ product_manager_role_guid: str,
1109
+ body: Optional[dict | DeleteRelationshipRequestBody] = None,
1110
+ ) -> None:
1111
+ """Detach a product manager from a digital product. Async version.
1112
+
1113
+ Parameters
1114
+ ----------
1115
+ digital_product_guid : str
1116
+ The GUID of the digital product.
1117
+ product_manager_role_guid : str
1118
+ The GUID of the product manager role to detach.
1119
+ body : dict | DeleteRelationshipRequestBody, optional
1120
+ Request body for deletion.
1121
+
1122
+ Returns
1123
+ -------
1124
+ None
1125
+
1126
+ Raises
1127
+ ------
1128
+ PyegeriaException
1129
+ If there are issues in communications, message format, or Egeria errors.
1130
+
1131
+ Notes
1132
+ -----
1133
+ Sample JSON body:
1134
+ ```json
1135
+ {
1136
+ "class" : "DeleteRelationshipRequestBody"
1137
+ }
1138
+ ```
1139
+ """
1140
+ url = (
1141
+ f"{self.product_manager_command_root}/digital-products/"
1142
+ f"{digital_product_guid}/product-managers/{product_manager_role_guid}/detach"
1143
+ )
1144
+ await self._async_delete_relationship_request(url, body)
1145
+ logger.info(f"Detached digital product manager {digital_product_guid} -> {product_manager_role_guid}")
1146
+
1147
+ def detach_product_manager(
1148
+ self,
1149
+ digital_product_guid: str,
1150
+ product_manager_role_guid: str,
1151
+ body: Optional[dict | DeleteRelationshipRequestBody] = None,
1152
+ ) -> None:
1153
+ """Detach a product manager from a digital product.
1154
+
1155
+ Parameters
1156
+ ----------
1157
+ digital_product_guid : str
1158
+ The GUID of the digital product.
1159
+ product_manager_role_guid : str
1160
+ The GUID of the product manager role to detach.
1161
+ body : dict | DeleteRelationshipRequestBody, optional
1162
+ Request body for deletion.
1163
+
1164
+ Returns
1165
+ -------
1166
+ None
1167
+
1168
+ Raises
1169
+ ------
1170
+ PyegeriaException
1171
+ If there are issues in communications, message format, or Egeria errors.
1172
+
1173
+ Notes
1174
+ -----
1175
+ Sample JSON body:
1176
+ ```json
1177
+ {
1178
+ "class" : "DeleteRelationshipRequestBody"
1179
+ }
1180
+ ```
1181
+ """
1182
+ loop = asyncio.get_event_loop()
1183
+ loop.run_until_complete(
1184
+ self._async_detach_product_manager(
1185
+ digital_product_guid, product_manager_role_guid, body
1186
+ )
1187
+ )
1188
+
1189
+ #
1190
+ # Digital Product Catalog Management
1191
+ #
1192
+
1193
+ @dynamic_catch
1194
+ async def _async_create_digital_product_catalog(
1195
+ self,
1196
+ body: Optional[dict | NewElementRequestBody] = None,
1197
+ ) -> str:
1198
+ """Create a new digital product catalog collection. Async version.
1199
+
1200
+ Parameters
1201
+ ----------
1202
+ body : dict | NewElementRequestBody, optional
1203
+ Request body containing digital product catalog properties.
1204
+
1205
+ Returns
1206
+ -------
1207
+ str
1208
+ The GUID of the created digital product catalog.
1209
+
1210
+ Raises
1211
+ ------
1212
+ PyegeriaException
1213
+ If there are issues in communications, message format, or Egeria errors.
1214
+ ValidationError
1215
+ If the body does not conform to NewElementRequestBody.
1216
+ PyegeriaNotAuthorizedException
1217
+ If the user is not authorized for the requested action.
1218
+
1219
+ Notes
1220
+ -----
1221
+ JSON Structure looks like:
1222
+ {
1223
+ "class" : "NewElementRequestBody",
1224
+ "typeName": "DigitalProductCatalog",
1225
+ "isOwnAnchor" : true,
1226
+ "anchorScopeGUID" : "optional GUID of search scope",
1227
+ "parentGUID" : "xxx",
1228
+ "parentRelationshipTypeName" : "CollectionMembership",
1229
+ "parentAtEnd1": true,
1230
+ "properties": {
1231
+ "class" : "CatalogProperties",
1232
+ "qualifiedName": "DigitalProductCatalog::Add catalog name here",
1233
+ "displayName" : "Catalog name",
1234
+ "description" : "Add description of catalog here",
1235
+ "additionalProperties": {
1236
+ "property1Name" : "property1Value",
1237
+ "property2Name" : "property2Value"
1238
+ }
1239
+ },
1240
+ "externalSourceGUID": "add guid here",
1241
+ "externalSourceName": "add qualified name here",
1242
+ "effectiveTime" : "timestamp",
1243
+ "forLineage" : false,
1244
+ "forDuplicateProcessing" : false,
1245
+ }
1246
+ """
1247
+ url = f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/product-manager/collections"
1248
+ return await self._async_create_element_body_request(url, ["CatalogProperties"], body)
1249
+
1250
+ def create_digital_product_catalog(
1251
+ self,
1252
+ body: Optional[dict | NewElementRequestBody] = None,
1253
+ ) -> str:
1254
+ """Create a new digital product catalog collection. Sync version.
1255
+
1256
+ Parameters
1257
+ ----------
1258
+ body : dict | NewElementRequestBody, optional
1259
+ Request body containing digital product catalog properties.
1260
+
1261
+ Returns
1262
+ -------
1263
+ str
1264
+ The GUID of the created digital product catalog.
1265
+
1266
+ Raises
1267
+ ------
1268
+ PyegeriaException
1269
+ If there are issues in communications, message format, or Egeria errors.
1270
+ """
1271
+ body = self._prepare_body(body)
1272
+ loop = asyncio.get_event_loop()
1273
+ return loop.run_until_complete(self._async_create_digital_product_catalog(body))
1274
+
1275
+ @dynamic_catch
1276
+ async def _async_update_digital_product_catalog(
1277
+ self,
1278
+ digital_product_catalog_guid: str,
1279
+ body: Optional[dict | UpdateElementRequestBody] = None,
1280
+ ) -> None:
1281
+ """Update the properties of a digital product catalog. Async version.
1282
+
1283
+ Parameters
1284
+ ----------
1285
+ digital_product_catalog_guid : str
1286
+ The GUID of the digital product catalog to update.
1287
+ body : dict | UpdateElementRequestBody, optional
1288
+ Request body containing updated properties.
1289
+
1290
+ Returns
1291
+ -------
1292
+ None
1293
+
1294
+ Raises
1295
+ ------
1296
+ PyegeriaException
1297
+ If there are issues in communications, message format, or Egeria errors.
1298
+ ValidationError
1299
+ If the body does not conform to UpdateElementRequestBody.
1300
+ PyegeriaNotAuthorizedException
1301
+ If the user is not authorized for the requested action.
1302
+ """
1303
+ url = (
1304
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/"
1305
+ f"product-manager/collections/{digital_product_catalog_guid}/update"
1306
+ )
1307
+ await self._async_update_element_body_request(url, ["CatalogProperties"], body)
1308
+
1309
+ def update_digital_product_catalog(
1310
+ self,
1311
+ digital_product_catalog_guid: str,
1312
+ body: Optional[dict | UpdateElementRequestBody] = None,
1313
+ ) -> None:
1314
+ """Update the properties of a digital product catalog. Sync version.
1315
+
1316
+ Parameters
1317
+ ----------
1318
+ digital_product_catalog_guid : str
1319
+ The GUID of the digital product catalog to update.
1320
+ body : dict | UpdateElementRequestBody, optional
1321
+ Request body containing updated properties.
1322
+
1323
+ Returns
1324
+ -------
1325
+ None
1326
+
1327
+ Raises
1328
+ ------
1329
+ PyegeriaException
1330
+ If there are issues in communications, message format, or Egeria errors.
1331
+ """
1332
+ digital_product_catalog_guid = str(digital_product_catalog_guid)
1333
+ body = self._prepare_body(body)
1334
+ loop = asyncio.get_event_loop()
1335
+ loop.run_until_complete(
1336
+ self._async_update_digital_product_catalog(digital_product_catalog_guid, body)
1337
+ )
1338
+
1339
+ @dynamic_catch
1340
+ async def _async_delete_digital_product_catalog(
1341
+ self,
1342
+ digital_product_catalog_guid: str,
1343
+ body: Optional[dict | DeleteElementRequestBody] = None,
1344
+ cascade: bool = False,
1345
+ ) -> None:
1346
+ """Delete a digital product catalog. Async version.
1347
+
1348
+ Parameters
1349
+ ----------
1350
+ digital_product_catalog_guid : str
1351
+ The GUID of the digital product catalog to delete.
1352
+ body : dict | DeleteElementRequestBody, optional
1353
+ Request body for deletion.
1354
+ cascade : bool, optional
1355
+ Whether to cascade the delete. Defaults to False.
1356
+
1357
+ Returns
1358
+ -------
1359
+ None
1360
+
1361
+ Raises
1362
+ ------
1363
+ PyegeriaException
1364
+ If there are issues in communications, message format, or Egeria errors.
1365
+ ValidationError
1366
+ If the body does not conform to DeleteElementRequestBody.
1367
+ PyegeriaNotAuthorizedException
1368
+ If the user is not authorized for the requested action.
1369
+ """
1370
+ url = (
1371
+ f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/"
1372
+ f"product-manager/collections/{digital_product_catalog_guid}/delete"
1373
+ )
1374
+ await self._async_delete_element_request(url, body, cascade)
1375
+
1376
+ def delete_digital_product_catalog(
1377
+ self,
1378
+ digital_product_catalog_guid: str,
1379
+ body: Optional[dict | DeleteElementRequestBody] = None,
1380
+ cascade: bool = False,
1381
+ ) -> None:
1382
+ """Delete a digital product catalog. Sync version.
1383
+
1384
+ Parameters
1385
+ ----------
1386
+ digital_product_catalog_guid : str
1387
+ The GUID of the digital product catalog to delete.
1388
+ body : dict | DeleteElementRequestBody, optional
1389
+ Request body for deletion.
1390
+ cascade : bool, optional
1391
+ Whether to cascade the delete. Defaults to False.
1392
+
1393
+ Returns
1394
+ -------
1395
+ None
1396
+
1397
+ Raises
1398
+ ------
1399
+ PyegeriaException
1400
+ If there are issues in communications, message format, or Egeria errors.
1401
+ """
1402
+ digital_product_catalog_guid = str(digital_product_catalog_guid)
1403
+ body = self._prepare_body(body)
1404
+ cascade = bool(cascade)
1405
+ loop = asyncio.get_event_loop()
1406
+ loop.run_until_complete(
1407
+ self._async_delete_digital_product_catalog(digital_product_catalog_guid, body, cascade)
1408
+ )
1409
+
1410
+ @dynamic_catch
1411
+ async def _async_get_digital_product_catalog_by_guid(
1412
+ self,
1413
+ digital_product_catalog_guid: str,
1414
+ body: Optional[dict] = None,
1415
+ output_format: str = "JSON",
1416
+ report_spec: Optional[str | dict] = None,
1417
+ ) -> dict | str:
1418
+ """Return the properties of a specific digital product catalog by GUID. Async version.
1419
+
1420
+ Parameters
1421
+ ----------
1422
+ digital_product_catalog_guid : str
1423
+ The GUID of the digital product catalog to retrieve.
1424
+ body : dict, optional
1425
+ Request body (typically empty for retrieval).
1426
+ output_format : str, optional
1427
+ Format for output. Defaults to "JSON".
1428
+ report_spec : str | dict, optional
1429
+ Report specification for formatting.
1430
+
1431
+ Returns
1432
+ -------
1433
+ dict | str
1434
+ The digital product catalog properties.
1435
+
1436
+ Raises
1437
+ ------
1438
+ PyegeriaException
1439
+ If there are issues in communications, message format, or Egeria errors.
1440
+ PyegeriaNotFoundException
1441
+ If the digital product catalog is not found.
1442
+ PyegeriaNotAuthorizedException
1443
+ If the user is not authorized for the requested action.
1444
+ """
1445
+ url = f"{self.product_manager_command_root}/collections/{digital_product_catalog_guid}/retrieve"
1446
+ response = await self._async_get_guid_request(
1447
+ url,
1448
+ _type="DigitalProductCatalog",
1449
+ _gen_output=None,
1450
+ output_format=output_format,
1451
+ report_spec=report_spec,
1452
+ body=body,
1453
+ )
1454
+ return response
1455
+
1456
+ def get_digital_product_catalog_by_guid(
1457
+ self,
1458
+ digital_product_catalog_guid: str,
1459
+ body: Optional[dict] = None,
1460
+ output_format: str = "JSON",
1461
+ report_spec: Optional[str | dict] = None,
1462
+ ) -> dict | str:
1463
+ """Return the properties of a specific digital product catalog by GUID. Sync version.
1464
+
1465
+ Parameters
1466
+ ----------
1467
+ digital_product_catalog_guid : str
1468
+ The GUID of the digital product catalog to retrieve.
1469
+ body : dict, optional
1470
+ Request body (typically empty for retrieval).
1471
+ output_format : str, optional
1472
+ Format for output. Defaults to "JSON".
1473
+ report_spec : str | dict, optional
1474
+ Report specification for formatting.
1475
+
1476
+ Returns
1477
+ -------
1478
+ dict | str
1479
+ The digital product catalog properties.
1480
+
1481
+ Raises
1482
+ ------
1483
+ PyegeriaException
1484
+ If there are issues in communications, message format, or Egeria errors.
1485
+ """
1486
+ loop = asyncio.get_event_loop()
1487
+ return loop.run_until_complete(
1488
+ self._async_get_digital_product_catalog_by_guid(
1489
+ digital_product_catalog_guid, body, output_format, report_spec
1490
+ )
1491
+ )
1492
+
1493
+ @dynamic_catch
1494
+ async def _async_get_digital_product_catalogs_by_name(
1495
+ self,
1496
+ filter_string: Optional[str] = None,
1497
+ classification_names: Optional[list[str]] = None,
1498
+ body: Optional[dict] = None,
1499
+ start_from: int = 0,
1500
+ page_size: int = 0,
1501
+ output_format: str = "JSON",
1502
+ report_spec: Optional[str | dict] = None,
1503
+ ) -> list | str:
1504
+ """Returns the list of digital product catalogs with a particular name. Async version.
1505
+
1506
+ Parameters
1507
+ ----------
1508
+ filter_string : str, optional
1509
+ Filter string to match against catalog names.
1510
+ classification_names : list[str], optional
1511
+ List of classification names to filter by.
1512
+ body : dict, optional
1513
+ Request body for additional filtering.
1514
+ start_from : int, optional
1515
+ Starting index for pagination. Defaults to 0.
1516
+ page_size : int, optional
1517
+ Number of results per page. Defaults to 0 (no limit).
1518
+ output_format : str, optional
1519
+ Format for output. Defaults to "JSON".
1520
+ report_spec : str | dict, optional
1521
+ Report specification for formatting.
1522
+
1523
+ Returns
1524
+ -------
1525
+ list | str
1526
+ List of digital product catalogs matching the criteria.
1527
+
1528
+ Raises
1529
+ ------
1530
+ PyegeriaException
1531
+ If there are issues in communications, message format, or Egeria errors.
1532
+ """
1533
+ url = f"{self.product_manager_command_root}/collections/by-name"
1534
+ response = await self._async_get_name_request(
1535
+ url,
1536
+ _type="DigitalProductCatalog",
1537
+ _gen_output=None,
1538
+ filter_string=filter_string,
1539
+ classification_names=classification_names,
1540
+ start_from=start_from,
1541
+ page_size=page_size,
1542
+ output_format=output_format,
1543
+ report_spec=report_spec,
1544
+ body=body,
1545
+ )
1546
+ return response
1547
+
1548
+ def get_digital_product_catalogs_by_name(
1549
+ self,
1550
+ filter_string: Optional[str] = None,
1551
+ classification_names: Optional[list[str]] = None,
1552
+ body: Optional[dict] = None,
1553
+ start_from: int = 0,
1554
+ page_size: int = 0,
1555
+ output_format: str = "JSON",
1556
+ report_spec: Optional[str | dict] = None,
1557
+ ) -> list | str:
1558
+ """Returns the list of digital product catalogs with a particular name. Sync version.
1559
+
1560
+ Parameters
1561
+ ----------
1562
+ filter_string : str, optional
1563
+ Filter string to match against catalog names.
1564
+ classification_names : list[str], optional
1565
+ List of classification names to filter by.
1566
+ body : dict, optional
1567
+ Request body for additional filtering.
1568
+ start_from : int, optional
1569
+ Starting index for pagination. Defaults to 0.
1570
+ page_size : int, optional
1571
+ Number of results per page. Defaults to 0 (no limit).
1572
+ output_format : str, optional
1573
+ Format for output. Defaults to "JSON".
1574
+ report_spec : str | dict, optional
1575
+ Report specification for formatting.
1576
+
1577
+ Returns
1578
+ -------
1579
+ list | str
1580
+ List of digital product catalogs matching the criteria.
1581
+
1582
+ Raises
1583
+ ------
1584
+ PyegeriaException
1585
+ If there are issues in communications, message format, or Egeria errors.
1586
+ """
1587
+ loop = asyncio.get_event_loop()
1588
+ return loop.run_until_complete(
1589
+ self._async_get_digital_product_catalogs_by_name(
1590
+ filter_string, classification_names, body, start_from, page_size, output_format, report_spec
1591
+ )
1592
+ )
1593
+
1594
+ @dynamic_catch
1595
+ async def _async_find_digital_product_catalogs(
1596
+ self,
1597
+ search_string: str = "*",
1598
+ starts_with: bool = False,
1599
+ ends_with: bool = False,
1600
+ ignore_case: bool = True,
1601
+ anchor_domain: Optional[str] = None,
1602
+ metadata_element_type: Optional[str] = None,
1603
+ metadata_element_subtype: Optional[str] = None,
1604
+ skip_relationships: Optional[list[str]] = None,
1605
+ include_only_relationships: Optional[list[str]] = None,
1606
+ skip_classified_elements: Optional[list[str]] = None,
1607
+ include_only_classified_elements: Optional[list[str]] = None,
1608
+ graph_query_depth: int = 0,
1609
+ governance_zone_filter: Optional[list[str]] = None,
1610
+ as_of_time: Optional[str] = None,
1611
+ effective_time: Optional[str] = None,
1612
+ relationship_page_size: int = 0,
1613
+ limit_results_by_status: Optional[list[str]] = None,
1614
+ sequencing_order: Optional[str] = None,
1615
+ sequencing_property: Optional[str] = None,
1616
+ start_from: int = 0,
1617
+ page_size: int = 0,
1618
+ output_format: str = "JSON",
1619
+ report_spec: Optional[str | dict] = None,
1620
+ property_names: Optional[list[str]] = None,
1621
+ body: Optional[dict] = None,
1622
+ ) -> list | str:
1623
+ """Returns the list of digital product catalogs matching the search string. Async version.
1624
+
1625
+ Parameters
1626
+ ----------
1627
+ search_string : str, optional
1628
+ Search string to match. Defaults to "*" (all).
1629
+ starts_with : bool, optional
1630
+ Whether to match from the start. Defaults to False.
1631
+ ends_with : bool, optional
1632
+ Whether to match at the end. Defaults to False.
1633
+ ignore_case : bool, optional
1634
+ Whether to ignore case. Defaults to True.
1635
+ anchor_domain : str, optional
1636
+ Domain to anchor the search.
1637
+ metadata_element_type : str, optional
1638
+ Type of metadata element to search for.
1639
+ metadata_element_subtype : str, optional
1640
+ Subtype of metadata element.
1641
+ skip_relationships : list[str], optional
1642
+ Relationships to skip in the graph.
1643
+ include_only_relationships : list[str], optional
1644
+ Only include these relationships.
1645
+ skip_classified_elements : list[str], optional
1646
+ Skip elements with these classifications.
1647
+ include_only_classified_elements : list[str], optional
1648
+ Only include elements with these classifications.
1649
+ graph_query_depth : int, optional
1650
+ Depth of graph query. Defaults to 0.
1651
+ governance_zone_filter : list[str], optional
1652
+ Filter by governance zones.
1653
+ as_of_time : str, optional
1654
+ Historical time for the query.
1655
+ effective_time : str, optional
1656
+ Effective time for the query.
1657
+ relationship_page_size : int, optional
1658
+ Page size for relationships. Defaults to 0.
1659
+ limit_results_by_status : list[str], optional
1660
+ Limit results by status values.
1661
+ sequencing_order : str, optional
1662
+ Order for sequencing results.
1663
+ sequencing_property : str, optional
1664
+ Property to sequence by.
1665
+ start_from : int, optional
1666
+ Starting index for pagination. Defaults to 0.
1667
+ page_size : int, optional
1668
+ Number of results per page. Defaults to 0 (no limit).
1669
+ output_format : str, optional
1670
+ Format for output. Defaults to "JSON".
1671
+ report_spec : str | dict, optional
1672
+ Report specification for formatting.
1673
+ property_names: list[str], optional
1674
+ The names of properties to search for.
1675
+ body : dict, optional
1676
+ Request body for additional parameters.
1677
+
1678
+ Returns
1679
+ -------
1680
+ list | str
1681
+ List of digital product catalogs matching the search criteria.
1682
+
1683
+ Raises
1684
+ ------
1685
+ PyegeriaException
1686
+ If there are issues in communications, message format, or Egeria errors.
1687
+ """
1688
+ url = f"{self.product_manager_command_root}/collections/by-search-string"
1689
+ response = await self._async_find_request(
1690
+ url,
1691
+ _type="DigitalProductCatalog",
1692
+ _gen_output=None,
1693
+ search_string=search_string,
1694
+ starts_with=starts_with,
1695
+ ends_with=ends_with,
1696
+ ignore_case=ignore_case,
1697
+ anchor_domain=anchor_domain,
1698
+ metadata_element_type=metadata_element_type,
1699
+ metadata_element_subtypes=metadata_element_subtype,
1700
+ skip_relationships=skip_relationships,
1701
+ include_only_relationships=include_only_relationships,
1702
+ skip_classified_elements=skip_classified_elements,
1703
+ include_only_classified_elements=include_only_classified_elements,
1704
+ graph_query_depth=graph_query_depth,
1705
+ governance_zone_filter=governance_zone_filter,
1706
+ as_of_time=as_of_time,
1707
+ effective_time=effective_time,
1708
+ relationship_page_size=relationship_page_size,
1709
+ limit_results_by_status=limit_results_by_status,
1710
+ sequencing_order=sequencing_order,
1711
+ sequencing_property=sequencing_property,
1712
+ start_from=start_from,
1713
+ page_size=page_size,
1714
+ output_format=output_format,
1715
+ report_spec=report_spec,
1716
+ property_names=property_names,
1717
+ body=body,
1718
+ )
1719
+ return response
1720
+
1721
+ def find_digital_product_catalogs(
1722
+ self,
1723
+ search_string: str = "*",
1724
+ starts_with: bool = False,
1725
+ ends_with: bool = False,
1726
+ ignore_case: bool = True,
1727
+ anchor_domain: Optional[str] = None,
1728
+ metadata_element_type: Optional[str] = None,
1729
+ metadata_element_subtype: Optional[str] = None,
1730
+ skip_relationships: Optional[list[str]] = None,
1731
+ include_only_relationships: Optional[list[str]] = None,
1732
+ skip_classified_elements: Optional[list[str]] = None,
1733
+ include_only_classified_elements: Optional[list[str]] = None,
1734
+ graph_query_depth: int = 0,
1735
+ governance_zone_filter: Optional[list[str]] = None,
1736
+ as_of_time: Optional[str] = None,
1737
+ effective_time: Optional[str] = None,
1738
+ relationship_page_size: int = 0,
1739
+ limit_results_by_status: Optional[list[str]] = None,
1740
+ sequencing_order: Optional[str] = None,
1741
+ sequencing_property: Optional[str] = None,
1742
+ start_from: int = 0,
1743
+ page_size: int = 0,
1744
+ output_format: str = "JSON",
1745
+ report_spec: Optional[str | dict] = None,
1746
+ property_names: Optional[list[str]] = None,
1747
+ body: Optional[dict] = None,
1748
+ ) -> list | str:
1749
+ """Returns the list of digital product catalogs matching the search string. Sync version.
1750
+
1751
+ Parameters
1752
+ ----------
1753
+ search_string : str, optional
1754
+ Search string to match. Defaults to "*" (all).
1755
+ starts_with : bool, optional
1756
+ Whether to match from the start. Defaults to False.
1757
+ ends_with : bool, optional
1758
+ Whether to match at the end. Defaults to False.
1759
+ ignore_case : bool, optional
1760
+ Whether to ignore case. Defaults to True.
1761
+ anchor_domain : str, optional
1762
+ Domain to anchor the search.
1763
+ metadata_element_type : str, optional
1764
+ Type of metadata element to search for.
1765
+ metadata_element_subtype : str, optional
1766
+ Subtype of metadata element.
1767
+ skip_relationships : list[str], optional
1768
+ Relationships to skip in the graph.
1769
+ include_only_relationships : list[str], optional
1770
+ Only include these relationships.
1771
+ skip_classified_elements : list[str], optional
1772
+ Skip elements with these classifications.
1773
+ include_only_classified_elements : list[str], optional
1774
+ Only include elements with these classifications.
1775
+ graph_query_depth : int, optional
1776
+ Depth of graph query. Defaults to 0.
1777
+ governance_zone_filter : list[str], optional
1778
+ Filter by governance zones.
1779
+ as_of_time : str, optional
1780
+ Historical time for the query.
1781
+ effective_time : str, optional
1782
+ Effective time for the query.
1783
+ relationship_page_size : int, optional
1784
+ Page size for relationships. Defaults to 0.
1785
+ limit_results_by_status : list[str], optional
1786
+ Limit results by status values.
1787
+ sequencing_order : str, optional
1788
+ Order for sequencing results.
1789
+ sequencing_property : str, optional
1790
+ Property to sequence by.
1791
+ start_from : int, optional
1792
+ Starting index for pagination. Defaults to 0.
1793
+ page_size : int, optional
1794
+ Number of results per page. Defaults to 0 (no limit).
1795
+ output_format : str, optional
1796
+ Format for output. Defaults to "JSON".
1797
+ report_spec : str | dict, optional
1798
+ Report specification for formatting.
1799
+ property_names: list[str], optional
1800
+ The names of properties to search for.
1801
+ body : dict, optional
1802
+ Request body for additional parameters.
1803
+
1804
+ Returns
1805
+ -------
1806
+ list | str
1807
+ List of digital product catalogs matching the search criteria.
1808
+
1809
+ Raises
1810
+ ------
1811
+ PyegeriaException
1812
+ If there are issues in communications, message format, or Egeria errors.
1813
+ """
1814
+ loop = asyncio.get_event_loop()
1815
+ return loop.run_until_complete(
1816
+ self._async_find_digital_product_catalogs(
1817
+ search_string, starts_with, ends_with, ignore_case, anchor_domain,
1818
+ metadata_element_type, metadata_element_subtype, skip_relationships,
1819
+ include_only_relationships, skip_classified_elements, include_only_classified_elements,
1820
+ graph_query_depth, governance_zone_filter, as_of_time, effective_time,
1821
+ relationship_page_size, limit_results_by_status, sequencing_order,
1822
+ sequencing_property, start_from, page_size, output_format, report_spec,
1823
+ property_names, body
1824
+ )
1825
+ )