zenml-nightly 0.58.2.dev20240626__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 (214) hide show
  1. README.md +30 -9
  2. RELEASE_NOTES.md +240 -0
  3. zenml/VERSION +1 -1
  4. zenml/analytics/enums.py +3 -0
  5. zenml/cli/__init__.py +28 -0
  6. zenml/cli/artifact.py +1 -2
  7. zenml/cli/integration.py +9 -8
  8. zenml/cli/server.py +6 -0
  9. zenml/cli/stack.py +946 -39
  10. zenml/cli/stack_components.py +7 -0
  11. zenml/cli/text_utils.py +35 -1
  12. zenml/cli/utils.py +127 -10
  13. zenml/client.py +23 -14
  14. zenml/config/docker_settings.py +8 -5
  15. zenml/constants.py +10 -1
  16. zenml/container_registries/base_container_registry.py +1 -0
  17. zenml/enums.py +7 -0
  18. zenml/event_hub/event_hub.py +5 -8
  19. zenml/integrations/aws/__init__.py +1 -0
  20. zenml/integrations/azure/__init__.py +1 -0
  21. zenml/integrations/deepchecks/__init__.py +1 -0
  22. zenml/integrations/discord/__init__.py +1 -0
  23. zenml/integrations/evidently/__init__.py +1 -0
  24. zenml/integrations/facets/__init__.py +1 -0
  25. zenml/integrations/feast/__init__.py +1 -0
  26. zenml/integrations/gcp/__init__.py +3 -1
  27. zenml/integrations/gcp/google_credentials_mixin.py +1 -1
  28. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
  29. zenml/integrations/huggingface/__init__.py +1 -0
  30. zenml/integrations/integration.py +24 -0
  31. zenml/integrations/kubeflow/__init__.py +3 -0
  32. zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
  33. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
  34. zenml/integrations/kubernetes/__init__.py +3 -1
  35. zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
  36. zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
  37. zenml/integrations/langchain/__init__.py +1 -0
  38. zenml/integrations/mlflow/__init__.py +3 -1
  39. zenml/integrations/neural_prophet/__init__.py +1 -0
  40. zenml/integrations/polars/__init__.py +1 -0
  41. zenml/integrations/prodigy/__init__.py +1 -0
  42. zenml/integrations/pycaret/__init__.py +6 -0
  43. zenml/integrations/registry.py +37 -0
  44. zenml/integrations/s3/artifact_stores/s3_artifact_store.py +17 -6
  45. zenml/integrations/seldon/__init__.py +1 -0
  46. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
  47. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
  48. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
  49. zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
  50. zenml/integrations/skypilot_aws/__init__.py +2 -1
  51. zenml/integrations/skypilot_azure/__init__.py +1 -1
  52. zenml/integrations/skypilot_gcp/__init__.py +1 -1
  53. zenml/integrations/skypilot_lambda/__init__.py +1 -1
  54. zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
  55. zenml/integrations/slack/__init__.py +1 -0
  56. zenml/integrations/tekton/__init__.py +1 -0
  57. zenml/integrations/tensorboard/__init__.py +0 -1
  58. zenml/integrations/tensorflow/__init__.py +18 -6
  59. zenml/integrations/wandb/__init__.py +1 -0
  60. zenml/models/__init__.py +11 -0
  61. zenml/models/v2/core/component.py +18 -0
  62. zenml/models/v2/core/model.py +1 -2
  63. zenml/models/v2/core/service_connector.py +17 -0
  64. zenml/models/v2/core/stack.py +31 -0
  65. zenml/models/v2/misc/full_stack.py +97 -0
  66. zenml/models/v2/misc/stack_deployment.py +86 -0
  67. zenml/new/pipelines/pipeline.py +1 -1
  68. zenml/orchestrators/input_utils.py +3 -6
  69. zenml/stack/stack.py +3 -6
  70. zenml/stack_deployments/__init__.py +14 -0
  71. zenml/stack_deployments/aws_stack_deployment.py +254 -0
  72. zenml/stack_deployments/gcp_stack_deployment.py +260 -0
  73. zenml/stack_deployments/stack_deployment.py +208 -0
  74. zenml/stack_deployments/utils.py +44 -0
  75. zenml/utils/function_utils.py +1 -1
  76. zenml/utils/pagination_utils.py +7 -5
  77. zenml/utils/pipeline_docker_image_builder.py +97 -68
  78. zenml/utils/pydantic_utils.py +6 -5
  79. zenml/zen_server/cloud_utils.py +18 -3
  80. zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
  81. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
  82. zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
  83. zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
  84. zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
  85. zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
  86. zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
  87. zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
  88. zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
  89. zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
  90. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
  91. zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
  92. zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
  93. zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
  94. zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
  95. zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
  96. zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
  97. zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
  98. zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
  99. zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
  100. zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
  101. zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
  102. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
  103. zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
  104. zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
  105. zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
  106. zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
  107. zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
  108. zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
  109. zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
  110. zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
  111. zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
  112. zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
  113. zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
  114. zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
  115. zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
  116. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
  117. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
  118. zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
  119. zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
  120. zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
  121. zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
  122. zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
  123. zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
  124. zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
  125. zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
  126. zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
  127. zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
  128. zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
  129. zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
  130. zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
  131. zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
  132. zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
  133. zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
  134. zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
  135. zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
  136. zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
  137. zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
  138. zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
  139. zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
  140. zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
  141. zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
  142. zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
  143. zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
  144. zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
  145. zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
  146. zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
  148. zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
  149. zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
  150. zenml/zen_server/dashboard/index.html +7 -7
  151. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  152. zenml/zen_server/dashboard_legacy/index.html +1 -1
  153. zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
  154. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  155. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
  156. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.chunk.js.map} +1 -1
  157. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  158. zenml/zen_server/deploy/helm/README.md +2 -2
  159. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
  160. zenml/zen_server/pipeline_deployment/utils.py +57 -44
  161. zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
  162. zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
  163. zenml/zen_server/routers/workspaces_endpoints.py +64 -0
  164. zenml/zen_server/zen_server_api.py +2 -0
  165. zenml/zen_stores/migrations/utils.py +1 -1
  166. zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
  167. zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
  168. zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
  169. zenml/zen_stores/rest_zen_store.py +145 -4
  170. zenml/zen_stores/schemas/stack_schemas.py +10 -0
  171. zenml/zen_stores/schemas/step_run_schemas.py +27 -11
  172. zenml/zen_stores/sql_zen_store.py +300 -6
  173. zenml/zen_stores/zen_store_interface.py +80 -0
  174. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +32 -10
  175. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +178 -162
  176. zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
  177. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
  178. zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
  179. zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
  180. zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
  181. zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
  182. zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
  183. zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
  184. zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
  185. zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
  186. zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
  187. zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
  188. zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
  189. zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
  190. zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
  191. zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
  192. zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
  193. zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
  194. zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
  195. zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
  196. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
  197. zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
  198. zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
  199. zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
  200. zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
  201. zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
  202. zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
  203. zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
  204. zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
  205. zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
  206. zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
  207. zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
  208. zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
  209. zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
  210. zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
  211. zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
  212. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
  213. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
  214. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
