zenml-nightly 0.58.2.dev20240626__py3-none-any.whl → 0.62.0.dev20240726__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 (266) hide show
  1. README.md +31 -10
  2. RELEASE_NOTES.md +280 -0
  3. zenml/VERSION +1 -1
  4. zenml/__init__.py +2 -0
  5. zenml/analytics/enums.py +3 -0
  6. zenml/cli/__init__.py +28 -0
  7. zenml/cli/artifact.py +1 -2
  8. zenml/cli/integration.py +9 -8
  9. zenml/cli/server.py +6 -0
  10. zenml/cli/stack.py +812 -39
  11. zenml/cli/stack_components.py +9 -0
  12. zenml/cli/text_utils.py +35 -1
  13. zenml/cli/utils.py +127 -10
  14. zenml/client.py +23 -14
  15. zenml/config/docker_settings.py +8 -5
  16. zenml/constants.py +13 -1
  17. zenml/container_registries/base_container_registry.py +1 -0
  18. zenml/enums.py +23 -0
  19. zenml/event_hub/event_hub.py +5 -8
  20. zenml/integrations/__init__.py +1 -0
  21. zenml/integrations/aws/__init__.py +1 -0
  22. zenml/integrations/azure/__init__.py +3 -2
  23. zenml/integrations/constants.py +1 -0
  24. zenml/integrations/databricks/__init__.py +52 -0
  25. zenml/integrations/databricks/flavors/__init__.py +30 -0
  26. zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
  27. zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +147 -0
  28. zenml/integrations/databricks/model_deployers/__init__.py +20 -0
  29. zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
  30. zenml/integrations/databricks/orchestrators/__init__.py +20 -0
  31. zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +497 -0
  32. zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
  33. zenml/integrations/databricks/services/__init__.py +19 -0
  34. zenml/integrations/databricks/services/databricks_deployment.py +407 -0
  35. zenml/integrations/databricks/utils/__init__.py +14 -0
  36. zenml/integrations/databricks/utils/databricks_utils.py +87 -0
  37. zenml/integrations/deepchecks/__init__.py +1 -0
  38. zenml/integrations/discord/__init__.py +1 -0
  39. zenml/integrations/evidently/__init__.py +1 -0
  40. zenml/integrations/facets/__init__.py +1 -0
  41. zenml/integrations/feast/__init__.py +1 -0
  42. zenml/integrations/gcp/__init__.py +3 -1
  43. zenml/integrations/gcp/google_credentials_mixin.py +1 -1
  44. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
  45. zenml/integrations/great_expectations/data_validators/ge_data_validator.py +12 -8
  46. zenml/integrations/huggingface/__init__.py +1 -0
  47. zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +88 -3
  48. zenml/integrations/huggingface/steps/accelerate_runner.py +1 -7
  49. zenml/integrations/integration.py +24 -0
  50. zenml/integrations/kubeflow/__init__.py +3 -0
  51. zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
  52. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
  53. zenml/integrations/kubernetes/__init__.py +3 -1
  54. zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
  55. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +1 -13
  56. zenml/integrations/kubernetes/orchestrators/manifest_utils.py +22 -4
  57. zenml/integrations/kubernetes/pod_settings.py +4 -0
  58. zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
  59. zenml/integrations/langchain/__init__.py +1 -0
  60. zenml/integrations/lightgbm/__init__.py +1 -0
  61. zenml/integrations/mlflow/__init__.py +4 -2
  62. zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +6 -2
  63. zenml/integrations/mlflow/services/mlflow_deployment.py +1 -1
  64. zenml/integrations/neural_prophet/__init__.py +1 -0
  65. zenml/integrations/polars/__init__.py +1 -0
  66. zenml/integrations/prodigy/__init__.py +1 -0
  67. zenml/integrations/pycaret/__init__.py +6 -0
  68. zenml/integrations/registry.py +37 -0
  69. zenml/integrations/s3/artifact_stores/s3_artifact_store.py +17 -6
  70. zenml/integrations/seldon/__init__.py +1 -0
  71. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
  72. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
  73. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
  74. zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
  75. zenml/integrations/skypilot_aws/__init__.py +2 -1
  76. zenml/integrations/skypilot_azure/__init__.py +1 -3
  77. zenml/integrations/skypilot_gcp/__init__.py +1 -1
  78. zenml/integrations/skypilot_lambda/__init__.py +1 -1
  79. zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
  80. zenml/integrations/slack/__init__.py +1 -0
  81. zenml/integrations/tekton/__init__.py +1 -0
  82. zenml/integrations/tensorboard/__init__.py +0 -1
  83. zenml/integrations/tensorflow/__init__.py +18 -6
  84. zenml/integrations/wandb/__init__.py +1 -0
  85. zenml/logging/step_logging.py +34 -35
  86. zenml/materializers/built_in_materializer.py +1 -1
  87. zenml/materializers/cloudpickle_materializer.py +1 -1
  88. zenml/model/model.py +1 -1
  89. zenml/models/__init__.py +11 -0
  90. zenml/models/v2/core/component.py +47 -0
  91. zenml/models/v2/core/model.py +1 -2
  92. zenml/models/v2/core/server_settings.py +0 -20
  93. zenml/models/v2/core/service_connector.py +17 -0
  94. zenml/models/v2/core/stack.py +31 -0
  95. zenml/models/v2/misc/full_stack.py +129 -0
  96. zenml/models/v2/misc/stack_deployment.py +91 -0
  97. zenml/new/pipelines/pipeline.py +1 -1
  98. zenml/new/pipelines/run_utils.py +1 -1
  99. zenml/orchestrators/__init__.py +4 -0
  100. zenml/orchestrators/input_utils.py +3 -6
  101. zenml/orchestrators/step_launcher.py +1 -0
  102. zenml/orchestrators/wheeled_orchestrator.py +147 -0
  103. zenml/service_connectors/service_connector_utils.py +408 -0
  104. zenml/stack/stack.py +3 -6
  105. zenml/stack_deployments/__init__.py +14 -0
  106. zenml/stack_deployments/aws_stack_deployment.py +254 -0
  107. zenml/stack_deployments/azure_stack_deployment.py +179 -0
  108. zenml/stack_deployments/gcp_stack_deployment.py +269 -0
  109. zenml/stack_deployments/stack_deployment.py +218 -0
  110. zenml/stack_deployments/utils.py +48 -0
  111. zenml/steps/base_step.py +7 -5
  112. zenml/utils/function_utils.py +2 -2
  113. zenml/utils/pagination_utils.py +7 -5
  114. zenml/utils/pipeline_docker_image_builder.py +105 -68
  115. zenml/utils/pydantic_utils.py +6 -5
  116. zenml/utils/source_utils.py +4 -1
  117. zenml/zen_server/cloud_utils.py +18 -3
  118. zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-B_YdvmwS.js} +1 -1
  119. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
  120. zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
  121. zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-l_1hUr1S.js} +2 -2
  122. zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
  123. zenml/zen_server/dashboard/assets/AwarenessChannel-CFg5iX4Z.js +1 -0
  124. zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-Dvkx_82E.js} +2 -2
  125. zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +1 -0
  126. zenml/zen_server/dashboard/assets/Commands-DoN1xrEq.js +1 -0
  127. zenml/zen_server/dashboard/assets/CopyButton-Cr7xYEPb.js +2 -0
  128. zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-Ck-nZ43m.js} +7 -7
  129. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
  130. zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
  131. zenml/zen_server/dashboard/assets/Error-kLtljEOM.js +1 -0
  132. zenml/zen_server/dashboard/assets/ExecutionStatus-DguLLgTK.js +1 -0
  133. zenml/zen_server/dashboard/assets/Helpbox-BXUMP21n.js +1 -0
  134. zenml/zen_server/dashboard/assets/Infobox-DSt0O-dm.js +1 -0
  135. zenml/zen_server/dashboard/assets/InlineAvatar-xsrsIGE-.js +1 -0
  136. zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
  137. zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +1 -0
  138. zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
  139. zenml/zen_server/dashboard/assets/SetPassword-BXGTWiwj.js +1 -0
  140. zenml/zen_server/dashboard/assets/SuccessStep-DZC60t0x.js +1 -0
  141. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DGvwFWO1.js} +1 -1
  142. zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
  143. zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
  144. zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-CZBOf6JM.js} +1 -1
  145. zenml/zen_server/dashboard/assets/cloud-only-C_yFCAkP.js +1 -0
  146. zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
  148. zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
  149. zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
  150. zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
  151. zenml/zen_server/dashboard/assets/index-BczVOqUf.js +55 -0
  152. zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +1 -0
  153. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
  154. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
  155. zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-CrHrndTI.js} +1 -1
  156. zenml/zen_server/dashboard/assets/logs-D8k8BVFf.js +1 -0
  157. zenml/zen_server/dashboard/assets/not-found-DYa4pC-C.js +1 -0
  158. zenml/zen_server/dashboard/assets/package-B3fWP-Dh.js +1 -0
  159. zenml/zen_server/dashboard/assets/page-1h_sD1jz.js +1 -0
  160. zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-1iL8aMqs.js} +1 -1
  161. zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-2grKx_MY.js} +1 -1
  162. zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +1 -0
  163. zenml/zen_server/dashboard/assets/page-8a4UMKXZ.js +1 -0
  164. zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-B6h3iaHJ.js} +1 -1
  165. zenml/zen_server/dashboard/assets/page-BDns21Iz.js +1 -0
  166. zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-BhgCDInH.js} +2 -2
  167. zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-Bi-wtWiO.js} +2 -2
  168. zenml/zen_server/dashboard/assets/page-BkeAAYwp.js +1 -0
  169. zenml/zen_server/dashboard/assets/page-BkuQDIf-.js +1 -0
  170. zenml/zen_server/dashboard/assets/page-BnaevhnB.js +1 -0
  171. zenml/zen_server/dashboard/assets/page-Bq0YxkLV.js +1 -0
  172. zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +2 -0
  173. zenml/zen_server/dashboard/assets/page-C6-UGEbH.js +1 -0
  174. zenml/zen_server/dashboard/assets/page-CCNRIt_f.js +1 -0
  175. zenml/zen_server/dashboard/assets/page-CHNxpz3n.js +1 -0
  176. zenml/zen_server/dashboard/assets/page-DgorQFqi.js +1 -0
  177. zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +1 -0
  178. zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-MFQyIJd3.js} +1 -1
  179. zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +1 -0
  180. zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +9 -0
  181. zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-uA5prJGY.js} +1 -1
  182. zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +1 -0
  183. zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
  184. zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +1 -0
  185. zenml/zen_server/dashboard/assets/stack-detail-query-Cficsl6d.js +1 -0
  186. zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
  187. zenml/zen_server/dashboard/assets/update-server-settings-mutation-7d8xi1tS.js +1 -0
  188. zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-D7mAQGUM.js} +1 -1
  189. zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
  190. zenml/zen_server/dashboard/index.html +7 -7
  191. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  192. zenml/zen_server/dashboard_legacy/index.html +1 -1
  193. zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.12246c7548e71e2c4438e496360de80c.js} +4 -4
  194. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  195. zenml/zen_server/dashboard_legacy/static/js/main.3b27024b.chunk.js +2 -0
  196. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.3b27024b.chunk.js.map} +1 -1
  197. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  198. zenml/zen_server/deploy/helm/README.md +2 -2
  199. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
  200. zenml/zen_server/pipeline_deployment/utils.py +57 -44
  201. zenml/zen_server/rbac/utils.py +10 -2
  202. zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
  203. zenml/zen_server/routers/devices_endpoints.py +4 -1
  204. zenml/zen_server/routers/server_endpoints.py +29 -2
  205. zenml/zen_server/routers/service_connectors_endpoints.py +57 -0
  206. zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
  207. zenml/zen_server/routers/steps_endpoints.py +2 -1
  208. zenml/zen_server/routers/workspaces_endpoints.py +64 -0
  209. zenml/zen_server/zen_server_api.py +2 -0
  210. zenml/zen_stores/migrations/utils.py +1 -1
  211. zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
  212. zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
  213. zenml/zen_stores/migrations/versions/0.62.0_release.py +23 -0
  214. zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
  215. zenml/zen_stores/migrations/versions/b4fca5241eea_migrate_onboarding_state.py +167 -0
  216. zenml/zen_stores/rest_zen_store.py +149 -4
  217. zenml/zen_stores/schemas/component_schemas.py +14 -0
  218. zenml/zen_stores/schemas/server_settings_schemas.py +23 -11
  219. zenml/zen_stores/schemas/stack_schemas.py +10 -0
  220. zenml/zen_stores/schemas/step_run_schemas.py +27 -11
  221. zenml/zen_stores/sql_zen_store.py +450 -6
  222. zenml/zen_stores/zen_store_interface.py +80 -0
  223. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/METADATA +35 -13
  224. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/RECORD +227 -191
  225. zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
  226. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
  227. zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
  228. zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
  229. zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
  230. zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
  231. zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
  232. zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
  233. zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
  234. zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
  235. zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
  236. zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
  237. zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
  238. zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
  239. zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
  240. zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
  241. zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
  242. zenml/zen_server/dashboard/assets/chevron-down-zcvCWmyP.js +0 -1
  243. zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
  244. zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
  245. zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
  246. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
  247. zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
  248. zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
  249. zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
  250. zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
  251. zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
  252. zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
  253. zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
  254. zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
  255. zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
  256. zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
  257. zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
  258. zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
  259. zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
  260. zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
  261. zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
  262. zenml/zen_server/dashboard/assets/update-server-settings-mutation-0Wgz8pUE.js +0 -1
  263. zenml/zen_server/dashboard_legacy/static/js/main.ac2f17d0.chunk.js +0 -2
  264. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/LICENSE +0 -0
  265. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/WHEEL +0 -0
  266. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/entry_points.txt +0 -0
