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.
- README.md +2 -2
- RELEASE_NOTES.md +120 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +0 -4
- zenml/actions/pipeline_run/pipeline_run_action.py +19 -17
- zenml/analytics/enums.py +4 -6
- zenml/cli/__init__.py +28 -76
- zenml/cli/base.py +2 -2
- zenml/cli/pipeline.py +54 -61
- zenml/cli/stack.py +6 -8
- zenml/cli/web_login.py +8 -0
- zenml/client.py +232 -103
- zenml/config/build_configuration.py +43 -17
- zenml/config/compiler.py +14 -22
- zenml/config/docker_settings.py +80 -57
- zenml/config/pipeline_run_configuration.py +3 -0
- zenml/config/server_config.py +3 -0
- zenml/config/source.py +60 -1
- zenml/constants.py +11 -2
- zenml/entrypoints/base_entrypoint_configuration.py +53 -8
- zenml/enums.py +4 -1
- zenml/environment.py +25 -9
- zenml/image_builders/base_image_builder.py +1 -1
- zenml/image_builders/build_context.py +25 -72
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +13 -4
- zenml/integrations/azure/__init__.py +4 -0
- zenml/integrations/azure/flavors/__init__.py +11 -0
- zenml/integrations/azure/flavors/azureml_orchestrator_flavor.py +263 -0
- zenml/{_hub → integrations/azure/orchestrators}/__init__.py +7 -2
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +544 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py +86 -0
- zenml/integrations/azure/step_operators/azureml_step_operator.py +3 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +20 -2
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +19 -13
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +7 -2
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +123 -6
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +1 -1
- zenml/integrations/mlflow/__init__.py +1 -1
- zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +3 -1
- zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +3 -0
- zenml/logger.py +13 -0
- zenml/models/__init__.py +26 -22
- zenml/models/v2/base/filter.py +32 -0
- zenml/models/v2/core/pipeline.py +73 -89
- zenml/models/v2/core/pipeline_build.py +15 -11
- zenml/models/v2/core/pipeline_deployment.py +72 -24
- zenml/models/v2/core/pipeline_run.py +65 -1
- zenml/models/v2/core/run_template.py +393 -0
- zenml/models/v2/core/server_settings.py +12 -0
- zenml/models/v2/core/user.py +0 -21
- zenml/models/v2/misc/server_models.py +7 -1
- zenml/models/v2/misc/stack_deployment.py +5 -0
- zenml/models/v2/misc/user_auth.py +0 -7
- zenml/new/pipelines/build_utils.py +220 -89
- zenml/new/pipelines/code_archive.py +157 -0
- zenml/new/pipelines/pipeline.py +46 -78
- zenml/new/pipelines/run_utils.py +79 -1
- zenml/post_execution/pipeline.py +1 -4
- zenml/service_connectors/service_connector_utils.py +18 -2
- zenml/stack_deployments/aws_stack_deployment.py +32 -8
- zenml/stack_deployments/azure_stack_deployment.py +122 -10
- zenml/stack_deployments/gcp_stack_deployment.py +36 -7
- zenml/stack_deployments/stack_deployment.py +23 -7
- zenml/steps/base_step.py +3 -0
- zenml/steps/utils.py +0 -4
- zenml/utils/archivable.py +149 -0
- zenml/utils/code_utils.py +244 -0
- zenml/utils/notebook_utils.py +122 -0
- zenml/utils/package_utils.py +39 -0
- zenml/utils/pipeline_docker_image_builder.py +3 -96
- zenml/utils/source_utils.py +109 -1
- zenml/zen_server/dashboard/assets/{404-B_YdvmwS.js → 404-CRAA_Lew.js} +1 -1
- zenml/zen_server/dashboard/assets/@radix-BXWm7HOa.js +85 -0
- zenml/zen_server/dashboard/assets/{@react-router-CO-OsFwI.js → @react-router-l3lMcXA2.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-l_1hUr1S.js → @reactflow-CeVxyqYT.js} +2 -2
- zenml/zen_server/dashboard/assets/{@tanstack-DYiOyJUL.js → @tanstack-FmcYZMuX.js} +4 -4
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-ErO9aOgK.js +1 -0
- zenml/zen_server/dashboard/assets/{AwarenessChannel-CFg5iX4Z.js → AwarenessChannel-CLXo5rKM.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-Dvkx_82E.js → CodeSnippet-D0VLxT2A.js} +2 -2
- zenml/zen_server/dashboard/assets/CollapsibleCard-BaUPiVg0.js +1 -0
- zenml/zen_server/dashboard/assets/{Commands-DoN1xrEq.js → Commands-JrcZK-3j.js} +1 -1
- zenml/zen_server/dashboard/assets/CopyButton-Dbo52T1K.js +2 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-Ck-nZ43m.js → CsvVizualization-D3kAypDj.js} +3 -3
- zenml/zen_server/dashboard/assets/DisplayDate-DizbSeT-.js +1 -0
- zenml/zen_server/dashboard/assets/EditSecretDialog-Bd7mFLS4.js +1 -0
- zenml/zen_server/dashboard/assets/{EmptyState-BMLnFVlB.js → EmptyState-BHblM39I.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-kLtljEOM.js → Error-C6LeJSER.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-DguLLgTK.js → ExecutionStatus-jH4OrWBq.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-BXUMP21n.js → Helpbox-aAB2XP-z.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-DSt0O-dm.js → Infobox-BQ0aty32.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-xsrsIGE-.js → InlineAvatar-DpTLgM3Q.js} +1 -1
- zenml/zen_server/dashboard/assets/Lock-CNyJvf2r.js +1 -0
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-xp3hhULl.js → MarkdownVisualization-Bajxn0HY.js} +1 -1
- zenml/zen_server/dashboard/assets/NumberBox-BmKE0qnO.js +1 -0
- zenml/zen_server/dashboard/assets/{PasswordChecker-DUveqlva.js → PasswordChecker-yGGoJSB-.js} +1 -1
- zenml/zen_server/dashboard/assets/ProviderRadio-BBqkIuTd.js +1 -0
- zenml/zen_server/dashboard/assets/RadioItem-xLhXoiFV.js +1 -0
- zenml/zen_server/dashboard/assets/SearchField-C9R0mdaX.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-BXGTWiwj.js → SetPassword-52sNxNiO.js} +1 -1
- zenml/zen_server/dashboard/assets/{SuccessStep-DZC60t0x.js → SuccessStep-DlkItqYG.js} +1 -1
- zenml/zen_server/dashboard/assets/Tick-uxv80Q6a.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DGvwFWO1.js → UpdatePasswordSchemas-oN4G3sKz.js} +1 -1
- zenml/zen_server/dashboard/assets/{aws-BgKTfTfx.js → aws-0_3UsPif.js} +1 -1
- zenml/zen_server/dashboard/assets/{check-circle-i56092KI.js → check-circle-1_I207rW.js} +1 -1
- zenml/zen_server/dashboard/assets/chevron-down-BpaF8JqM.js +1 -0
- zenml/zen_server/dashboard/assets/{chevron-right-double-CZBOf6JM.js → chevron-right-double-Dk8e2L99.js} +1 -1
- zenml/zen_server/dashboard/assets/{cloud-only-C_yFCAkP.js → cloud-only-BkUuI0lZ.js} +1 -1
- zenml/zen_server/dashboard/assets/components-Br2ezRib.js +1 -0
- zenml/zen_server/dashboard/assets/{copy-BXNk6BjL.js → copy-f3XGPPxt.js} +1 -1
- zenml/zen_server/dashboard/assets/{database-1xWSgZfO.js → database-cXYNX9tt.js} +1 -1
- zenml/zen_server/dashboard/assets/{docker-CQMVm_4d.js → docker-8uj__HHK.js} +1 -1
- zenml/zen_server/dashboard/assets/dots-horizontal-sKQlWEni.js +1 -0
- zenml/zen_server/dashboard/assets/edit-C0MVvPD2.js +1 -0
- zenml/zen_server/dashboard/assets/{file-text-CqD_iu6l.js → file-text-B9JibxTs.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-bu_DgLKI.js → help-FuHlZwn0.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-rK_Wuy2W.js → index-Bd1xgUQG.js} +1 -1
- zenml/zen_server/dashboard/assets/index-DaGknux4.css +1 -0
- zenml/zen_server/dashboard/assets/{index-BczVOqUf.js → index-DhIZtpxB.js} +5 -5
- zenml/zen_server/dashboard/assets/index.esm-DT4uyn2i.js +1 -0
- zenml/zen_server/dashboard/assets/layout-D6oiSbfd.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-CrHrndTI.js → login-mutation-13A_JSVA.js} +1 -1
- zenml/zen_server/dashboard/assets/{logs-D8k8BVFf.js → logs-CgeE2vZP.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-DYa4pC-C.js → not-found-B0Mmb90p.js} +1 -1
- zenml/zen_server/dashboard/assets/package-DdkziX79.js +1 -0
- zenml/zen_server/dashboard/assets/page-7-v2OBm-.js +1 -0
- zenml/zen_server/dashboard/assets/{page-MFQyIJd3.js → page-B3ozwdD1.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BkuQDIf-.js → page-BGwA9B1M.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-1iL8aMqs.js → page-BkjAUyTA.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BnacgBiy.js +1 -0
- zenml/zen_server/dashboard/assets/page-BxF_KMQ3.js +2 -0
- zenml/zen_server/dashboard/assets/page-C4POHC0K.js +1 -0
- zenml/zen_server/dashboard/assets/page-C9kudd44.js +9 -0
- zenml/zen_server/dashboard/assets/page-CA1j3GpJ.js +1 -0
- zenml/zen_server/dashboard/assets/page-CCY6yfmu.js +1 -0
- zenml/zen_server/dashboard/assets/page-CgTe7Bme.js +1 -0
- zenml/zen_server/dashboard/assets/{page-8a4UMKXZ.js → page-Cgn-6v2Y.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CxQmQqDw.js +1 -0
- zenml/zen_server/dashboard/assets/page-D2Goey3H.js +1 -0
- zenml/zen_server/dashboard/assets/page-DLpOnf7u.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BhgCDInH.js → page-DSTQnBk-.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-1h_sD1jz.js → page-DTysUGOy.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-2grKx_MY.js → page-D_EXUFJb.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Db15QzsM.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BDns21Iz.js → page-DugsjcQ_.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-C6-UGEbH.js → page-OFKSPyN7.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BkeAAYwp.js → page-RnG-qhv9.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CCNRIt_f.js → page-T2BtjwPl.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TXe1Eo3Z.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BnaevhnB.js → page-YiF_fNbe.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-uA5prJGY.js → page-hQaiQXfg.js} +1 -1
- zenml/zen_server/dashboard/assets/persist-3-5nOJ6m.js +1 -0
- zenml/zen_server/dashboard/assets/{play-circle-CNtZKDnW.js → play-circle-XSkLR12B.js} +1 -1
- zenml/zen_server/dashboard/assets/plus-FB9-lEq_.js +1 -0
- zenml/zen_server/dashboard/assets/refresh-COb6KYDi.js +1 -0
- zenml/zen_server/dashboard/assets/sharedSchema-BoYx_B_L.js +14 -0
- zenml/zen_server/dashboard/assets/{stack-detail-query-Cficsl6d.js → stack-detail-query-B-US_-wa.js} +1 -1
- zenml/zen_server/dashboard/assets/{terminal-By9cErXc.js → terminal-grtjrIEJ.js} +1 -1
- zenml/zen_server/dashboard/assets/trash-Cd5CSFqA.js +1 -0
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-7d8xi1tS.js → update-server-settings-mutation-B8GB_ubU.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-D7mAQGUM.js → url-hcMJkz8p.js} +1 -1
- zenml/zen_server/dashboard/assets/{zod-BhoGpZ63.js → zod-CnykDKJj.js} +1 -1
- zenml/zen_server/dashboard/index.html +7 -7
- zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
- zenml/zen_server/dashboard_legacy/index.html +1 -1
- zenml/zen_server/dashboard_legacy/{precache-manifest.12246c7548e71e2c4438e496360de80c.js → precache-manifest.9c473c96a43298343a7ce1256183123b.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js → main.463c90b9.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js.map → main.463c90b9.chunk.js.map} +1 -1
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/rbac/models.py +1 -0
- zenml/zen_server/rbac/utils.py +4 -0
- zenml/zen_server/routers/pipeline_builds_endpoints.py +2 -66
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +2 -53
- zenml/zen_server/routers/pipelines_endpoints.py +1 -74
- zenml/zen_server/routers/run_templates_endpoints.py +212 -0
- zenml/zen_server/routers/stack_deployment_endpoints.py +6 -0
- zenml/zen_server/routers/users_endpoints.py +0 -7
- zenml/zen_server/routers/workspaces_endpoints.py +79 -0
- zenml/zen_server/{pipeline_deployment → template_execution}/runner_entrypoint_configuration.py +1 -8
- zenml/zen_server/{pipeline_deployment → template_execution}/utils.py +214 -92
- zenml/zen_server/utils.py +77 -2
- zenml/zen_server/zen_server_api.py +54 -2
- zenml/zen_stores/base_zen_store.py +7 -1
- zenml/zen_stores/migrations/versions/0.63.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.64.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/026d4577b6a0_add_code_path.py +39 -0
- zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +51 -0
- zenml/zen_stores/migrations/versions/7d1919bb1ef0_add_run_templates.py +100 -0
- zenml/zen_stores/migrations/versions/909550c7c4da_remove_user_hub_token.py +36 -0
- zenml/zen_stores/migrations/versions/b59aa68fdb1f_simplify_pipelines.py +139 -0
- zenml/zen_stores/rest_zen_store.py +112 -39
- zenml/zen_stores/schemas/__init__.py +2 -0
- zenml/zen_stores/schemas/pipeline_build_schemas.py +3 -3
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +32 -2
- zenml/zen_stores/schemas/pipeline_run_schemas.py +29 -3
- zenml/zen_stores/schemas/pipeline_schemas.py +29 -30
- zenml/zen_stores/schemas/run_template_schemas.py +264 -0
- zenml/zen_stores/schemas/server_settings_schemas.py +2 -0
- zenml/zen_stores/schemas/step_run_schemas.py +11 -4
- zenml/zen_stores/schemas/user_schemas.py +0 -2
- zenml/zen_stores/sql_zen_store.py +389 -151
- zenml/zen_stores/template_utils.py +261 -0
- zenml/zen_stores/zen_store_interface.py +93 -20
- {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/METADATA +3 -3
- {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/RECORD +211 -184
- zenml/_hub/client.py +0 -289
- zenml/_hub/constants.py +0 -21
- zenml/_hub/utils.py +0 -79
- zenml/cli/hub.py +0 -1116
- zenml/models/v2/core/pipeline_namespace.py +0 -113
- zenml/models/v2/misc/hub_plugin_models.py +0 -79
- zenml/new/pipelines/deserialization_utils.py +0 -292
- zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +0 -85
- zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +0 -1
- zenml/zen_server/dashboard/assets/CopyButton-Cr7xYEPb.js +0 -2
- zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +0 -1
- zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +0 -1
- zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +0 -1
- zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +0 -1
- zenml/zen_server/dashboard/assets/package-B3fWP-Dh.js +0 -1
- zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +0 -1
- zenml/zen_server/dashboard/assets/page-B6h3iaHJ.js +0 -1
- zenml/zen_server/dashboard/assets/page-Bi-wtWiO.js +0 -5
- zenml/zen_server/dashboard/assets/page-Bq0YxkLV.js +0 -1
- zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +0 -2
- zenml/zen_server/dashboard/assets/page-CHNxpz3n.js +0 -1
- zenml/zen_server/dashboard/assets/page-DgorQFqi.js +0 -1
- zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +0 -1
- zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +0 -1
- zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +0 -9
- zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +0 -1
- zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +0 -1
- zenml/zen_server/dashboard/assets/secrets-video-OBJ6irhH.svg +0 -21
- zenml/zen_server/dashboard/assets/stacks-video-7gfxpAq4.svg +0 -21
- /zenml/zen_server/{pipeline_deployment → template_execution}/__init__.py +0 -0
- /zenml/zen_server/{pipeline_deployment → template_execution}/workload_manager_interface.py +0 -0
- {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/WHEEL +0 -0
- {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
|
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
|
72
|
-
|
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
|
-
|
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.
|
127
|
-
extra_files = self.
|
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=
|
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
|
155
|
-
"""Gets all
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
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
|
-
"""
|
14
|
+
"""AzureML orchestrator."""
|
15
|
+
from zenml.integrations.azure.orchestrators.azureml_orchestrator import (
|
16
|
+
AzureMLOrchestrator,
|
17
|
+
)
|
18
|
+
|
19
|
+
__all__ = ["AzureMLOrchestrator"]
|