zenml-nightly 0.62.0.dev20240729__py3-none-any.whl → 0.64.0.dev20240809__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 (240) hide show
  1. README.md +2 -2
  2. RELEASE_NOTES.md +120 -0
  3. zenml/VERSION +1 -1
  4. zenml/__init__.py +0 -4
  5. zenml/actions/pipeline_run/pipeline_run_action.py +19 -17
  6. zenml/analytics/enums.py +4 -6
  7. zenml/cli/__init__.py +28 -76
  8. zenml/cli/base.py +2 -2
  9. zenml/cli/pipeline.py +54 -61
  10. zenml/cli/stack.py +6 -8
  11. zenml/cli/web_login.py +8 -0
  12. zenml/client.py +232 -103
  13. zenml/config/build_configuration.py +43 -17
  14. zenml/config/compiler.py +14 -22
  15. zenml/config/docker_settings.py +80 -57
  16. zenml/config/pipeline_run_configuration.py +3 -0
  17. zenml/config/server_config.py +3 -0
  18. zenml/config/source.py +60 -1
  19. zenml/constants.py +11 -2
  20. zenml/entrypoints/base_entrypoint_configuration.py +53 -8
  21. zenml/enums.py +4 -1
  22. zenml/environment.py +25 -9
  23. zenml/image_builders/base_image_builder.py +1 -1
  24. zenml/image_builders/build_context.py +25 -72
  25. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +13 -4
  26. zenml/integrations/azure/__init__.py +4 -0
  27. zenml/integrations/azure/flavors/__init__.py +11 -0
  28. zenml/integrations/azure/flavors/azureml_orchestrator_flavor.py +263 -0
  29. zenml/{_hub → integrations/azure/orchestrators}/__init__.py +7 -2
  30. zenml/integrations/azure/orchestrators/azureml_orchestrator.py +544 -0
  31. zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py +86 -0
  32. zenml/integrations/azure/step_operators/azureml_step_operator.py +3 -0
  33. zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +20 -2
  34. zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +19 -13
  35. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +7 -2
  36. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +123 -6
  37. zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +1 -1
  38. zenml/integrations/mlflow/__init__.py +1 -1
  39. zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +3 -1
  40. zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +3 -0
  41. zenml/logger.py +13 -0
  42. zenml/models/__init__.py +26 -22
  43. zenml/models/v2/base/filter.py +32 -0
  44. zenml/models/v2/core/pipeline.py +73 -89
  45. zenml/models/v2/core/pipeline_build.py +15 -11
  46. zenml/models/v2/core/pipeline_deployment.py +72 -24
  47. zenml/models/v2/core/pipeline_run.py +65 -1
  48. zenml/models/v2/core/run_template.py +393 -0
  49. zenml/models/v2/core/server_settings.py +12 -0
  50. zenml/models/v2/core/user.py +0 -21
  51. zenml/models/v2/misc/server_models.py +7 -1
  52. zenml/models/v2/misc/stack_deployment.py +5 -0
  53. zenml/models/v2/misc/user_auth.py +0 -7
  54. zenml/new/pipelines/build_utils.py +220 -89
  55. zenml/new/pipelines/code_archive.py +157 -0
  56. zenml/new/pipelines/pipeline.py +46 -78
  57. zenml/new/pipelines/run_utils.py +79 -1
  58. zenml/post_execution/pipeline.py +1 -4
  59. zenml/service_connectors/service_connector_utils.py +18 -2
  60. zenml/stack_deployments/aws_stack_deployment.py +32 -8
  61. zenml/stack_deployments/azure_stack_deployment.py +122 -10
  62. zenml/stack_deployments/gcp_stack_deployment.py +36 -7
  63. zenml/stack_deployments/stack_deployment.py +23 -7
  64. zenml/steps/base_step.py +3 -0
  65. zenml/steps/utils.py +0 -4
  66. zenml/utils/archivable.py +149 -0
  67. zenml/utils/code_utils.py +244 -0
  68. zenml/utils/notebook_utils.py +122 -0
  69. zenml/utils/package_utils.py +39 -0
  70. zenml/utils/pipeline_docker_image_builder.py +3 -96
  71. zenml/utils/source_utils.py +109 -1
  72. zenml/zen_server/dashboard/assets/{404-B_YdvmwS.js → 404-CRAA_Lew.js} +1 -1
  73. zenml/zen_server/dashboard/assets/@radix-BXWm7HOa.js +85 -0
  74. zenml/zen_server/dashboard/assets/{@react-router-CO-OsFwI.js → @react-router-l3lMcXA2.js} +1 -1
  75. zenml/zen_server/dashboard/assets/{@reactflow-l_1hUr1S.js → @reactflow-CeVxyqYT.js} +2 -2
  76. zenml/zen_server/dashboard/assets/{@tanstack-DYiOyJUL.js → @tanstack-FmcYZMuX.js} +4 -4
  77. zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-ErO9aOgK.js +1 -0
  78. zenml/zen_server/dashboard/assets/{AwarenessChannel-CFg5iX4Z.js → AwarenessChannel-CLXo5rKM.js} +1 -1
  79. zenml/zen_server/dashboard/assets/{CodeSnippet-Dvkx_82E.js → CodeSnippet-D0VLxT2A.js} +2 -2
  80. zenml/zen_server/dashboard/assets/CollapsibleCard-BaUPiVg0.js +1 -0
  81. zenml/zen_server/dashboard/assets/{Commands-DoN1xrEq.js → Commands-JrcZK-3j.js} +1 -1
  82. zenml/zen_server/dashboard/assets/CopyButton-Dbo52T1K.js +2 -0
  83. zenml/zen_server/dashboard/assets/{CsvVizualization-Ck-nZ43m.js → CsvVizualization-D3kAypDj.js} +3 -3
  84. zenml/zen_server/dashboard/assets/DisplayDate-DizbSeT-.js +1 -0
  85. zenml/zen_server/dashboard/assets/EditSecretDialog-Bd7mFLS4.js +1 -0
  86. zenml/zen_server/dashboard/assets/{EmptyState-BMLnFVlB.js → EmptyState-BHblM39I.js} +1 -1
  87. zenml/zen_server/dashboard/assets/{Error-kLtljEOM.js → Error-C6LeJSER.js} +1 -1
  88. zenml/zen_server/dashboard/assets/{ExecutionStatus-DguLLgTK.js → ExecutionStatus-jH4OrWBq.js} +1 -1
  89. zenml/zen_server/dashboard/assets/{Helpbox-BXUMP21n.js → Helpbox-aAB2XP-z.js} +1 -1
  90. zenml/zen_server/dashboard/assets/{Infobox-DSt0O-dm.js → Infobox-BQ0aty32.js} +1 -1
  91. zenml/zen_server/dashboard/assets/{InlineAvatar-xsrsIGE-.js → InlineAvatar-DpTLgM3Q.js} +1 -1
  92. zenml/zen_server/dashboard/assets/Lock-CNyJvf2r.js +1 -0
  93. zenml/zen_server/dashboard/assets/{MarkdownVisualization-xp3hhULl.js → MarkdownVisualization-Bajxn0HY.js} +1 -1
  94. zenml/zen_server/dashboard/assets/NumberBox-BmKE0qnO.js +1 -0
  95. zenml/zen_server/dashboard/assets/{PasswordChecker-DUveqlva.js → PasswordChecker-yGGoJSB-.js} +1 -1
  96. zenml/zen_server/dashboard/assets/ProviderRadio-BBqkIuTd.js +1 -0
  97. zenml/zen_server/dashboard/assets/RadioItem-xLhXoiFV.js +1 -0
  98. zenml/zen_server/dashboard/assets/SearchField-C9R0mdaX.js +1 -0
  99. zenml/zen_server/dashboard/assets/{SetPassword-BXGTWiwj.js → SetPassword-52sNxNiO.js} +1 -1
  100. zenml/zen_server/dashboard/assets/{SuccessStep-DZC60t0x.js → SuccessStep-DlkItqYG.js} +1 -1
  101. zenml/zen_server/dashboard/assets/Tick-uxv80Q6a.js +1 -0
  102. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DGvwFWO1.js → UpdatePasswordSchemas-oN4G3sKz.js} +1 -1
  103. zenml/zen_server/dashboard/assets/{aws-BgKTfTfx.js → aws-0_3UsPif.js} +1 -1
  104. zenml/zen_server/dashboard/assets/{check-circle-i56092KI.js → check-circle-1_I207rW.js} +1 -1
  105. zenml/zen_server/dashboard/assets/chevron-down-BpaF8JqM.js +1 -0
  106. zenml/zen_server/dashboard/assets/{chevron-right-double-CZBOf6JM.js → chevron-right-double-Dk8e2L99.js} +1 -1
  107. zenml/zen_server/dashboard/assets/{cloud-only-C_yFCAkP.js → cloud-only-BkUuI0lZ.js} +1 -1
  108. zenml/zen_server/dashboard/assets/components-Br2ezRib.js +1 -0
  109. zenml/zen_server/dashboard/assets/{copy-BXNk6BjL.js → copy-f3XGPPxt.js} +1 -1
  110. zenml/zen_server/dashboard/assets/{database-1xWSgZfO.js → database-cXYNX9tt.js} +1 -1
  111. zenml/zen_server/dashboard/assets/{docker-CQMVm_4d.js → docker-8uj__HHK.js} +1 -1
  112. zenml/zen_server/dashboard/assets/dots-horizontal-sKQlWEni.js +1 -0
  113. zenml/zen_server/dashboard/assets/edit-C0MVvPD2.js +1 -0
  114. zenml/zen_server/dashboard/assets/{file-text-CqD_iu6l.js → file-text-B9JibxTs.js} +1 -1
  115. zenml/zen_server/dashboard/assets/{help-bu_DgLKI.js → help-FuHlZwn0.js} +1 -1
  116. zenml/zen_server/dashboard/assets/{index-rK_Wuy2W.js → index-Bd1xgUQG.js} +1 -1
  117. zenml/zen_server/dashboard/assets/index-DaGknux4.css +1 -0
  118. zenml/zen_server/dashboard/assets/{index-BczVOqUf.js → index-DhIZtpxB.js} +5 -5
  119. zenml/zen_server/dashboard/assets/index.esm-DT4uyn2i.js +1 -0
  120. zenml/zen_server/dashboard/assets/layout-D6oiSbfd.js +1 -0
  121. zenml/zen_server/dashboard/assets/{login-mutation-CrHrndTI.js → login-mutation-13A_JSVA.js} +1 -1
  122. zenml/zen_server/dashboard/assets/{logs-D8k8BVFf.js → logs-CgeE2vZP.js} +1 -1
  123. zenml/zen_server/dashboard/assets/{not-found-DYa4pC-C.js → not-found-B0Mmb90p.js} +1 -1
  124. zenml/zen_server/dashboard/assets/package-DdkziX79.js +1 -0
  125. zenml/zen_server/dashboard/assets/page-7-v2OBm-.js +1 -0
  126. zenml/zen_server/dashboard/assets/{page-MFQyIJd3.js → page-B3ozwdD1.js} +1 -1
  127. zenml/zen_server/dashboard/assets/{page-BkuQDIf-.js → page-BGwA9B1M.js} +1 -1
  128. zenml/zen_server/dashboard/assets/{page-1iL8aMqs.js → page-BkjAUyTA.js} +1 -1
  129. zenml/zen_server/dashboard/assets/page-BnacgBiy.js +1 -0
  130. zenml/zen_server/dashboard/assets/page-BxF_KMQ3.js +2 -0
  131. zenml/zen_server/dashboard/assets/page-C4POHC0K.js +1 -0
  132. zenml/zen_server/dashboard/assets/page-C9kudd44.js +9 -0
  133. zenml/zen_server/dashboard/assets/page-CA1j3GpJ.js +1 -0
  134. zenml/zen_server/dashboard/assets/page-CCY6yfmu.js +1 -0
  135. zenml/zen_server/dashboard/assets/page-CgTe7Bme.js +1 -0
  136. zenml/zen_server/dashboard/assets/{page-8a4UMKXZ.js → page-Cgn-6v2Y.js} +1 -1
  137. zenml/zen_server/dashboard/assets/page-CxQmQqDw.js +1 -0
  138. zenml/zen_server/dashboard/assets/page-D2Goey3H.js +1 -0
  139. zenml/zen_server/dashboard/assets/page-DLpOnf7u.js +1 -0
  140. zenml/zen_server/dashboard/assets/{page-BhgCDInH.js → page-DSTQnBk-.js} +1 -1
  141. zenml/zen_server/dashboard/assets/{page-1h_sD1jz.js → page-DTysUGOy.js} +1 -1
  142. zenml/zen_server/dashboard/assets/{page-2grKx_MY.js → page-D_EXUFJb.js} +1 -1
  143. zenml/zen_server/dashboard/assets/page-Db15QzsM.js +1 -0
  144. zenml/zen_server/dashboard/assets/{page-BDns21Iz.js → page-DugsjcQ_.js} +1 -1
  145. zenml/zen_server/dashboard/assets/{page-C6-UGEbH.js → page-OFKSPyN7.js} +1 -1
  146. zenml/zen_server/dashboard/assets/{page-BkeAAYwp.js → page-RnG-qhv9.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{page-CCNRIt_f.js → page-T2BtjwPl.js} +1 -1
  148. zenml/zen_server/dashboard/assets/page-TXe1Eo3Z.js +1 -0
  149. zenml/zen_server/dashboard/assets/{page-BnaevhnB.js → page-YiF_fNbe.js} +1 -1
  150. zenml/zen_server/dashboard/assets/{page-uA5prJGY.js → page-hQaiQXfg.js} +1 -1
  151. zenml/zen_server/dashboard/assets/persist-3-5nOJ6m.js +1 -0
  152. zenml/zen_server/dashboard/assets/{play-circle-CNtZKDnW.js → play-circle-XSkLR12B.js} +1 -1
  153. zenml/zen_server/dashboard/assets/plus-FB9-lEq_.js +1 -0
  154. zenml/zen_server/dashboard/assets/refresh-COb6KYDi.js +1 -0
  155. zenml/zen_server/dashboard/assets/sharedSchema-BoYx_B_L.js +14 -0
  156. zenml/zen_server/dashboard/assets/{stack-detail-query-Cficsl6d.js → stack-detail-query-B-US_-wa.js} +1 -1
  157. zenml/zen_server/dashboard/assets/{terminal-By9cErXc.js → terminal-grtjrIEJ.js} +1 -1
  158. zenml/zen_server/dashboard/assets/trash-Cd5CSFqA.js +1 -0
  159. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-7d8xi1tS.js → update-server-settings-mutation-B8GB_ubU.js} +1 -1
  160. zenml/zen_server/dashboard/assets/{url-D7mAQGUM.js → url-hcMJkz8p.js} +1 -1
  161. zenml/zen_server/dashboard/assets/{zod-BhoGpZ63.js → zod-CnykDKJj.js} +1 -1
  162. zenml/zen_server/dashboard/index.html +7 -7
  163. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  164. zenml/zen_server/dashboard_legacy/index.html +1 -1
  165. zenml/zen_server/dashboard_legacy/{precache-manifest.12246c7548e71e2c4438e496360de80c.js → precache-manifest.9c473c96a43298343a7ce1256183123b.js} +4 -4
  166. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  167. zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js → main.463c90b9.chunk.js} +2 -2
  168. zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js.map → main.463c90b9.chunk.js.map} +1 -1
  169. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  170. zenml/zen_server/deploy/helm/README.md +2 -2
  171. zenml/zen_server/rbac/models.py +1 -0
  172. zenml/zen_server/rbac/utils.py +4 -0
  173. zenml/zen_server/routers/pipeline_builds_endpoints.py +2 -66
  174. zenml/zen_server/routers/pipeline_deployments_endpoints.py +2 -53
  175. zenml/zen_server/routers/pipelines_endpoints.py +1 -74
  176. zenml/zen_server/routers/run_templates_endpoints.py +212 -0
  177. zenml/zen_server/routers/stack_deployment_endpoints.py +6 -0
  178. zenml/zen_server/routers/users_endpoints.py +0 -7
  179. zenml/zen_server/routers/workspaces_endpoints.py +79 -0
  180. zenml/zen_server/{pipeline_deployment → template_execution}/runner_entrypoint_configuration.py +1 -8
  181. zenml/zen_server/{pipeline_deployment → template_execution}/utils.py +214 -92
  182. zenml/zen_server/utils.py +77 -2
  183. zenml/zen_server/zen_server_api.py +54 -2
  184. zenml/zen_stores/base_zen_store.py +7 -1
  185. zenml/zen_stores/migrations/versions/0.63.0_release.py +23 -0
  186. zenml/zen_stores/migrations/versions/0.64.0_release.py +23 -0
  187. zenml/zen_stores/migrations/versions/026d4577b6a0_add_code_path.py +39 -0
  188. zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +51 -0
  189. zenml/zen_stores/migrations/versions/7d1919bb1ef0_add_run_templates.py +100 -0
  190. zenml/zen_stores/migrations/versions/909550c7c4da_remove_user_hub_token.py +36 -0
  191. zenml/zen_stores/migrations/versions/b59aa68fdb1f_simplify_pipelines.py +139 -0
  192. zenml/zen_stores/rest_zen_store.py +112 -39
  193. zenml/zen_stores/schemas/__init__.py +2 -0
  194. zenml/zen_stores/schemas/pipeline_build_schemas.py +3 -3
  195. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +32 -2
  196. zenml/zen_stores/schemas/pipeline_run_schemas.py +29 -3
  197. zenml/zen_stores/schemas/pipeline_schemas.py +29 -30
  198. zenml/zen_stores/schemas/run_template_schemas.py +264 -0
  199. zenml/zen_stores/schemas/server_settings_schemas.py +2 -0
  200. zenml/zen_stores/schemas/step_run_schemas.py +11 -4
  201. zenml/zen_stores/schemas/user_schemas.py +0 -2
  202. zenml/zen_stores/sql_zen_store.py +389 -151
  203. zenml/zen_stores/template_utils.py +261 -0
  204. zenml/zen_stores/zen_store_interface.py +93 -20
  205. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/METADATA +3 -3
  206. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/RECORD +211 -184
  207. zenml/_hub/client.py +0 -289
  208. zenml/_hub/constants.py +0 -21
  209. zenml/_hub/utils.py +0 -79
  210. zenml/cli/hub.py +0 -1116
  211. zenml/models/v2/core/pipeline_namespace.py +0 -113
  212. zenml/models/v2/misc/hub_plugin_models.py +0 -79
  213. zenml/new/pipelines/deserialization_utils.py +0 -292
  214. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +0 -85
  215. zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +0 -1
  216. zenml/zen_server/dashboard/assets/CopyButton-Cr7xYEPb.js +0 -2
  217. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +0 -1
  218. zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +0 -1
  219. zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +0 -1
  220. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +0 -1
  221. zenml/zen_server/dashboard/assets/package-B3fWP-Dh.js +0 -1
  222. zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +0 -1
  223. zenml/zen_server/dashboard/assets/page-B6h3iaHJ.js +0 -1
  224. zenml/zen_server/dashboard/assets/page-Bi-wtWiO.js +0 -5
  225. zenml/zen_server/dashboard/assets/page-Bq0YxkLV.js +0 -1
  226. zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +0 -2
  227. zenml/zen_server/dashboard/assets/page-CHNxpz3n.js +0 -1
  228. zenml/zen_server/dashboard/assets/page-DgorQFqi.js +0 -1
  229. zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +0 -1
  230. zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +0 -1
  231. zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +0 -9
  232. zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +0 -1
  233. zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +0 -1
  234. zenml/zen_server/dashboard/assets/secrets-video-OBJ6irhH.svg +0 -21
  235. zenml/zen_server/dashboard/assets/stacks-video-7gfxpAq4.svg +0 -21
  236. /zenml/zen_server/{pipeline_deployment → template_execution}/__init__.py +0 -0
  237. /zenml/zen_server/{pipeline_deployment → template_execution}/workload_manager_interface.py +0 -0
  238. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/LICENSE +0 -0
  239. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/WHEEL +0 -0
  240. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/entry_points.txt +0 -0
