zenml-nightly 0.58.2.dev20240623__py3-none-any.whl → 0.61.0.dev20240712__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. README.md +30 -9
  2. RELEASE_NOTES.md +240 -0
  3. zenml/VERSION +1 -1
  4. zenml/actions/base_action.py +177 -174
  5. zenml/actions/pipeline_run/pipeline_run_action.py +28 -23
  6. zenml/analytics/enums.py +3 -0
  7. zenml/artifact_stores/base_artifact_store.py +7 -1
  8. zenml/artifacts/utils.py +13 -10
  9. zenml/cli/__init__.py +28 -0
  10. zenml/cli/artifact.py +1 -2
  11. zenml/cli/integration.py +9 -8
  12. zenml/cli/server.py +6 -0
  13. zenml/cli/service_connectors.py +1 -0
  14. zenml/cli/stack.py +946 -39
  15. zenml/cli/stack_components.py +7 -0
  16. zenml/cli/text_utils.py +35 -1
  17. zenml/cli/utils.py +127 -10
  18. zenml/client.py +257 -72
  19. zenml/config/compiler.py +10 -9
  20. zenml/config/docker_settings.py +33 -14
  21. zenml/constants.py +11 -2
  22. zenml/container_registries/base_container_registry.py +1 -0
  23. zenml/enums.py +7 -0
  24. zenml/event_hub/base_event_hub.py +5 -5
  25. zenml/event_hub/event_hub.py +20 -14
  26. zenml/event_sources/base_event.py +0 -11
  27. zenml/event_sources/base_event_source.py +7 -0
  28. zenml/event_sources/webhooks/base_webhook_event_source.py +1 -4
  29. zenml/exceptions.py +4 -0
  30. zenml/hooks/hook_validators.py +2 -3
  31. zenml/integrations/aws/__init__.py +1 -0
  32. zenml/integrations/azure/__init__.py +1 -0
  33. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +3 -3
  34. zenml/integrations/deepchecks/__init__.py +1 -0
  35. zenml/integrations/discord/__init__.py +1 -0
  36. zenml/integrations/evidently/__init__.py +1 -0
  37. zenml/integrations/facets/__init__.py +1 -0
  38. zenml/integrations/feast/__init__.py +1 -0
  39. zenml/integrations/gcp/__init__.py +3 -1
  40. zenml/integrations/gcp/google_credentials_mixin.py +1 -1
  41. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
  42. zenml/integrations/huggingface/__init__.py +1 -0
  43. zenml/integrations/integration.py +24 -0
  44. zenml/integrations/kubeflow/__init__.py +3 -0
  45. zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
  46. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
  47. zenml/integrations/kubernetes/__init__.py +3 -1
  48. zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
  49. zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
  50. zenml/integrations/langchain/__init__.py +1 -0
  51. zenml/integrations/mlflow/__init__.py +4 -2
  52. zenml/integrations/neural_prophet/__init__.py +1 -0
  53. zenml/integrations/polars/__init__.py +1 -0
  54. zenml/integrations/prodigy/__init__.py +1 -0
  55. zenml/integrations/pycaret/__init__.py +6 -0
  56. zenml/integrations/registry.py +37 -0
  57. zenml/integrations/s3/artifact_stores/s3_artifact_store.py +93 -9
  58. zenml/integrations/seldon/__init__.py +1 -0
  59. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
  60. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
  61. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
  62. zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
  63. zenml/integrations/skypilot_aws/__init__.py +2 -1
  64. zenml/integrations/skypilot_azure/__init__.py +1 -1
  65. zenml/integrations/skypilot_gcp/__init__.py +1 -1
  66. zenml/integrations/skypilot_lambda/__init__.py +1 -1
  67. zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
  68. zenml/integrations/slack/__init__.py +1 -0
  69. zenml/integrations/tekton/__init__.py +1 -0
  70. zenml/integrations/tensorboard/__init__.py +0 -1
  71. zenml/integrations/tensorflow/__init__.py +18 -6
  72. zenml/integrations/wandb/__init__.py +1 -0
  73. zenml/logging/step_logging.py +54 -51
  74. zenml/models/__init__.py +28 -0
  75. zenml/models/v2/core/action.py +276 -0
  76. zenml/models/v2/core/component.py +18 -0
  77. zenml/models/v2/core/model.py +1 -2
  78. zenml/models/v2/core/service_connector.py +17 -0
  79. zenml/models/v2/core/stack.py +31 -0
  80. zenml/models/v2/core/trigger.py +182 -141
  81. zenml/models/v2/misc/full_stack.py +97 -0
  82. zenml/models/v2/misc/stack_deployment.py +86 -0
  83. zenml/new/pipelines/pipeline.py +14 -4
  84. zenml/new/pipelines/pipeline_decorator.py +1 -2
  85. zenml/new/pipelines/run_utils.py +1 -12
  86. zenml/new/steps/step_decorator.py +2 -3
  87. zenml/orchestrators/input_utils.py +3 -6
  88. zenml/pipelines/base_pipeline.py +0 -2
  89. zenml/pipelines/pipeline_decorator.py +1 -2
  90. zenml/stack/stack.py +3 -6
  91. zenml/stack/stack_component.py +4 -0
  92. zenml/stack_deployments/__init__.py +14 -0
  93. zenml/stack_deployments/aws_stack_deployment.py +254 -0
  94. zenml/stack_deployments/gcp_stack_deployment.py +260 -0
  95. zenml/stack_deployments/stack_deployment.py +208 -0
  96. zenml/stack_deployments/utils.py +44 -0
  97. zenml/steps/base_step.py +1 -2
  98. zenml/steps/step_decorator.py +1 -2
  99. zenml/types.py +10 -1
  100. zenml/utils/function_utils.py +1 -1
  101. zenml/utils/pagination_utils.py +7 -5
  102. zenml/utils/pipeline_docker_image_builder.py +117 -73
  103. zenml/utils/pydantic_utils.py +6 -5
  104. zenml/zen_server/cloud_utils.py +18 -3
  105. zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
  106. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
  107. zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
  108. zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
  109. zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
  110. zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
  111. zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
  112. zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
  113. zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
  114. zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
  115. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
  116. zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
  117. zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
  118. zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
  119. zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
  120. zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
  121. zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
  122. zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
  123. zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
  124. zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
  125. zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
  126. zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
  127. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
  128. zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
  129. zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
  130. zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
  131. zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
  132. zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
  133. zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
  134. zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
  135. zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
  136. zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
  137. zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
  138. zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
  139. zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
  140. zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
  141. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
  142. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
  143. zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
  144. zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
  145. zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
  146. zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
  147. zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
  148. zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
  149. zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
  150. zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
  151. zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
  152. zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
  153. zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
  154. zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
  155. zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
  156. zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
  157. zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
  158. zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
  159. zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
  160. zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
  161. zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
  162. zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
  163. zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
  164. zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
  165. zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
  166. zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
  167. zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
  168. zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
  169. zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
  170. zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
  171. zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
  172. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
  173. zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
  174. zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
  175. zenml/zen_server/dashboard/index.html +7 -7
  176. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  177. zenml/zen_server/dashboard_legacy/index.html +1 -1
  178. zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
  179. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  180. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
  181. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.chunk.js.map} +1 -1
  182. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  183. zenml/zen_server/deploy/helm/README.md +2 -2
  184. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
  185. zenml/zen_server/pipeline_deployment/utils.py +57 -44
  186. zenml/zen_server/rbac/models.py +1 -0
  187. zenml/zen_server/rbac/utils.py +22 -1
  188. zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
  189. zenml/zen_server/routers/actions_endpoints.py +324 -0
  190. zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
  191. zenml/zen_server/routers/triggers_endpoints.py +30 -158
  192. zenml/zen_server/routers/workspaces_endpoints.py +64 -0
  193. zenml/zen_server/zen_server_api.py +4 -0
  194. zenml/zen_stores/migrations/utils.py +1 -1
  195. zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
  196. zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
  197. zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
  198. zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
  199. zenml/zen_stores/rest_zen_store.py +248 -8
  200. zenml/zen_stores/schemas/__init__.py +2 -0
  201. zenml/zen_stores/schemas/action_schemas.py +192 -0
  202. zenml/zen_stores/schemas/stack_schemas.py +10 -0
  203. zenml/zen_stores/schemas/step_run_schemas.py +27 -11
  204. zenml/zen_stores/schemas/trigger_schemas.py +43 -50
  205. zenml/zen_stores/schemas/user_schemas.py +10 -2
  206. zenml/zen_stores/schemas/workspace_schemas.py +5 -0
  207. zenml/zen_stores/sql_zen_store.py +540 -36
  208. zenml/zen_stores/zen_store_interface.py +165 -0
  209. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +33 -11
  210. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +213 -193
  211. zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
  212. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
  213. zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
  214. zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
  215. zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
  216. zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
  217. zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
  218. zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
  219. zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
  220. zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
  221. zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
  222. zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
  223. zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
  224. zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
  225. zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
  226. zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
  227. zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
  228. zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
  229. zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
  230. zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
  231. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
  232. zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
  233. zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
  234. zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
  235. zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
  236. zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
  237. zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
  238. zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
  239. zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
  240. zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
  241. zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
  242. zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
  243. zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
  244. zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
  245. zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
  246. zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
  247. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
  248. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
  249. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,158 @@