@@ -15,6 +15,7 @@
15
15
 
16
16
  import os
17
17
  import re
18
+ from datetime import datetime
18
19
  from pathlib import Path
19
20
  from typing import (
20
21
  Any,
@@ -57,6 +58,7 @@ from zenml.constants import (
57
58
  ARTIFACTS,
58
59
  CODE_REFERENCES,
59
60
  CODE_REPOSITORIES,
61
+ CONFIG,
60
62
  CURRENT_USER,
61
63
  DEACTIVATE,
62
64
  DEFAULT_HTTP_TIMEOUT,
@@ -65,6 +67,7 @@ from zenml.constants import (
65
67
  ENV_ZENML_DISABLE_CLIENT_SERVER_MISMATCH_WARNING,
66
68
  EVENT_SOURCES,
67
69
  FLAVORS,
70
+ FULL_STACK,
68
71
  GET_OR_CREATE,
69
72
  INFO,
70
73
  LOGIN,
@@ -89,9 +92,12 @@ from zenml.constants import (
89
92
  SERVICE_CONNECTOR_RESOURCES,
90
93
  SERVICE_CONNECTOR_TYPES,
91
94
  SERVICE_CONNECTOR_VERIFY,
95
+ SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
92
96
  SERVICE_CONNECTORS,
93
97
  SERVICES,
98
+ STACK,
94
99
  STACK_COMPONENTS,
100
+ STACK_DEPLOYMENT,
95
101
  STACKS,
96
102
  STEPS,
97
103
  TAGS,
@@ -103,6 +109,7 @@ from zenml.constants import (
103
109
  )
104
110
  from zenml.enums import (
105
111
  OAuthGrantTypes,
112
+ StackDeploymentProvider,
106
113
  StoreType,
107
114
  )
108
115
  from zenml.exceptions import AuthorizationException, MethodNotAllowedError
@@ -139,6 +146,7 @@ from zenml.models import (
139
146
  ComponentRequest,
140
147
  ComponentResponse,
141
148
  ComponentUpdate,
149
+ DeployedStack,
142
150
  EventSourceFilter,
143
151
  EventSourceRequest,
144
152
  EventSourceResponse,
@@ -147,6 +155,7 @@ from zenml.models import (
147
155
  FlavorRequest,
148
156
  FlavorResponse,
149
157
  FlavorUpdate,
158
+ FullStackRequest,
150
159
  LogsResponse,
151
160
  ModelFilter,
152
161
  ModelRequest,
@@ -208,6 +217,8 @@ from zenml.models import (
208
217
  ServiceRequest,
209
218
  ServiceResponse,
210
219
  ServiceUpdate,
220
+ StackDeploymentConfig,
221
+ StackDeploymentInfo,
211
222
  StackFilter,
212
223
  StackRequest,
213
224
  StackResponse,
@@ -2467,6 +2478,10 @@ class RestZenStore(BaseZenStore):
2467
2478
  f"{SERVICE_CONNECTORS}{SERVICE_CONNECTOR_VERIFY}",
2468
2479
  body=service_connector,
2469
2480
  params={"list_resources": list_resources},
2481
+ timeout=max(
2482
+ self.config.http_timeout,
2483
+ SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
2484
+ ),
2470
2485
  )
2471
2486
 
2472
2487
  resources = ServiceConnectorResourcesModel.model_validate(
@@ -2504,6 +2519,10 @@ class RestZenStore(BaseZenStore):
2504
2519
  response_body = self.put(
2505
2520
  f"{SERVICE_CONNECTORS}/{str(service_connector_id)}{SERVICE_CONNECTOR_VERIFY}",
2506
2521
  params=params,
2522
+ timeout=max(
2523
+ self.config.http_timeout,
2524
+ SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
2525
+ ),
2507
2526
  )
2508
2527
 
2509
2528
  resources = ServiceConnectorResourcesModel.model_validate(
@@ -2744,6 +2763,23 @@ class RestZenStore(BaseZenStore):
2744
2763
  response_model=StackResponse,
2745
2764
  )
2746
2765
 
2766
+ def create_full_stack(self, full_stack: FullStackRequest) -> StackResponse:
2767
+ """Register a full-stack.
2768
+
2769
+ Args:
2770
+ full_stack: The full stack configuration.
2771
+
2772
+ Returns:
2773
+ The registered stack.
2774
+ """
2775
+ assert full_stack.workspace is not None
2776
+
2777
+ return self._create_resource(
2778
+ resource=full_stack,
2779
+ response_model=StackResponse,
2780
+ route=f"{WORKSPACES}/{str(full_stack.workspace)}{FULL_STACK}",
2781
+ )
2782
+
2747
2783
  def get_stack(self, stack_id: UUID, hydrate: bool = True) -> StackResponse:
2748
2784
  """Get a stack by its unique ID.
2749
2785
 
@@ -2813,6 +2849,88 @@ class RestZenStore(BaseZenStore):
2813
2849
  route=STACKS,
2814
2850
  )
2815
2851
 
2852
+ # ---------------- Stack deployments-----------------
2853
+
2854
+ def get_stack_deployment_info(
2855
+ self,
2856
+ provider: StackDeploymentProvider,
2857
+ ) -> StackDeploymentInfo:
2858
+ """Get information about a stack deployment provider.
2859
+
2860
+ Args:
2861
+ provider: The stack deployment provider.
2862
+
2863
+ Returns:
2864
+ Information about the stack deployment provider.
2865
+ """
2866
+ body = self.get(
2867
+ f"{STACK_DEPLOYMENT}{INFO}",
2868
+ params={"provider": provider.value},
2869
+ )
2870
+ return StackDeploymentInfo.model_validate(body)
2871
+
2872
+ def get_stack_deployment_config(
2873
+ self,
2874
+ provider: StackDeploymentProvider,
2875
+ stack_name: str,
2876
+ location: Optional[str] = None,
2877
+ ) -> StackDeploymentConfig:
2878
+ """Return the cloud provider console URL and configuration needed to deploy the ZenML stack.
2879
+
2880
+ Args:
2881
+ provider: The stack deployment provider.
2882
+ stack_name: The name of the stack.
2883
+ location: The location where the stack should be deployed.
2884
+
2885
+ Returns:
2886
+ The cloud provider console URL and configuration needed to deploy
2887
+ the ZenML stack to the specified cloud provider.
2888
+ """
2889
+ params = {
2890
+ "provider": provider.value,
2891
+ "stack_name": stack_name,
2892
+ }
2893
+ if location:
2894
+ params["location"] = location
2895
+ body = self.get(f"{STACK_DEPLOYMENT}{CONFIG}", params=params)
2896
+ return StackDeploymentConfig.model_validate(body)
2897
+
2898
+ def get_stack_deployment_stack(
2899
+ self,
2900
+ provider: StackDeploymentProvider,
2901
+ stack_name: str,
2902
+ location: Optional[str] = None,
2903
+ date_start: Optional[datetime] = None,
2904
+ ) -> Optional[DeployedStack]:
2905
+ """Return a matching ZenML stack that was deployed and registered.
2906
+
2907
+ Args:
2908
+ provider: The stack deployment provider.
2909
+ stack_name: The name of the stack.
2910
+ location: The location where the stack should be deployed.
2911
+ date_start: The date when the deployment started.
2912
+
2913
+ Returns:
2914
+ The ZenML stack that was deployed and registered or None if the
2915
+ stack was not found.
2916
+ """
2917
+ params = {
2918
+ "provider": provider.value,
2919
+ "stack_name": stack_name,
2920
+ }
2921
+ if location:
2922
+ params["location"] = location
2923
+ if date_start:
2924
+ params["date_start"] = str(date_start)
2925
+ body = self.get(
2926
+ f"{STACK_DEPLOYMENT}{STACK}",
2927
+ params=params,
2928
+ )
2929
+ if body:
2930
+ return DeployedStack.model_validate(body)
2931
+
2932
+ return None
2933
+
2816
2934
  # ----------------------------- Step runs -----------------------------
2817
2935
 
2818
2936
  def create_run_step(self, step_run: StepRunRequest) -> StepRunResponse:
@@ -3964,6 +4082,7 @@ class RestZenStore(BaseZenStore):
3964
4082
  method: str,
3965
4083
  url: str,
3966
4084
  params: Optional[Dict[str, Any]] = None,
4085
+ timeout: Optional[int] = None,
3967
4086
  **kwargs: Any,
3968
4087
  ) -> Json:
3969
4088
  """Make a request to the REST API.
@@ -3972,6 +4091,7 @@ class RestZenStore(BaseZenStore):
3972
4091
  method: The HTTP method to use.
3973
4092
  url: The URL to request.
3974
4093
  params: The query parameters to pass to the endpoint.
4094
+ timeout: The request timeout in seconds.
3975
4095
  kwargs: Additional keyword arguments to pass to the request.
3976
4096
 
3977
4097
  Returns:
@@ -3994,7 +4114,7 @@ class RestZenStore(BaseZenStore):
3994
4114
  url,
3995
4115
  params=params,
3996
4116
  verify=self.config.verify_ssl,
3997
- timeout=self.config.http_timeout,
4117
+ timeout=timeout or self.config.http_timeout,
3998
4118
  **kwargs,
3999
4119
  )
4000
4120
  )
@@ -4023,13 +4143,18 @@ class RestZenStore(BaseZenStore):
4023
4143
  raise
4024
4144
 
4025
4145
  def get(
4026
- self, path: str, params: Optional[Dict[str, Any]] = None, **kwargs: Any
4146
+ self,
4147
+ path: str,
4148
+ params: Optional[Dict[str, Any]] = None,
4149
+ timeout: Optional[int] = None,
4150
+ **kwargs: Any,
4027
4151
  ) -> Json:
4028
4152
  """Make a GET request to the given endpoint path.
4029
4153
 
4030
4154
  Args:
4031
4155
  path: The path to the endpoint.
4032
4156
  params: The query parameters to pass to the endpoint.
4157
+ timeout: The request timeout in seconds.
4033
4158
  kwargs: Additional keyword arguments to pass to the request.
4034
4159
 
4035
4160
  Returns:
@@ -4037,17 +4162,26 @@ class RestZenStore(BaseZenStore):
4037
4162
  """
4038
4163
  logger.debug(f"Sending GET request to {path}...")
4039
4164
  return self._request(
4040
- "GET", self.url + API + VERSION_1 + path, params=params, **kwargs
4165
+ "GET",
4166
+ self.url + API + VERSION_1 + path,
4167
+ params=params,
4168
+ timeout=timeout,
4169
+ **kwargs,
4041
4170
  )
4042
4171
 
4043
4172
  def delete(
4044
- self, path: str, params: Optional[Dict[str, Any]] = None, **kwargs: Any
4173
+ self,
4174
+ path: str,
4175
+ params: Optional[Dict[str, Any]] = None,
4176
+ timeout: Optional[int] = None,
4177
+ **kwargs: Any,
4045
4178
  ) -> Json:
4046
4179
  """Make a DELETE request to the given endpoint path.
4047
4180
 
4048
4181
  Args:
4049
4182
  path: The path to the endpoint.
4050
4183
  params: The query parameters to pass to the endpoint.
4184
+ timeout: The request timeout in seconds.
4051
4185
  kwargs: Additional keyword arguments to pass to the request.
4052
4186
 
4053
4187
  Returns:
@@ -4058,6 +4192,7 @@ class RestZenStore(BaseZenStore):
4058
4192
  "DELETE",
4059
4193
  self.url + API + VERSION_1 + path,
4060
4194
  params=params,
4195
+ timeout=timeout,
4061
4196
  **kwargs,
4062
4197
  )
4063
4198
 
@@ -4066,6 +4201,7 @@ class RestZenStore(BaseZenStore):
4066
4201
  path: str,
4067
4202
  body: BaseModel,
4068
4203
  params: Optional[Dict[str, Any]] = None,
4204
+ timeout: Optional[int] = None,
4069
4205
  **kwargs: Any,
4070
4206
  ) -> Json:
4071
4207
  """Make a POST request to the given endpoint path.
@@ -4074,6 +4210,7 @@ class RestZenStore(BaseZenStore):
4074
4210
  path: The path to the endpoint.
4075
4211
  body: The body to send.
4076
4212
  params: The query parameters to pass to the endpoint.
4213
+ timeout: The request timeout in seconds.
4077
4214
  kwargs: Additional keyword arguments to pass to the request.
4078
4215
 
4079
4216
  Returns:
@@ -4085,6 +4222,7 @@ class RestZenStore(BaseZenStore):
4085
4222
  self.url + API + VERSION_1 + path,
4086
4223
  data=body.model_dump_json(),
4087
4224
  params=params,
4225
+ timeout=timeout,
4088
4226
  **kwargs,
4089
4227
  )
4090
4228
 
@@ -4093,6 +4231,7 @@ class RestZenStore(BaseZenStore):
4093
4231
  path: str,
4094
4232
  body: Optional[BaseModel] = None,
4095
4233
  params: Optional[Dict[str, Any]] = None,
4234
+ timeout: Optional[int] = None,
4096
4235
  **kwargs: Any,
4097
4236
  ) -> Json:
4098
4237
  """Make a PUT request to the given endpoint path.
@@ -4101,6 +4240,7 @@ class RestZenStore(BaseZenStore):
4101
4240
  path: The path to the endpoint.
4102
4241
  body: The body to send.
4103
4242
  params: The query parameters to pass to the endpoint.
4243
+ timeout: The request timeout in seconds.
4104
4244
  kwargs: Additional keyword arguments to pass to the request.
4105
4245
 
4106
4246
  Returns:
@@ -4113,6 +4253,7 @@ class RestZenStore(BaseZenStore):
4113
4253
  self.url + API + VERSION_1 + path,
4114
4254
  data=data,
4115
4255
  params=params,
4256
+ timeout=timeout,
4116
4257
  **kwargs,
4117
4258
  )
4118
4259
 
@@ -13,6 +13,8 @@
13
13
  # permissions and limitations under the License.
14
14
  """SQL Model Implementations for Stacks."""
15
15
 
16
+ import base64
17
+ import json
16
18
  from datetime import datetime
17
19
  from typing import TYPE_CHECKING, Any, List, Optional
18
20
  from uuid import UUID
@@ -75,6 +77,7 @@ class StackSchema(NamedSchema, table=True):
75
77
 
76
78
  __tablename__ = "stack"
77
79
  stack_spec_path: Optional[str]
80
+ labels: Optional[bytes]
78
81
 
79
82
  workspace_id: UUID = build_foreign_key_field(
80
83
  source=__tablename__,
@@ -124,6 +127,10 @@ class StackSchema(NamedSchema, table=True):
124
127
  ).items():
125
128
  if field == "components":
126
129
  self.components = components
130
+ elif field == "labels":
131
+ self.labels = base64.b64encode(
132
+ json.dumps(stack_update.labels).encode("utf-8")
133
+ )
127
134
  else:
128
135
  setattr(self, field, value)
129
136
 
@@ -158,6 +165,9 @@ class StackSchema(NamedSchema, table=True):
158
165
  workspace=self.workspace.to_model(),
159
166
  components={c.type: [c.to_model()] for c in self.components},
160
167
  stack_spec_path=self.stack_spec_path,
168
+ labels=json.loads(base64.b64decode(self.labels).decode())
169
+ if self.labels
170
+ else None,
161
171
  )
162
172
 
163
173
  return StackResponse(
@@ -192,6 +192,7 @@ class StepRunSchema(NamedSchema, table=True):
192
192
  The created StepRunResponse.
193
193
 
194
194
  Raises:
195
+ ValueError: In case the step run configuration can not be loaded.
195
196
  RuntimeError: If the step run schema does not have a deployment_id
196
197
  or a step_configuration.
197
198
  """
@@ -212,19 +213,34 @@ class StepRunSchema(NamedSchema, table=True):
212
213
  for artifact in self.output_artifacts
213
214
  }
214
215
 
216
+ full_step_config = None
215
217
  if self.deployment is not None:
216
- full_step_config = Step.model_validate(
217
- json.loads(self.deployment.step_configurations)[self.name]
218
- )
219
- elif self.step_configuration is not None:
220
- full_step_config = Step.model_validate_json(
221
- self.step_configuration
222
- )
223
- else:
224
- raise RuntimeError(
225
- "Step run model creation has failed. Each step run entry "
226
- "should either have a deployment_id or step_configuration."
218
+ step_configuration = json.loads(
219
+ self.deployment.step_configurations
227
220
  )
221
+ if self.name in step_configuration:
222
+ full_step_config = Step.model_validate(
223
+ step_configuration[self.name]
224
+ )
225
+ elif not self.step_configuration:
226
+ raise ValueError(
227
+ f"Unable to load the configuration for step `{self.name}` from the"
228
+ f"database. To solve this please delete the pipeline run that this"
229
+ f"step run belongs to. Pipeline Run ID: `{self.pipeline_run_id}`."
230
+ )
231
+
232
+ # the step configuration moved into the deployment - the following case is to ensure
233
+ # backwards compatibility
234
+ if full_step_config is None:
235
+ if self.step_configuration:
236
+ full_step_config = Step.model_validate_json(
237
+ self.step_configuration
238
+ )
239
+ else:
240
+ raise RuntimeError(
241
+ "Step run model creation has failed. Each step run entry "
242
+ "should either have a deployment_id or step_configuration."
243
+ )
228
244
 
229
245
  body = StepRunResponseBody(
230
246
  user=self.user.to_model() if self.user else None,