@@ -14,18 +14,18 @@
14
14
  """Image build context."""
15
15
 
16
16
  import os
17
- from pathlib import Path
18
- from typing import IO, Dict, List, Optional, Set, Tuple, cast
17
+ from typing import IO, Dict, List, Optional, Set, cast
19
18
 
20
19
  from zenml.constants import REPOSITORY_DIRECTORY_NAME
21
20
  from zenml.io import fileio
22
21
  from zenml.logger import get_logger
23
22
  from zenml.utils import io_utils, string_utils
23
+ from zenml.utils.archivable import Archivable
24
24
 
25
25
  logger = get_logger(__name__)
26
26
 
27
27
 
28
- class BuildContext:
28
+ class BuildContext(Archivable):
29
29
  """Image build context.
30
30
 
31
31
  This class is responsible for creating an archive of the files needed to
@@ -45,9 +45,9 @@ class BuildContext:
45
45
  given, a file called `.dockerignore` in the build context root
46
46
  directory will be used instead if it exists.
47
47
  """
48
+ super().__init__()
48
49
  self._root = root
49
50
  self._dockerignore_file = dockerignore_file
50
- self._extra_files: Dict[str, str] = {}
51
51
 
52
52
  @property
53
53
  def dockerignore_file(self) -> Optional[str]:
@@ -68,70 +68,26 @@ class BuildContext:
68
68
 
69
69
  return None
70
70
 
71
- def add_file(self, source: str, destination: str) -> None:
72
- """Adds a file to the build context.
73
-
74
- Args:
75
- source: The source of the file to add. This can either be a path
76
- or the file content.
77
- destination: The path inside the build context where the file
78
- should be added.
79
- """
80
- if fileio.exists(source):
81
- with fileio.open(source) as f:
82
- self._extra_files[destination] = f.read()
83
- else:
84
- self._extra_files[destination] = source
85
-
86
- def add_directory(self, source: str, destination: str) -> None:
87
- """Adds a directory to the build context.
88
-
89
- Args:
90
- source: Path to the directory.
91
- destination: The path inside the build context where the directory
92
- should be added.
93
-
94
- Raises:
95
- ValueError: If `source` does not point to a directory.
96
- """
97
- if not fileio.isdir(source):
98
- raise ValueError(
99
- f"Can't add directory {source} to the build context as it "
100
- "does not exist or is not a directory."
101
- )
102
-
103
- for dir, _, files in fileio.walk(source):
104
- dir_path = Path(fileio.convert_to_str(dir))
105
- for file_name in files:
106
- file_name = fileio.convert_to_str(file_name)
107
- file_source = dir_path / file_name
108
- file_destination = (
109
- Path(destination)
110
- / dir_path.relative_to(source)
111
- / file_name
112
- )
113
-
114
- with file_source.open("r") as f:
115
- self._extra_files[file_destination.as_posix()] = f.read()
116
-
117
- def write_archive(self, output_file: IO[bytes], gzip: bool = True) -> None:
71
+ def write_archive(
72
+ self, output_file: IO[bytes], use_gzip: bool = True
73
+ ) -> None:
118
74
  """Writes an archive of the build context to the given file.
119
75
 
120
76
  Args:
121
77
  output_file: The file to write the archive to.
122
- gzip: Whether to use `gzip` to compress the file.
78
+ use_gzip: Whether to use `gzip` to compress the file.
123
79
  """