1
+ # Copyright (c) ZenML GmbH 2024. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Endpoint definitions for stack deployments."""
15
+
16
+ import datetime
17
+ from typing import Optional
18
+
19
+ from fastapi import APIRouter, Request, Security
20
+
21
+ from zenml.constants import (
22
+ API,
23
+ CONFIG,
24
+ INFO,
25
+ STACK,
26
+ STACK_DEPLOYMENT,
27
+ STACK_DEPLOYMENT_API_TOKEN_EXPIRATION,
28
+ VERSION_1,
29
+ )
30
+ from zenml.enums import StackDeploymentProvider
31
+ from zenml.models import (
32
+ DeployedStack,
33
+ StackDeploymentConfig,
34
+ StackDeploymentInfo,
35
+ )
36
+ from zenml.stack_deployments.utils import get_stack_deployment_class
37
+ from zenml.zen_server.auth import AuthContext, authorize
38
+ from zenml.zen_server.exceptions import error_response
39
+ from zenml.zen_server.rbac.models import Action, ResourceType
40
+ from zenml.zen_server.rbac.utils import verify_permission
41
+ from zenml.zen_server.utils import (
42
+ handle_exceptions,
43
+ )
44
+
45
+ router = APIRouter(
46
+ prefix=API + VERSION_1 + STACK_DEPLOYMENT,
47
+ tags=["stacks"],
48
+ responses={401: error_response, 403: error_response},
49
+ )
50
+
51
+
52
+ @router.get(
53
+ INFO,
54
+ )
55
+ @handle_exceptions
56
+ def get_stack_deployment_info(
57
+ provider: StackDeploymentProvider,
58
+ _: AuthContext = Security(authorize),
59
+ ) -> StackDeploymentInfo:
60
+ """Get information about a stack deployment provider.
61
+
62
+ Args:
63
+ provider: The stack deployment provider.
64
+
65
+ Returns:
66
+ Information about the stack deployment provider.
67
+ """
68
+ stack_deployment_class = get_stack_deployment_class(provider)
69
+ return stack_deployment_class.get_deployment_info()
70
+
71
+
72
+ @router.get(
73
+ CONFIG,
74
+ )
75
+ @handle_exceptions
76
+ def get_stack_deployment_config(
77
+ request: Request,
78
+ provider: StackDeploymentProvider,
79
+ stack_name: str,
80
+ location: Optional[str] = None,
81
+ auth_context: AuthContext = Security(authorize),
82
+ ) -> StackDeploymentConfig:
83
+ """Return the URL to deploy the ZenML stack to the specified cloud provider.
84
+
85
+ Args:
86
+ request: The FastAPI request object.
87
+ provider: The stack deployment provider.
88
+ stack_name: The name of the stack.
89
+ location: The location where the stack should be deployed.
90
+ auth_context: The authentication context.
91
+
92
+ Returns:
93
+ The cloud provider console URL where the stack will be deployed and
94
+ the configuration for the stack deployment.
95
+ """
96
+ verify_permission(
97
+ resource_type=ResourceType.SERVICE_CONNECTOR, action=Action.CREATE
98
+ )
99
+ verify_permission(
100
+ resource_type=ResourceType.STACK_COMPONENT,
101
+ action=Action.CREATE,
102
+ )
103
+ verify_permission(resource_type=ResourceType.STACK, action=Action.CREATE)
104
+
105
+ stack_deployment_class = get_stack_deployment_class(provider)
106
+ # Get the base server URL used to call this FastAPI endpoint
107
+ url = request.url.replace(path="").replace(query="")
108
+ # Use HTTPS for the URL
109
+ url = url.replace(scheme="https")
110
+
111
+ token = auth_context.access_token
112
+ assert token is not None
113
+
114
+ # A new API token is generated for the stack deployment
115
+ expires = datetime.datetime.utcnow() + datetime.timedelta(
116
+ minutes=STACK_DEPLOYMENT_API_TOKEN_EXPIRATION
117
+ )
118
+ api_token = token.encode(expires=expires)
119
+
120
+ return stack_deployment_class(
121
+ stack_name=stack_name,
122
+ location=location,
123
+ zenml_server_url=str(url),
124
+ zenml_server_api_token=api_token,
125
+ ).get_deployment_config()
126
+
127
+
128
+ @router.get(
129
+ STACK,
130
+ )
131
+ @handle_exceptions
132
+ def get_deployed_stack(
133
+ provider: StackDeploymentProvider,
134
+ stack_name: str,
135
+ location: Optional[str] = None,
136
+ date_start: Optional[datetime.datetime] = None,
137
+ _: AuthContext = Security(authorize),
138
+ ) -> Optional[DeployedStack]:
139
+ """Return a matching ZenML stack that was deployed and registered.
140
+
141
+ Args:
142
+ provider: The stack deployment provider.
143
+ stack_name: The name of the stack.
144
+ location: The location where the stack should be deployed.
145
+ date_start: The date when the deployment started.
146
+
147
+ Returns:
148
+ The ZenML stack that was deployed and registered or None if the stack
149
+ was not found.
150
+ """
151
+ stack_deployment_class = get_stack_deployment_class(provider)
152
+ return stack_deployment_class(
153
+ stack_name=stack_name,
154
+ location=location,
155
+ # These fields are not needed for this operation
156
+ zenml_server_url="",
157
+ zenml_server_api_token="",
158
+ ).get_stack(date_start=date_start)
@@ -18,7 +18,6 @@ from uuid import UUID
18
18
  from fastapi import APIRouter, Depends, Security