@@ -33,6 +33,7 @@ from typing import (
33
33
  NoReturn,
34
34
  Optional,
35
35
  Sequence,
36
+ Set,
36
37
  Tuple,
37
38
  Type,
38
39
  TypeVar,
@@ -107,10 +108,12 @@ from zenml.enums import (
107
108
  ExecutionStatus,
108
109
  LoggingLevels,
109
110
  ModelStages,
111
+ OnboardingStep,
110
112
  SecretScope,
111
113
  SecretsStoreType,
112
114
  SorterOps,
113
115
  StackComponentType,
116
+ StackDeploymentProvider,
114
117
  StepRunInputArtifactType,
115
118
  StepRunOutputArtifactType,
116
119
  StoreType,
@@ -164,6 +167,7 @@ from zenml.models import (
164
167
  ComponentRequest,
165
168
  ComponentResponse,
166
169
  ComponentUpdate,
170
+ DeployedStack,
167
171
  EventSourceFilter,
168
172
  EventSourceRequest,
169
173
  EventSourceResponse,
@@ -172,6 +176,7 @@ from zenml.models import (
172
176
  FlavorRequest,
173
177
  FlavorResponse,
174
178
  FlavorUpdate,
179
+ FullStackRequest,
175
180
  LogsResponse,
176
181
  ModelFilter,
177
182
  ModelRequest,
@@ -242,6 +247,8 @@ from zenml.models import (
242
247
  ServiceRequest,
243
248
  ServiceResponse,
244
249
  ServiceUpdate,
250
+ StackDeploymentConfig,
251
+ StackDeploymentInfo,
245
252
  StackFilter,
246
253
  StackRequest,
247
254
  StackResponse,
@@ -279,6 +286,7 @@ from zenml.service_connectors.service_connector_registry import (
279
286
  service_connector_registry,
280
287
  )
281
288
  from zenml.stack.flavor_registry import FlavorRegistry
289
+ from zenml.stack_deployments.utils import get_stack_deployment_class
282
290
  from zenml.utils import uuid_utils
283
291
  from zenml.utils.enum_utils import StrEnum
284
292
  from zenml.utils.networking_utils import (
@@ -792,6 +800,7 @@ class SqlZenStore(BaseZenStore):
792
800
  _secrets_store: Optional[BaseSecretsStore] = None
793
801
  _backup_secrets_store: Optional[BaseSecretsStore] = None
794
802
  _should_send_user_enriched_events: bool = False
803
+ _cached_onboarding_state: Optional[Set[str]] = None
795
804
 
796
805
  @property
797
806
  def secrets_store(self) -> "BaseSecretsStore":
@@ -1548,12 +1557,18 @@ class SqlZenStore(BaseZenStore):
1548
1557
  revisions_afterwards = self.alembic.current_revisions()
1549
1558
 
1550
1559
  if current_revisions != revisions_afterwards:
1551
- if current_revisions and version.parse(
1552
- current_revisions[0]
1553
- ) < version.parse("0.57.1"):
1554
- # We want to send the missing user enriched events for users
1555
- # which were created pre 0.57.1 and only on one upgrade
1556
- self._should_send_user_enriched_events = True
1560
+ try:
1561
+ if current_revisions and version.parse(
1562
+ current_revisions[0]
1563
+ ) < version.parse("0.57.1"):
1564
+ # We want to send the missing user enriched events for users
1565
+ # which were created pre 0.57.1 and only on one upgrade
1566
+ self._should_send_user_enriched_events = True
1567
+ except version.InvalidVersion:
1568
+ # This can happen if the database is not currently
1569
+ # stamped with an official ZenML version (e.g. in
1570
+ # development environments).
1571
+ pass
1557
1572
 
1558
1573
  self._sync_flavors()
1559
1574
 
@@ -1677,6 +1692,60 @@ class SqlZenStore(BaseZenStore):
1677
1692
 
1678
1693
  return settings.to_model(include_metadata=True)
1679
1694
 
1695
+ def get_onboarding_state(self) -> List[str]:
1696
+ """Get the server onboarding state.
1697
+
1698
+ Returns:
1699
+ The server onboarding state.
1700
+ """
1701
+ with Session(self.engine) as session:
1702
+ settings = self._get_server_settings(session=session)
1703
+ if settings.onboarding_state:
1704
+ self._cached_onboarding_state = set(
1705
+ json.loads(settings.onboarding_state)
1706
+ )
1707
+ return list(self._cached_onboarding_state)
1708
+ else:
1709
+ return []
1710
+
1711
+ def _update_onboarding_state(
1712
+ self, completed_steps: Set[str], session: Session
1713
+ ) -> None:
1714
+ """Update the server onboarding state.
1715
+
1716
+ Args:
1717
+ completed_steps: Newly completed onboarding steps.
1718
+ session: DB session.
1719
+ """
1720
+ if self._cached_onboarding_state and completed_steps.issubset(
1721
+ self._cached_onboarding_state
1722
+ ):
1723
+ # All the onboarding steps are already completed, no need to query
1724
+ # the DB
1725
+ return
1726
+
1727
+ settings = self._get_server_settings(session=session)
1728
+ settings.update_onboarding_state(completed_steps=completed_steps)
1729
+ session.add(settings)
1730
+ session.commit()
1731
+ session.refresh(settings)
1732
+
1733
+ assert settings.onboarding_state
1734
+ self._cached_onboarding_state = set(
1735
+ json.loads(settings.onboarding_state)
1736
+ )
1737
+
1738
+ def update_onboarding_state(self, completed_steps: Set[str]) -> None:
1739
+ """Update the server onboarding state.
1740
+
1741
+ Args:
1742
+ completed_steps: Newly completed onboarding steps.
1743
+ """
1744
+ with Session(self.engine) as session:
1745
+ self._update_onboarding_state(
1746
+ completed_steps=completed_steps, session=session
1747
+ )
1748
+
1680
1749
  def activate_server(
1681
1750
  self, request: ServerActivationRequest
1682
1751
  ) -> Optional[UserResponse]:
@@ -3117,6 +3186,29 @@ class SqlZenStore(BaseZenStore):
3117
3186
  "found."
3118
3187
  )
3119
3188
 
3189
+ # warn about skypilot regions, if needed
3190
+ if component.flavor in {"vm_gcp", "vm_azure"}:
3191
+ stack_deployment_class = get_stack_deployment_class(
3192
+ StackDeploymentProvider.GCP
3193
+ if component.flavor == "vm_gcp"
3194
+ else StackDeploymentProvider.AZURE
3195
+ )
3196
+ skypilot_regions = (
3197
+ stack_deployment_class.skypilot_default_regions().values()
3198
+ )
3199
+ if (
3200
+ component.configuration.get("region", None)
3201
+ and component.configuration["region"]
3202
+ not in skypilot_regions
3203
+ ):
3204
+ logger.warning(
3205
+ f"Region `{component.configuration['region']}` is not enabled in Skypilot "
3206
+ f"by default. Supported regions by default are: {skypilot_regions}. "
3207
+ "Check the Skypilot documentation to learn how to enable regions rather "
3208
+ "than default ones. (If you have already extended your configuration - "
3209
+ "simply ignore this warning)"
3210
+ )
3211
+
3120
3212
  # Create the component
3121
3213
  new_component = StackComponentSchema(
3122
3214
  name=component.name,
@@ -6145,6 +6237,7 @@ class SqlZenStore(BaseZenStore):
6145
6237
 
6146
6238
  connector = new_service_connector.to_model(include_metadata=True)
6147
6239
  self._populate_connector_type(connector)
6240
+
6148
6241
  return connector
6149
6242
 
6150
6243
  def get_service_connector(
@@ -6911,14 +7004,283 @@ class SqlZenStore(BaseZenStore):
6911
7004
  name=stack.name,
6912
7005
  description=stack.description,
6913
7006
  components=defined_components,
7007
+ labels=base64.b64encode(
7008
+ json.dumps(stack.labels).encode("utf-8")
7009
+ ),
6914
7010
  )
6915
7011
 
6916
7012
  session.add(new_stack_schema)
6917
7013
  session.commit()
6918
7014
  session.refresh(new_stack_schema)
6919
7015
 
7016
+ for component in defined_components:
7017
+ if component.type == StackComponentType.ORCHESTRATOR:
7018
+ if component.flavor not in {"local", "local_docker"}:
7019
+ self._update_onboarding_state(
7020
+ completed_steps={
7021
+ OnboardingStep.STACK_WITH_REMOTE_ORCHESTRATOR_CREATED
7022
+ },
7023
+ session=session,
7024
+ )
7025
+
6920
7026
  return new_stack_schema.to_model(include_metadata=True)
6921
7027
 
7028
+ def create_full_stack(self, full_stack: FullStackRequest) -> StackResponse:
7029
+ """Register a full stack.
7030
+
7031
+ Args:
7032
+ full_stack: The full stack configuration.
7033
+
7034
+ Returns:
7035
+ The registered stack.
7036
+
7037
+ Raises:
7038
+ ValueError: If the full stack creation fails, due to the corrupted
7039
+ input.
7040
+ RuntimeError: If the full stack creation fails, due to unforeseen
7041
+ errors.
7042
+ """
7043
+ # For clean-up purposes, each created entity is tracked here
7044
+ service_connectors_created_ids: List[UUID] = []
7045
+ components_created_ids: List[UUID] = []
7046
+
7047
+ try:
7048
+ # Validate the name of the new stack
7049
+ validate_name(full_stack)
7050
+
7051
+ if full_stack.labels is None:
7052
+ full_stack.labels = {}
7053
+
7054
+ full_stack.labels.update({"zenml:full_stack": True})
7055
+
7056
+ # Service Connectors
7057
+ service_connectors: List[ServiceConnectorResponse] = []
7058
+
7059
+ need_to_generate_permanent_tokens = False
7060
+ orchestrator_component = full_stack.components[
7061
+ StackComponentType.ORCHESTRATOR
7062
+ ]
7063
+ if isinstance(orchestrator_component, UUID):
7064
+ orchestrator = self.get_stack_component(
7065
+ orchestrator_component,
7066
+ hydrate=False,
7067
+ )
7068
+ need_to_generate_permanent_tokens = (
7069
+ orchestrator.flavor.startswith("vm_")
7070
+ )
7071
+ else:
7072
+ need_to_generate_permanent_tokens = (
7073
+ orchestrator_component.flavor.startswith("vm_")
7074
+ )
7075
+
7076
+ for connector_id_or_info in full_stack.service_connectors:
7077
+ # Fetch an existing service connector
7078
+ if isinstance(connector_id_or_info, UUID):
7079
+ existing_service_connector = self.get_service_connector(
7080
+ connector_id_or_info
7081
+ )
7082
+ if need_to_generate_permanent_tokens:
7083
+ if (
7084
+ existing_service_connector.configuration.get(
7085
+ "generate_temporary_tokens", None
7086
+ )
7087
+ is not False
7088
+ ):
7089
+ self.update_service_connector(
7090
+ existing_service_connector.id,
7091
+ ServiceConnectorUpdate(
7092
+ configuration=existing_service_connector.configuration.update(
7093
+ {"generate_temporary_tokens": False}
7094
+ )
7095
+ ),
7096
+ )
7097
+ service_connectors.append(
7098
+ self.get_service_connector(connector_id_or_info)
7099
+ )
7100
+ # Create a new service connector
7101
+ else:
7102
+ connector_name = full_stack.name
7103
+ while True:
7104
+ try:
7105
+ service_connector_request = ServiceConnectorRequest(
7106
+ name=connector_name,
7107
+ connector_type=connector_id_or_info.type,
7108
+ auth_method=connector_id_or_info.auth_method,
7109
+ configuration=connector_id_or_info.configuration.update(
7110
+ {
7111
+ "generate_temporary_tokens": not need_to_generate_permanent_tokens
7112
+ }
7113
+ ),
7114
+ user=full_stack.user,
7115
+ workspace=full_stack.workspace,
7116
+ labels={
7117
+ k: str(v)
7118
+ for k, v in full_stack.labels.items()
7119
+ },
7120
+ )
7121
+ service_connector_response = (
7122
+ self.create_service_connector(
7123
+ service_connector=service_connector_request
7124
+ )
7125
+ )
7126
+ service_connectors.append(
7127
+ service_connector_response
7128
+ )
7129
+ service_connectors_created_ids.append(
7130
+ service_connector_response.id
7131
+ )
7132
+ break
7133
+ except EntityExistsError:
7134
+ connector_name = (
7135
+ f"{full_stack.name}-{random_str(4)}".lower()
7136
+ )
7137
+ continue
7138
+
7139
+ # Stack Components
7140
+ components_mapping: Dict[StackComponentType, List[UUID]] = {}
7141
+ for (
7142
+ component_type,
7143
+ component_info,
7144
+ ) in full_stack.components.items():
7145
+ # Fetch an existing component
7146
+ if isinstance(component_info, UUID):
7147
+ component = self.get_stack_component(
7148
+ component_id=component_info
7149
+ )
7150
+ # Create a new component
7151
+ else:
7152
+ flavor_list = self.list_flavors(
7153
+ flavor_filter_model=FlavorFilter(
7154
+ name=component_info.flavor,
7155
+ type=component_type,
7156
+ )
7157
+ )
7158
+ if not len(flavor_list):
7159
+ raise ValueError(
7160
+ f"Flavor '{component_info.flavor}' not found "
7161
+ f"for component type '{component_type}'."
7162
+ )
7163
+
7164
+ flavor_model = flavor_list[0]
7165
+
7166
+ component_name = full_stack.name
7167
+ while True:
7168
+ try:
7169
+ component_request = ComponentRequest(
7170
+ name=component_name,
7171
+ type=component_type,
7172
+ flavor=component_info.flavor,
7173
+ configuration=component_info.configuration,
7174
+ user=full_stack.user,
7175
+ workspace=full_stack.workspace,
7176
+ labels=full_stack.labels,
7177
+ )
7178
+ component = self.create_stack_component(
7179
+ component=component_request
7180
+ )
7181
+ components_created_ids.append(component.id)
7182
+ break
7183
+ except EntityExistsError:
7184
+ component_name = (
7185
+ f"{full_stack.name}-{random_str(4)}".lower()
7186
+ )
7187
+ continue
7188
+
7189
+ if component_info.service_connector_index is not None:
7190
+ service_connector = service_connectors[
7191
+ component_info.service_connector_index
7192
+ ]
7193
+
7194
+ requirements = flavor_model.connector_requirements
7195
+
7196
+ if not requirements:
7197
+ raise ValueError(
7198
+ f"The '{flavor_model.name}' implementation "
7199
+ "does not support using a service connector to "
7200
+ "connect to resources."
7201
+ )
7202
+
7203
+ if component_info.service_connector_resource_id:
7204
+ resource_id = (
7205
+ component_info.service_connector_resource_id
7206
+ )
7207
+ else:
7208
+ resource_id = None
7209
+ resource_type = requirements.resource_type
7210
+ if requirements.resource_id_attr is not None:
7211
+ resource_id = component_info.configuration.get(
7212
+ requirements.resource_id_attr
7213
+ )
7214
+
7215
+ satisfied, msg = requirements.is_satisfied_by(
7216
+ connector=service_connector,
7217
+ component=component,
7218
+ )
7219
+
7220
+ if not satisfied:
7221
+ raise ValueError(
7222
+ "Please pick a connector that is "
7223
+ "compatible with the component flavor and "
7224
+ "try again.."
7225
+ )
7226
+
7227
+ if not resource_id:
7228
+ if service_connector.resource_id:
7229
+ resource_id = service_connector.resource_id
7230
+ elif service_connector.supports_instances:
7231
+ raise ValueError(
7232
+ f"Multiple {resource_type} resources "
7233
+ "are available for the selected "
7234
+ "connector. Please use a `resource_id` "
7235
+ "to configure a "
7236
+ f"{resource_type} resource."
7237
+ )
7238
+
7239
+ component_update = ComponentUpdate(
7240
+ connector=service_connector.id,
7241
+ connector_resource_id=resource_id,
7242
+ )
7243
+ self.update_stack_component(
7244
+ component_id=component.id,
7245
+ component_update=component_update,
7246
+ )
7247
+
7248
+ components_mapping[component_type] = [
7249
+ component.id,
7250
+ ]
7251
+
7252
+ # Stack
7253
+ stack_name = full_stack.name
7254
+ while True:
7255
+ try:
7256
+ stack_request = StackRequest(
7257
+ user=full_stack.user,
7258
+ workspace=full_stack.workspace,
7259
+ name=stack_name,
7260
+ description=full_stack.description,
7261
+ components=components_mapping,
7262
+ labels=full_stack.labels,
7263
+ )
7264
+ stack_response = self.create_stack(stack_request)
7265
+
7266
+ break
7267
+ except EntityExistsError:
7268
+ stack_name = f"{full_stack.name}-{random_str(4)}".lower()
7269
+
7270
+ return stack_response
7271
+
7272
+ except Exception as e:
7273
+ for component_id in components_created_ids:
7274
+ self.delete_stack_component(component_id=component_id)
7275
+ for service_connector_id in service_connectors_created_ids:
7276
+ self.delete_service_connector(
7277
+ service_connector_id=service_connector_id
7278
+ )
7279
+ raise RuntimeError(
7280
+ f"Full Stack creation has failed {e}. Cleaning up the "
7281
+ f"created entities."
7282
+ ) from e
7283
+
6922
7284
  def get_stack(self, stack_id: UUID, hydrate: bool = True) -> StackResponse:
6923
7285
  """Get a stack by its unique ID.
6924
7286
 
@@ -7195,6 +7557,69 @@ class SqlZenStore(BaseZenStore):
7195
7557
  workspace_id=workspace.id,
7196
7558
  )
7197
7559
 
7560
+ # ---------------- Stack deployments-----------------
7561
+
7562
+ def get_stack_deployment_info(
7563
+ self,
7564
+ provider: StackDeploymentProvider,
7565
+ ) -> StackDeploymentInfo:
7566
+ """Get information about a stack deployment provider.
7567
+
7568
+ Args:
7569
+ provider: The stack deployment provider.
7570
+
7571
+ Raises:
7572
+ NotImplementedError: Stack deployments are not supported by the
7573
+ local ZenML deployment.
7574
+ """
7575
+ raise NotImplementedError(
7576
+ "Stack deployments are not supported by local ZenML deployments."
7577
+ )
7578
+
7579
+ def get_stack_deployment_config(
7580
+ self,
7581
+ provider: StackDeploymentProvider,
7582
+ stack_name: str,
7583
+ location: Optional[str] = None,
7584
+ ) -> StackDeploymentConfig:
7585
+ """Return the cloud provider console URL and configuration needed to deploy the ZenML stack.
7586
+
7587
+ Args:
7588
+ provider: The stack deployment provider.
7589
+ stack_name: The name of the stack.
7590
+ location: The location where the stack should be deployed.
7591
+
7592
+ Raises:
7593
+ NotImplementedError: Stack deployments are not supported by the
7594
+ local ZenML deployment.
7595
+ """
7596
+ raise NotImplementedError(
7597
+ "Stack deployments are not supported by local ZenML deployments."
7598
+ )
7599
+
7600
+ def get_stack_deployment_stack(
7601
+ self,
7602
+ provider: StackDeploymentProvider,
7603
+ stack_name: str,
7604
+ location: Optional[str] = None,
7605
+ date_start: Optional[datetime] = None,
7606
+ ) -> Optional[DeployedStack]:
7607
+ """Return a matching ZenML stack that was deployed and registered.
7608
+
7609
+ Args:
7610
+ provider: The stack deployment provider.
7611
+ stack_name: The name of the stack.
7612
+ location: The location where the stack should be deployed.
7613
+ date_start: The date when the deployment started.
7614
+
7615
+ Raises:
7616
+ NotImplementedError: Stack deployments are not supported by the
7617
+ local ZenML deployment.
7618
+ """
7619
+ raise NotImplementedError(
7620
+ "Stack deployments are not supported by local ZenML deployments."
7621
+ )
7622
+
7198
7623
  # ----------------------------- Step runs -----------------------------
7199
7624
 
7200
7625
  def create_run_step(self, step_run: StepRunRequest) -> StepRunResponse:
@@ -7671,6 +8096,25 @@ class SqlZenStore(BaseZenStore):
7671
8096
  "duration_seconds": duration_seconds,
7672
8097
  **stack_metadata,
7673
8098
  }
8099
+
8100
+ completed_onboarding_steps: Set[str] = {
8101
+ OnboardingStep.PIPELINE_RUN,
8102
+ OnboardingStep.STARTER_SETUP_COMPLETED,
8103
+ }
8104
+ if stack_metadata["orchestrator"] not in {
8105
+ "local",
8106
+ "local_docker",
8107
+ }:
8108
+ completed_onboarding_steps.update(
8109
+ {
8110
+ OnboardingStep.PIPELINE_RUN_WITH_REMOTE_ORCHESTRATOR,
8111
+ OnboardingStep.PRODUCTION_SETUP_COMPLETED,
8112
+ }
8113
+ )
8114
+
8115
+ self._update_onboarding_state(
8116
+ completed_steps=completed_onboarding_steps, session=session
8117
+ )
7674
8118
  pipeline_run.update(run_update)
7675
8119
  session.add(pipeline_run)
7676
8120
 
@@ -13,11 +13,13 @@
13
13
  # permissions and limitations under the License.
14
14
  """ZenML Store interface."""
15
15
 
16
+ import datetime
16
17
  from abc import ABC, abstractmethod
17
18
  from typing import List, Optional, Tuple, Union
18
19
  from uuid import UUID
19
20
 
20
21
  from zenml.config.pipeline_run_configuration import PipelineRunConfiguration
22
+ from zenml.enums import StackDeploymentProvider
21
23
  from zenml.models import (
22
24
  ActionFilter,
23
25
  ActionRequest,
@@ -46,6 +48,7 @@ from zenml.models import (
46
48
  ComponentRequest,
47
49
  ComponentResponse,
48
50
  ComponentUpdate,
51
+ DeployedStack,
49
52
  EventSourceFilter,
50
53
  EventSourceRequest,
51
54
  EventSourceResponse,
@@ -54,6 +57,7 @@ from zenml.models import (
54
57
  FlavorRequest,
55
58
  FlavorResponse,
56
59
  FlavorUpdate,
60
+ FullStackRequest,
57
61
  LogsResponse,
58
62
  ModelFilter,
59
63
  ModelRequest,
@@ -115,6 +119,8 @@ from zenml.models import (
115
119
  ServiceRequest,
116
120
  ServiceResponse,
117
121
  ServiceUpdate,
122
+ StackDeploymentConfig,
123
+ StackDeploymentInfo,
118
124
  StackFilter,
119
125
  StackRequest,
120
126
  StackResponse,
@@ -2166,6 +2172,24 @@ class ZenStoreInterface(ABC):
2166
2172
  by this user in this workspace.
2167
2173
  """
2168
2174
 
2175
+ @abstractmethod
2176
+ def create_full_stack(self, full_stack: FullStackRequest) -> StackResponse:
2177
+ """Create a full stack.
2178
+
2179
+ Args:
2180
+ full_stack: The full stack configuration.
2181
+
2182
+ Returns:
2183
+ The created stack.
2184
+
2185
+ Raises:
2186
+ EntityExistsError: If a service connector with the same name
2187
+ already exists.
2188
+ StackComponentExistsError: If a stack component with the same name
2189
+ already exists.
2190
+ StackExistsError: If a stack with the same name already exists.
2191
+ """
2192
+
2169
2193
  @abstractmethod
2170
2194
  def get_stack(self, stack_id: UUID, hydrate: bool = True) -> StackResponse:
2171
2195
  """Get a stack by its unique ID.
@@ -2228,6 +2252,62 @@ class ZenStoreInterface(ABC):
2228
2252
  KeyError: if the stack doesn't exist.
2229
2253
  """
2230
2254
 
2255
+ # ---------------- Stack deployments-----------------
2256
+
2257
+ @abstractmethod
2258
+ def get_stack_deployment_info(
2259
+ self,
2260
+ provider: StackDeploymentProvider,
2261
+ ) -> StackDeploymentInfo:
2262
+ """Get information about a stack deployment provider.
2263
+
2264
+ Args:
2265
+ provider: The stack deployment provider.
2266
+
2267
+ Returns:
2268
+ Information about the stack deployment provider.
2269
+ """
2270
+
2271
+ @abstractmethod
2272
+ def get_stack_deployment_config(
2273
+ self,
2274
+ provider: StackDeploymentProvider,
2275
+ stack_name: str,
2276
+ location: Optional[str] = None,
2277
+ ) -> StackDeploymentConfig:
2278
+ """Return the cloud provider console URL and configuration needed to deploy the ZenML stack.
2279
+
2280
+ Args:
2281
+ provider: The stack deployment provider.
2282
+ stack_name: The name of the stack.
2283
+ location: The location where the stack should be deployed.
2284
+
2285
+ Returns:
2286
+ The cloud provider console URL and configuration needed to deploy
2287
+ the ZenML stack to the specified cloud provider.
2288
+ """
2289
+
2290
+ @abstractmethod
2291
+ def get_stack_deployment_stack(
2292
+ self,
2293
+ provider: StackDeploymentProvider,
2294
+ stack_name: str,
2295
+ location: Optional[str] = None,
2296
+ date_start: Optional[datetime.datetime] = None,
2297
+ ) -> Optional[DeployedStack]:
2298
+ """Return a matching ZenML stack that was deployed and registered.
2299
+
2300
+ Args:
2301
+ provider: The stack deployment provider.
2302
+ stack_name: The name of the stack.
2303
+ location: The location where the stack should be deployed.
2304
+ date_start: The date when the deployment started.
2305
+
2306
+ Returns:
2307
+ The ZenML stack that was deployed and registered or None if the
2308
+ stack was not found.
2309
+ """
2310
+
2231
2311
  # -------------------- Step runs --------------------
2232
2312
 
2233
2313
  @abstractmethod