124
80
  from docker.utils import build as docker_build_utils
125
81
 
126
- files = self._get_files()
127
- extra_files = self._get_extra_files()
82
+ files = self.get_files()
83
+ extra_files = self.get_extra_files()
128
84
 
129
85
  context_archive = docker_build_utils.create_archive(
130
86
  fileobj=output_file,
131
87
  root=self._root,
132
- files=sorted(files),
133
- gzip=gzip,
134
- extra_files=extra_files,
88
+ files=sorted(files.keys()),
89
+ gzip=use_gzip,
90
+ extra_files=list(extra_files.items()),
135
91
  )
136
92
 
137
93
  build_context_size = os.path.getsize(context_archive.name)
@@ -151,33 +107,30 @@ class BuildContext:
151
107
  os.path.join(self._root, ".dockerignore"),
152
108
  )
153
109
 
154
- def _get_files(self) -> Set[str]:
155
- """Gets all non-ignored files in the build context root directory.
110
+ def get_files(self) -> Dict[str, str]:
111
+ """Gets all regular files that should be included in the archive.
156
112
 
157
113
  Returns:
158
- All build context files.
114
+ A dict {path_in_archive: path_on_filesystem} for all regular files
115
+ in the archive.
159
116
  """
160
117
  if self._root:
161
- exclude_patterns = self._get_exclude_patterns()
162
118
  from docker.utils import build as docker_build_utils
163
119
 
164
- return cast(
120
+ exclude_patterns = self._get_exclude_patterns()
121
+
122
+ archive_paths = cast(
165
123
  Set[str],
166
124
  docker_build_utils.exclude_paths(
167
125
  self._root, patterns=exclude_patterns
168
126
  ),
169
127
  )
128
+ return {
129
+ archive_path: os.path.join(self._root, archive_path)
130
+ for archive_path in archive_paths
131
+ }
170
132
  else:
171
- return set()
172
-
173
- def _get_extra_files(self) -> List[Tuple[str, str]]:
174
- """Gets all extra files of the build context.
175
-
176
- Returns:
177
- A tuple (path, file_content) for all extra files in the build
178
- context.
179
- """
180
- return list(self._extra_files.items())
133
+ return {}
181
134
 
182
135
  def _get_exclude_patterns(self) -> List[str]:
183
136
  """Gets all exclude patterns from the dockerignore file.