19
19
 
20
20
  from zenml import TriggerRequest
21
- from zenml.actions.base_action import BaseActionHandler
22
21
  from zenml.constants import API, TRIGGER_EXECUTIONS, TRIGGERS, VERSION_1
23
22
  from zenml.enums import PluginType
24
23
  from zenml.event_sources.base_event_source import BaseEventSourceHandler
@@ -81,54 +80,11 @@ def list_triggers(
81
80
  Returns:
82
81
  All triggers.
83
82
  """
84
-
85
- def list_triggers_fn(
86
- filter_model: TriggerFilter,
87
- ) -> Page[TriggerResponse]:
88
- """List triggers through their associated plugins.
89
-
90
- Args:
91
- filter_model: Filter model used for pagination, sorting,
92
- filtering.
93
-
94
- Returns:
95
- All triggers.
96
-
97
- Raises:
98
- ValueError: If the plugin for a trigger action is not a valid action
99
- plugin.
100
- """
101
- triggers = zen_store().list_triggers(
102
- trigger_filter_model=filter_model, hydrate=hydrate
103
- )
104
-
105
- # Process the triggers through their associated plugins
106
- for idx, trigger in enumerate(triggers.items):
107
- action_handler = plugin_flavor_registry().get_plugin(
108
- name=trigger.action_flavor,
109
- _type=PluginType.ACTION,
110
- subtype=trigger.action_subtype,
111
- )
112
-
113
- # Validate that the flavor and plugin_type correspond to an action
114
- # handler implementation
115
- if not isinstance(action_handler, BaseActionHandler):
116
- raise ValueError(
117
- f"Action handler plugin {trigger.action_subtype} "
118
- f"for flavor {trigger.action_flavor} is not a valid action "
119
- "handler plugin."
120
- )
121
-
122
- triggers.items[idx] = action_handler.get_trigger(
123
- trigger, hydrate=hydrate
124
- )
125
-
126
- return triggers
127
-
128
83
  return verify_permissions_and_list_entities(
129
84
  filter_model=trigger_filter_model,
130
85
  resource_type=ResourceType.TRIGGER,
131
- list_method=list_triggers_fn,
86
+ list_method=zen_store().list_triggers,
87
+ hydrate=hydrate,
132
88
  )
133
89
 
134
90
 
@@ -152,31 +108,9 @@ def get_trigger(
152
108
 
153
109
  Returns:
154
110
  The requested trigger.
155
-
156
- Raises:
157
- ValueError: If the action flavor/subtype combination is not actually a webhook event source
158
111
  """
159
112
  trigger = zen_store().get_trigger(trigger_id=trigger_id, hydrate=hydrate)
160
-
161
113
  verify_permission_for_model(trigger, action=Action.READ)
162
-
163
- action_handler = plugin_flavor_registry().get_plugin(
164
- name=trigger.action_flavor,
165
- _type=PluginType.ACTION,
166
- subtype=trigger.action_subtype,
167
- )
168
-
169
- # Validate that the flavor and plugin_type correspond to an action
170
- # handler implementation
171
- if not isinstance(action_handler, BaseActionHandler):
172
- raise ValueError(
173
- f"Action handler plugin {trigger.action_subtype} "
174
- f"for flavor {trigger.action_flavor} is not a valid action "
175
- "handler plugin."
176
- )
177
-
178
- trigger = action_handler.get_trigger(trigger, hydrate=hydrate)
179
-
180
114
  return dehydrate_response_model(trigger)
181
115
 
182
116
 
@@ -201,55 +135,35 @@ def create_trigger(
201
135
  Raises:
202
136
  ValueError: If the action flavor/subtype combination is not actually a webhook event source
203
137
  """
204
- if trigger.service_account_id:
205
- service_account = zen_store().get_service_account(
206
- service_account_name_or_id=trigger.service_account_id
138
+ if trigger.event_source_id and trigger.event_filter:
139
+ event_source = zen_store().get_event_source(
140
+ event_source_id=trigger.event_source_id
207
141
  )
208
- verify_permission_for_model(service_account, action=Action.READ)
209
-
210
- event_source = zen_store().get_event_source(
211
- event_source_id=trigger.event_source_id
212
- )
213
142
 
214
- event_source_handler = plugin_flavor_registry().get_plugin(
215
- name=event_source.flavor,
216
- _type=PluginType.EVENT_SOURCE,
217
- subtype=event_source.plugin_subtype,
218
- )
219
-
220
- # Validate that the flavor and plugin_type correspond to an event source
221
- # implementation
222
- if not isinstance(event_source_handler, BaseEventSourceHandler):
223
- raise ValueError(
224
- f"Event source plugin {event_source.plugin_subtype} "
225
- f"for flavor {event_source.flavor} is not a valid event source "
226
- "handler implementation."
143
+ event_source_handler = plugin_flavor_registry().get_plugin(
144
+ name=event_source.flavor,
145
+ _type=PluginType.EVENT_SOURCE,
146
+ subtype=event_source.plugin_subtype,
227
147
  )
228
148
 
229
- # Validate the trigger event filter
230
- event_source_handler.validate_event_filter_configuration(
231
- trigger.event_filter
232
- )
233
-
234
- action_handler = plugin_flavor_registry().get_plugin(
235
- name=trigger.action_flavor,
236
- _type=PluginType.ACTION,
237
- subtype=trigger.action_subtype,
238
- )
149
+ # Validate that the flavor and plugin_type correspond to an event source
150
+ # implementation
151
+ if not isinstance(event_source_handler, BaseEventSourceHandler):
152
+ raise ValueError(
153
+ f"Event source plugin {event_source.plugin_subtype} "
154
+ f"for flavor {event_source.flavor} is not a valid event source "
155
+ "handler implementation."
156
+ )
239
157
 
240
- # Validate that the flavor and plugin_type correspond to an action
241
- # handler implementation
242
- if not isinstance(action_handler, BaseActionHandler):
243
- raise ValueError(
244
- f"Action handler plugin {trigger.action_subtype} "
245
- f"for flavor {trigger.action_flavor} is not a valid action "
246
- "handler plugin."
158
+ # Validate the trigger event filter
159
+ event_source_handler.validate_event_filter_configuration(
160
+ trigger.event_filter
247
161
  )
248
162
 
249
163
  return verify_permissions_and_create_entity(
250
164
  request_model=trigger,
251
165
  resource_type=ResourceType.TRIGGER,
252
- create_method=action_handler.create_trigger,
166
+ create_method=zen_store().create_trigger,
253
167
  )
254
168
 
255
169
 
@@ -278,13 +192,12 @@ def update_trigger(
278
192
  """
279
193
  trigger = zen_store().get_trigger(trigger_id=trigger_id)
280
194
 
281
- if trigger_update.service_account_id:
282
- service_account = zen_store().get_service_account(
283
- service_account_name_or_id=trigger_update.service_account_id
284
- )
285
- verify_permission_for_model(service_account, action=Action.READ)
286
-
287
195
  if trigger_update.event_filter:
196
+ if not trigger.event_source:
197
+ raise ValueError(
198
+ "Trying to set event filter for trigger without event source."
199
+ )
200
+
288
201
  event_source = zen_store().get_event_source(
289
202
  event_source_id=trigger.event_source.id
290
203
  )
@@ -306,29 +219,13 @@ def update_trigger(
306
219
 
307
220
  # Validate the trigger event filter
308
221
  event_source_handler.validate_event_filter_configuration(
309
- trigger.event_filter
222
+ trigger_update.event_filter
310
223
  )
311
224
 
312
225
  verify_permission_for_model(trigger, action=Action.UPDATE)
313
226
 
314
- action_handler = plugin_flavor_registry().get_plugin(
315
- name=trigger.action_flavor,
316
- _type=PluginType.ACTION,
317
- subtype=trigger.action_subtype,
318
- )
319
-
320
- # Validate that the flavor and plugin_type correspond to an action
321
- # handler implementation
322
- if not isinstance(action_handler, BaseActionHandler):
323
- raise ValueError(
324
- f"Action handler plugin {trigger.action_subtype} "
325
- f"for flavor {trigger.action_flavor} is not a valid action "
326
- "handler plugin."
327
- )
328
-
329
- updated_trigger = action_handler.update_trigger(
330
- trigger=trigger,
331
- trigger_update=trigger_update,
227
+ updated_trigger = zen_store().update_trigger(
228
+ trigger_id=trigger_id, trigger_update=trigger_update
332
229
  )
333
230
 
334
231
  return dehydrate_response_model(updated_trigger)
@@ -341,41 +238,16 @@ def update_trigger(
341
238
  @handle_exceptions
342
239
  def delete_trigger(
343
240
  trigger_id: UUID,
344
- force: bool = False,
345
241
  _: AuthContext = Security(authorize),
346
242
  ) -> None:
347
243
  """Deletes a trigger.
348
244
 
349
245
  Args:
350
246
  trigger_id: Name of the trigger.
351
- force: Flag deciding whether to force delete the trigger.
352
-
353
- Raises:
354
- ValueError: If the action flavor/subtype combination is not actually a webhook event source
355
247
  """
356
248
  trigger = zen_store().get_trigger(trigger_id=trigger_id)
357
-
358
249
  verify_permission_for_model(trigger, action=Action.DELETE)
359
-
360
- action_handler = plugin_flavor_registry().get_plugin(
361
- name=trigger.action_flavor,
362
- _type=PluginType.ACTION,
363
- subtype=trigger.action_subtype,
364
- )
365
-
366
- # Validate that the flavor and plugin_type correspond to an action
367
- # handler implementation
368
- if not isinstance(action_handler, BaseActionHandler):
369
- raise ValueError(
370
- f"Action handler plugin {trigger.action_subtype} "
371
- f"for flavor {trigger.action_flavor} is not a valid action "
372
- "handler plugin."
373
- )
374
-
375
- action_handler.delete_trigger(
376
- trigger=trigger,
377
- force=force,
378
- )
250
+ zen_store().delete_trigger(trigger_id=trigger_id)
379
251
 
380
252
 
381
253
  executions_router = APIRouter(
@@ -22,6 +22,7 @@ from zenml.constants import (
22
22
  API,
23
23
  ARTIFACTS,
24
24
  CODE_REPOSITORIES,
25
+ FULL_STACK,
25
26
  GET_OR_CREATE,
26
27
  MODEL_VERSIONS,
27
28
  MODELS,
@@ -51,6 +52,7 @@ from zenml.models import (
51
52
  ComponentFilter,
52
53
  ComponentRequest,
53
54
  ComponentResponse,
55
+ FullStackRequest,
54
56
  ModelRequest,
55
57
  ModelResponse,
56
58
  ModelVersionArtifactRequest,
@@ -349,6 +351,68 @@ def create_stack(
349
351
  )
350
352
 
351
353
 
354
+ @router.post(
355
+ WORKSPACES + "/{workspace_name_or_id}" + FULL_STACK,
356
+ response_model=StackResponse,
357
+ responses={401: error_response, 409: error_response, 422: error_response},
358
+ )
359
+ @handle_exceptions
360
+ def create_full_stack(
361
+ workspace_name_or_id: Union[str, UUID],
362
+ full_stack: FullStackRequest,
363
+ auth_context: AuthContext = Security(authorize),
364
+ ) -> StackResponse:
365
+ """Creates a stack for a particular workspace.
366
+
367
+ Args:
368
+ workspace_name_or_id: Name or ID of the workspace.
369
+ full_stack: Stack to register.
370
+ auth_context: Authentication context.
371
+
372
+ Returns:
373
+ The created stack.
374
+ """
375
+ workspace = zen_store().get_workspace(workspace_name_or_id)
376
+
377
+ is_connector_create_needed = False
378
+ for connector_id_or_info in full_stack.service_connectors:
379
+ if isinstance(connector_id_or_info, UUID):
380
+ service_connector = zen_store().get_service_connector(
381
+ connector_id_or_info, hydrate=False
382
+ )
383
+ verify_permission_for_model(
384
+ model=service_connector, action=Action.READ
385
+ )
386
+ else:
387
+ is_connector_create_needed = True
388
+ if is_connector_create_needed:
389
+ verify_permission(
390
+ resource_type=ResourceType.SERVICE_CONNECTOR, action=Action.CREATE
391
+ )
392
+
393
+ is_component_create_needed = False
394
+ for component_id_or_info in full_stack.components.values():
395
+ if isinstance(component_id_or_info, UUID):
396
+ component = zen_store().get_stack_component(
397
+ component_id_or_info, hydrate=False
398
+ )
399
+ verify_permission_for_model(model=component, action=Action.READ)
400
+ else:
401
+ is_component_create_needed = True
402
+ if is_component_create_needed:
403
+ verify_permission(
404
+ resource_type=ResourceType.STACK_COMPONENT,
405
+ action=Action.CREATE,
406
+ )
407
+
408
+ verify_permission(resource_type=ResourceType.STACK, action=Action.CREATE)
409
+
410
+ full_stack.user = auth_context.user.id
411
+ full_stack.workspace = workspace.id
412
+
413
+ return zen_store().create_full_stack(full_stack)
414
+
415
+
352
416
  @router.get(
353
417
  WORKSPACES + "/{workspace_name_or_id}" + STACK_COMPONENTS,
354
418
  response_model=Page[ComponentResponse],
@@ -40,6 +40,7 @@ from zenml.constants import API, HEALTH
40
40
  from zenml.enums import AuthScheme, SourceContextTypes
41
41
  from zenml.zen_server.exceptions import error_detail
42
42
  from zenml.zen_server.routers import (
43
+ actions_endpoints,
43
44
  artifact_endpoint,
44
45
  artifact_version_endpoints,
45
46
  auth_endpoints,
@@ -62,6 +63,7 @@ from zenml.zen_server.routers import (
62
63
  service_connectors_endpoints,
63
64
  service_endpoints,
64
65
  stack_components_endpoints,
66
+ stack_deployment_endpoints,
65
67
  stacks_endpoints,
66
68
  steps_endpoints,
67
69
  tags_endpoints,
@@ -262,6 +264,7 @@ async def dashboard(request: Request) -> Any:
262
264
  return templates.TemplateResponse("index.html", {"request": request})
263
265
 
264
266
 
267
+ app.include_router(actions_endpoints.router)
265
268
  app.include_router(artifact_endpoint.artifact_router)
266
269
  app.include_router(artifact_version_endpoints.artifact_version_router)
267
270
  app.include_router(auth_endpoints.router)
@@ -288,6 +291,7 @@ app.include_router(service_accounts_endpoints.router)
288
291
  app.include_router(service_connectors_endpoints.router)
289
292
  app.include_router(service_connectors_endpoints.types_router)
290
293
  app.include_router(service_endpoints.router)
294
+ app.include_router(stack_deployment_endpoints.router)
291
295
  app.include_router(stacks_endpoints.router)
292
296
  app.include_router(stack_components_endpoints.router)
293
297
  app.include_router(stack_components_endpoints.types_router)
@@ -364,7 +364,7 @@ class MigrationUtils(BaseModel):
364
364
  # Convert column values to the correct type
365
365
  for column in table.columns:
366
366
  # Blob columns are stored as binary strings
367
- if column.type.python_type == bytes and isinstance(
367
+ if column.type.python_type is bytes and isinstance(
368
368
  row[column.name], str
369
369
  ):
370
370
  # Convert the string to bytes
@@ -0,0 +1,23 @@
1
+ """Release [0.60.0].
2
+
3
+ Revision ID: 0.60.0
4
+ Revises: 25155145c545
5
+ Create Date: 2024-06-25 14:26:48.867005
6
+
7
+ """
8
+
9
+ # revision identifiers, used by Alembic.
10
+ revision = "0.60.0"
11
+ down_revision = "25155145c545"
12
+ branch_labels = None
13
+ depends_on = None
14
+
15
+
16
+ def upgrade() -> None:
17
+ """Upgrade database schema and/or data, creating a new revision."""
18
+ pass
19
+
20
+
21
+ def downgrade() -> None:
22
+ """Downgrade database schema and/or data back to the previous revision."""
23
+ pass
@@ -0,0 +1,23 @@
1
+ """Release [0.61.0].
2
+
3
+ Revision ID: 0.61.0
4
+ Revises: 0d707865f404
5
+ Create Date: 2024-07-08 15:52:54.765307
6
+
7
+ """
8
+
9
+ # revision identifiers, used by Alembic.
10
+ revision = "0.61.0"
11
+ down_revision = "0d707865f404"
12
+ branch_labels = None
13
+ depends_on = None
14
+
15
+
16
+ def upgrade() -> None:
17
+ """Upgrade database schema and/or data, creating a new revision."""
18
+ pass
19
+
20
+
21
+ def downgrade() -> None:
22
+ """Downgrade database schema and/or data back to the previous revision."""
23
+ pass
@@ -0,0 +1,30 @@
1
+ """adding labels to stacks [0d707865f404].
2
+
3
+ Revision ID: 0d707865f404
4
+ Revises: 0.60.0
5
+ Create Date: 2024-07-04 16:10:07.709184
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "0d707865f404"
14
+ down_revision = "0.60.0"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ """Upgrade database schema and/or data, creating a new revision."""
21
+ with op.batch_alter_table("stack", schema=None) as batch_op:
22
+ batch_op.add_column(
23
+ sa.Column("labels", sa.LargeBinary(), nullable=True)
24
+ )
25
+
26
+
27
+ def downgrade() -> None:
28
+ """Downgrade database schema and/or data back to the previous revision."""
29
+ with op.batch_alter_table("stack", schema=None) as batch_op:
30
+ batch_op.drop_column("labels")