@@ -20,6 +20,7 @@ from uuid import UUID
20
20
 
21
21
  import boto3
22
22
  import sagemaker
23
+ from botocore.exceptions import WaiterError
23
24
  from sagemaker.network import NetworkConfig
24
25
  from sagemaker.processing import ProcessingInput, ProcessingOutput
25
26
  from sagemaker.workflow.execution_variables import ExecutionVariables
@@ -373,10 +374,18 @@ class SagemakerOrchestrator(ContainerizedOrchestrator):
373
374
  logger.info(
374
375
  "Executing synchronously. Waiting for pipeline to finish..."
375
376
  )
376
- pipeline_execution.wait(
377
- delay=POLLING_DELAY, max_attempts=MAX_POLLING_ATTEMPTS
378
- )
379
- logger.info("Pipeline completed successfully.")
377
+ try:
378
+ pipeline_execution.wait(
379
+ delay=POLLING_DELAY, max_attempts=MAX_POLLING_ATTEMPTS
380
+ )
381
+ logger.info("Pipeline completed successfully.")
382
+ except WaiterError:
383
+ raise RuntimeError(
384
+ "Timed out while waiting for pipeline execution to finish. For long-running "
385
+ "pipelines we recommend configuring your orchestrator for asynchronous execution. "
386
+ "The following command does this for you: \n"
387
+ f"`zenml orchestrator update {self.name} --synchronous=False`"
388
+ )
380
389
 
381
390
  def _get_region_name(self) -> str:
382
391
  """Returns the AWS region name.
@@ -27,6 +27,7 @@ from zenml.stack import Flavor
27
27
 
28
28
  AZURE_ARTIFACT_STORE_FLAVOR = "azure"
29
29
  AZUREML_STEP_OPERATOR_FLAVOR = "azureml"
30
+ AZUREML_ORCHESTRATOR_FLAVOR = "azureml"
30
31
 
31
32
  # Service connector constants
32
33
  AZURE_CONNECTOR_TYPE = "azure"
@@ -47,6 +48,7 @@ class AzureIntegration(Integration):
47
48
  "azure-mgmt-containerservice>=20.0.0",
48
49
  "azure-storage-blob==12.17.0", # temporary fix for https://github.com/Azure/azure-sdk-for-python/issues/32056
49
50
  "kubernetes",
51
+ "azure-ai-ml==1.18.0"
50
52
  ]
51
53
  REQUIREMENTS_IGNORED_ON_UNINSTALL = ["kubernetes"]
52
54
 
@@ -65,11 +67,13 @@ class AzureIntegration(Integration):
65
67
  from zenml.integrations.azure.flavors import (
66
68
  AzureArtifactStoreFlavor,
67
69
  AzureMLStepOperatorFlavor,
70
+ AzureMLOrchestratorFlavor,
68
71
  )
69
72
 
70
73
  return [
71
74
  AzureArtifactStoreFlavor,
72
75
  AzureMLStepOperatorFlavor,
76
+ AzureMLOrchestratorFlavor,
73
77
  ]
74
78
 
75
79
 
@@ -16,10 +16,17 @@
16
16
  from zenml.integrations.azure.flavors.azure_artifact_store_flavor import (
17
17
  AzureArtifactStoreConfig,
18
18
  AzureArtifactStoreFlavor,
19
+
19
20
  )
20
21
  from zenml.integrations.azure.flavors.azureml_step_operator_flavor import (
21
22
  AzureMLStepOperatorConfig,
22
23
  AzureMLStepOperatorFlavor,
24
+ AzureMLStepOperatorSettings,
25
+ )
26
+ from zenml.integrations.azure.flavors.azureml_orchestrator_flavor import (
27
+ AzureMLOrchestratorConfig,
28
+ AzureMLOrchestratorFlavor,
29
+ AzureMLOrchestratorSettings,
23
30
  )
24
31
 
25
32
  __all__ = [
@@ -27,4 +34,8 @@ __all__ = [
27
34
  "AzureArtifactStoreConfig",
28
35
  "AzureMLStepOperatorFlavor",
29
36
  "AzureMLStepOperatorConfig",
37
+ "AzureMLStepOperatorSettings",
38
+ "AzureMLOrchestratorFlavor",
39
+ "AzureMLOrchestratorConfig",
40
+ "AzureMLOrchestratorSettings",
30
41
  ]
@@ -0,0 +1,263 @@
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
+ """Implementation of the AzureML Orchestrator flavor."""
15
+
16
+ from typing import TYPE_CHECKING, Optional, Type
17
+
18
+ from pydantic import Field, model_validator
19
+
20
+ from zenml.config.base_settings import BaseSettings
21
+ from zenml.integrations.azure import (
22
+ AZURE_RESOURCE_TYPE,
23
+ AZUREML_ORCHESTRATOR_FLAVOR,
24
+ )
25
+ from zenml.logger import get_logger
26
+ from zenml.models import ServiceConnectorRequirements
27
+ from zenml.orchestrators.base_orchestrator import (
28
+ BaseOrchestratorConfig,
29
+ BaseOrchestratorFlavor,
30
+ )
31
+ from zenml.utils.enum_utils import StrEnum
32
+
33
+ if TYPE_CHECKING:
34
+ from zenml.integrations.azure.orchestrators import AzureMLOrchestrator
35
+
36
+ logger = get_logger(__name__)
37
+
38
+
39
+ class AzureMLComputeTypes(StrEnum):
40
+ """Enum for different types of compute on AzureML."""
41
+
42
+ SERVERLESS = "serverless"
43
+ COMPUTE_INSTANCE = "compute-instance"
44
+ COMPUTE_CLUSTER = "compute-cluster"
45
+
46
+
47
+ class AzureMLOrchestratorSettings(BaseSettings):
48
+ """Settings for the AzureML orchestrator.
49
+
50
+ These settings adjust the compute resources that will be used by the
51
+ pipeline execution.
52
+
53
+ There are three possible use cases for this implementation:
54
+
55
+ 1. Serverless compute (default behaviour):
56
+ - The `mode` is set to `serverless` (default behaviour).
57
+ - All the other parameters become irrelevant and will throw a
58
+ warning if set.
59
+
60
+ 2. Compute instance:
61
+ - The `mode` is set to `compute-instance`.
62
+ - In this case, users have to provide a `compute-name`.
63
+ - If a compute instance exists with this name, this instance
64
+ will be used and all the other parameters become irrelevant
65
+ and will throw a warning if set.
66
+ - If a compute instance does not already exist, ZenML will
67
+ create it. You can use the parameters `compute_size` and
68
+ `idle_type_before_shutdown_minutes` for this operation.
69
+
70
+ 3. Compute cluster:
71
+ - The `mode` is set to `compute-cluster`.
72
+ - In this case, users have to provide a `compute-name`.
73
+ - If a compute cluster exists with this name, this instance
74
+ will be used and all the other parameters become irrelevant
75
+ and will throw a warning if set.
76
+ - If a compute cluster does not already exist, ZenML will
77
+ create it. You can all the additional parameters for this
78
+ operation.
79
+ """
80
+
81
+ # Mode for compute
82
+ mode: AzureMLComputeTypes = AzureMLComputeTypes.SERVERLESS
83
+
84
+ # Common Configuration for Compute Instances and Clusters
85
+ compute_name: Optional[str] = None
86
+ size: Optional[str] = None
87
+
88
+ # Additional configuration for a Compute Instance
89
+ idle_time_before_shutdown_minutes: Optional[int] = None
90
+
91
+ # Additional configuration for a Compute Cluster
92
+ idle_time_before_scaledown_down: Optional[int] = None
93
+ location: Optional[str] = None
94
+ min_instances: Optional[int] = None
95
+ max_instances: Optional[int] = None
96
+ tier: Optional[str] = None
97
+
98
+ @model_validator(mode="after")
99
+ def azureml_settings_validator(self) -> "AzureMLOrchestratorSettings":
100
+ """Checks whether the right configuration is set based on mode.
101
+
102
+ Returns:
103
+ the instance itself.
104
+
105
+ Raises:
106
+ AssertionError: if a name is not provided when working with
107
+ instances and clusters.
108
+ """
109
+ excluded_fields = {"subscription_id", "resource_group", "workspace"}
110
+
111
+ viable_configuration_fields = {
112
+ AzureMLComputeTypes.SERVERLESS: {"mode"},
113
+ AzureMLComputeTypes.COMPUTE_INSTANCE: {
114
+ "mode",
115
+ "compute_name",
116
+ "size",
117
+ "idle_time_before_shutdown_minutes",
118
+ },
119
+ AzureMLComputeTypes.COMPUTE_CLUSTER: {
120
+ "mode",
121
+ "compute_name",
122
+ "size",
123
+ "idle_time_before_scaledown_down",
124
+ "location",
125
+ "min_instances",
126
+ "max_instances",
127
+ "tier",
128
+ },
129
+ }
130
+ viable_fields = viable_configuration_fields[self.mode]
131
+
132
+ for field in self.model_fields_set:
133
+ if field not in viable_fields and field not in excluded_fields:
134
+ logger.warning(
135
+ "In the AzureML Orchestrator Settings, the mode of "
136
+ f"operation is set to {self.mode}. In this mode, you can "
137
+ f"not configure the parameter '{field}'. This "
138
+ "configuration will be ignored."
139
+ )
140
+
141
+ if (
142
+ self.mode == AzureMLComputeTypes.COMPUTE_INSTANCE
143
+ or self.mode == AzureMLComputeTypes.COMPUTE_CLUSTER
144
+ ):
145
+ assert self.compute_name is not None, (
146
+ "When you are working with compute instances and clusters, "
147
+ "please define a name for the compute target."
148
+ )
149
+
150
+ return self
151
+
152
+
153
+ class AzureMLOrchestratorConfig(
154
+ BaseOrchestratorConfig, AzureMLOrchestratorSettings
155
+ ):
156
+ """Configuration for the AzureML orchestrator."""
157
+
158
+ subscription_id: str = Field(
159
+ description="Subscription ID that AzureML is running on."
160
+ )
161
+ resource_group: str = Field(
162
+ description="Name of the resource group that AzureML is running on.",
163
+ )
164
+ workspace: str = Field(
165
+ description="Name of the workspace that AzureML is running on."
166
+ )
167
+
168
+ @property
169
+ def is_remote(self) -> bool:
170
+ """Checks if this stack component is running remotely.
171
+
172
+ This designation is used to determine if the stack component can be
173
+ used with a local ZenML database or if it requires a remote ZenML
174
+ server.
175
+
176
+ Returns:
177
+ True if this config is for a remote component, False otherwise.
178
+ """
179
+ return True
180
+
181
+ @property
182
+ def is_synchronous(self) -> bool:
183
+ """Whether the orchestrator runs synchronous or not.
184
+
185
+ Returns:
186
+ Whether the orchestrator runs synchronous or not.
187
+ """
188
+ return False
189
+
190
+
191
+ class AzureMLOrchestratorFlavor(BaseOrchestratorFlavor):
192
+ """Flavor for the AzureML orchestrator."""
193
+
194
+ @property
195
+ def name(self) -> str:
196
+ """Name of the flavor.
197
+
198
+ Returns:
199
+ The name of the flavor.
200
+ """
201
+ return AZUREML_ORCHESTRATOR_FLAVOR
202
+
203
+ @property
204
+ def service_connector_requirements(
205
+ self,
206
+ ) -> Optional[ServiceConnectorRequirements]:
207
+ """Service connector resource requirements for service connectors.
208
+
209
+ Specifies resource requirements that are used to filter the available
210
+ service connector types that are compatible with this flavor.
211
+
212
+ Returns:
213
+ Requirements for compatible service connectors, if a service
214
+ connector is required for this flavor.
215
+ """
216
+ return ServiceConnectorRequirements(resource_type=AZURE_RESOURCE_TYPE)
217
+
218
+ @property
219
+ def docs_url(self) -> Optional[str]:
220
+ """A URL to point at docs explaining this flavor.
221
+
222
+ Returns:
223
+ A flavor docs url.
224
+ """
225
+ return self.generate_default_docs_url()
226
+
227
+ @property
228
+ def sdk_docs_url(self) -> Optional[str]:
229
+ """A URL to point at SDK docs explaining this flavor.
230
+
231
+ Returns:
232
+ A flavor SDK docs url.
233
+ """
234
+ return self.generate_default_sdk_docs_url()
235
+
236
+ @property
237
+ def logo_url(self) -> str:
238
+ """A URL to represent the flavor in the dashboard.
239
+
240
+ Returns:
241
+ The flavor logo.
242
+ """
243
+ return "https://public-flavor-logos.s3.eu-central-1.amazonaws.com/orchestrator/azureml.png"
244
+
245
+ @property
246
+ def config_class(self) -> Type[AzureMLOrchestratorConfig]:
247
+ """Returns AzureMLOrchestratorConfig config class.
248
+
249
+ Returns:
250
+ The config class.
251
+ """
252
+ return AzureMLOrchestratorConfig
253
+
254
+ @property
255
+ def implementation_class(self) -> Type["AzureMLOrchestrator"]:
256
+ """Implementation class.
257
+
258
+ Returns:
259
+ The implementation class.
260
+ """
261
+ from zenml.integrations.azure.orchestrators import AzureMLOrchestrator
262
+
263
+ return AzureMLOrchestrator
@@ -1,4 +1,4 @@
1
- # Copyright (c) ZenML GmbH 2023. All Rights Reserved.
1
+ # Copyright (c) ZenML GmbH 2024. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -11,4 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
12
  # or implied. See the License for the specific language governing
13
13
  # permissions and limitations under the License.
14
- """ZenML Hub internal code."""
14
+ """AzureML orchestrator."""
15
+ from zenml.integrations.azure.orchestrators.azureml_orchestrator import (
16
+ AzureMLOrchestrator,
17
+ )
18
+
19
+ __all__ = ["AzureMLOrchestrator"]