zenml-nightly 0.66.0.dev20240924__py3-none-any.whl → 0.66.0.dev20240926__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.
- zenml/VERSION +1 -1
- zenml/cli/__init__.py +7 -0
- zenml/cli/pipeline.py +21 -0
- zenml/constants.py +3 -0
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +288 -71
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +157 -4
- zenml/integrations/constants.py +1 -0
- zenml/integrations/deepchecks/__init__.py +1 -1
- zenml/integrations/deepchecks/data_validators/deepchecks_data_validator.py +55 -14
- zenml/integrations/deepchecks/validation_checks.py +62 -5
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +207 -18
- zenml/integrations/lightning/__init__.py +1 -1
- zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +9 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +18 -17
- zenml/integrations/lightning/orchestrators/lightning_orchestrator_entrypoint.py +2 -6
- zenml/integrations/mlflow/steps/mlflow_registry.py +2 -0
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +38 -26
- zenml/integrations/skypilot_kubernetes/__init__.py +52 -0
- zenml/integrations/skypilot_kubernetes/flavors/__init__.py +26 -0
- zenml/integrations/skypilot_kubernetes/flavors/skypilot_orchestrator_kubernetes_vm_flavor.py +125 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/__init__.py +25 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/skypilot_kubernetes_vm_orchestrator.py +74 -0
- zenml/models/v2/core/pipeline_run.py +62 -1
- zenml/new/pipelines/run_utils.py +4 -1
- zenml/orchestrators/base_orchestrator.py +41 -12
- zenml/stack/stack.py +11 -2
- zenml/zen_server/cloud_utils.py +33 -8
- zenml/zen_server/dashboard/assets/{404-iO8vpun1.js → 404-CMnKjD-L.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-B6kq9fJZ.js → @reactflow-CEC2f0cl.js} +1 -1
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-BqM1UpCD.js +1 -0
- zenml/zen_server/dashboard/assets/{CodeSnippet-DNWdQmbo.js → CodeSnippet-DRy_0J4D.js} +2 -2
- zenml/zen_server/dashboard/assets/{CollapsibleCard-B2OVjWYE.js → CollapsibleCard-lE-75Zob.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-DsoaVElZ.js → Commands-CVx2RAoT.js} +1 -1
- zenml/zen_server/dashboard/assets/{CopyButton-BqE_-PHO.js → CopyButton-C_yRGWuP.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-Dyasr2jU.js → CsvVizualization-Dd0P02Iz.js} +1 -1
- zenml/zen_server/dashboard/assets/{DialogItem-Cz1VLRwa.js → DialogItem-BCrc2wIk.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-DorJD_va.js → Error-BuMJbG-M.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-CIfQTutR.js → ExecutionStatus-fIulMG4w.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-CmfvtNeq.js → Helpbox-CJAp4kbv.js} +1 -1
- zenml/zen_server/dashboard/assets/Infobox-CC70zvGO.js +1 -0
- zenml/zen_server/dashboard/assets/{InlineAvatar-Ds2ZFHPc.js → InlineAvatar-C3QXdFW1.js} +1 -1
- zenml/zen_server/dashboard/assets/{Partials-DX-8iEa1.js → Partials-Cb8lrNsi.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderIcon-BOQJgapd.js → ProviderIcon-C9BuYVSN.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderRadio-BsYBw9YA.js → ProviderRadio-GYc9PJtG.js} +1 -1
- zenml/zen_server/dashboard/assets/{SearchField-W3GXpLlI.js → SearchField-BeF1yR7M.js} +1 -1
- zenml/zen_server/dashboard/assets/SecretTooltip-DgVWrPxX.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-B-0a8UCj.js → SetPassword-nAhHddXW.js} +1 -1
- zenml/zen_server/dashboard/assets/{Tick-i1DYsVcX.js → Tick-C5ZVvNRQ.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-C6Zb7ASL.js → UpdatePasswordSchemas-7KFsDbKb.js} +1 -1
- zenml/zen_server/dashboard/assets/UsageReason-DL5NL_ZD.js +1 -0
- zenml/zen_server/dashboard/assets/{WizardFooter-BHbO7zOa.js → WizardFooter-CgvFSppz.js} +1 -1
- zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-BBEe6I9-.js → all-pipeline-runs-query-DAPSF_74.js} +1 -1
- zenml/zen_server/dashboard/assets/{cloud-only-BuP4Kt_7.js → cloud-only-CxoNxh86.js} +1 -1
- zenml/zen_server/dashboard/assets/{create-stack-B2x2d4r1.js → create-stack-BfgeXFuV.js} +1 -1
- zenml/zen_server/dashboard/assets/delete-run-OkGmZQ5G.js +1 -0
- zenml/zen_server/dashboard/assets/{form-schemas-Bap0f854.js → form-schemas-C09PrQUJ.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-DFi8BroH.js → index-CLT4K7oC.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-B9wVwe7u.js → index-D0bJjaey.js} +3 -3
- zenml/zen_server/dashboard/assets/index-PcI3Xw77.css +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-DwxUz8VA.js → login-mutation-CB45FHbP.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-D5i9DunU.js → not-found-NtCUfXiV.js} +1 -1
- zenml/zen_server/dashboard/assets/page-AvcQe_oR.js +1 -0
- zenml/zen_server/dashboard/assets/page-B6DccgPa.js +1 -0
- zenml/zen_server/dashboard/assets/{page-xQG6GmFJ.js → page-B7DTiwhv.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CIbehp7V.js → page-B7LduaiG.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CEJWu1YO.js → page-B8WlhDq6.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BitfWsiW.js → page-BIhP9udn.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DE03uZZR.js → page-BLS9bXB8.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DFCK65G9.js → page-BYXn4SXu.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-bimkItOg.js → page-Bfvwt3AB.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D5F3DJjm.js → page-BipKr1Pt.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BwG4f5qc.js +1 -0
- zenml/zen_server/dashboard/assets/page-C1c_unjg.js +9 -0
- zenml/zen_server/dashboard/assets/{page-DQdwZZ9x.js → page-C25tiRdj.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CIATsAA7.js +1 -0
- zenml/zen_server/dashboard/assets/{page-iwoJnwPv.js → page-CKUVhcYr.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BiF8hLbO.js → page-CXLwze-m.js} +1 -1
- zenml/zen_server/dashboard/assets/page-D7TD0k_A.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CDOQLrPC.js → page-DIlOQjGU.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DGMa3ZQL.js → page-DJ31Huvj.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-J0s8Sq3N.js → page-DOqsdVzG.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DQGCHKrQ.js → page-DUapawuM.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-WCQ659by.js → page-Dd3jZyrf.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CrSdkteO.js → page-DyZzYHWA.js} +2 -2
- zenml/zen_server/dashboard/assets/page-L_xNBh_5.js +3 -0
- zenml/zen_server/dashboard/assets/{page-oS4hqS8M.js → page-VsrKiIdF.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DgM-N9RL.js → page-ioO58ULo.js} +1 -1
- zenml/zen_server/dashboard/assets/page-kalpiPZz.js +6 -0
- zenml/zen_server/dashboard/assets/{persist-xsYgVtR1.js → persist-ChKZVcn3.js} +1 -1
- zenml/zen_server/dashboard/assets/{persist-mEZN_fgH.js → persist-DodaLO0k.js} +1 -1
- zenml/zen_server/dashboard/assets/{sharedSchema-BfZcy7aP.js → sharedSchema-BvRWAv-c.js} +1 -1
- zenml/zen_server/dashboard/assets/{stack-detail-query-CU4egfhp.js → stack-detail-query-C9XwNP1E.js} +1 -1
- zenml/zen_server/dashboard/assets/tick-circle-m-hJG8i9.js +1 -0
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-DNqmQXDM.js → update-server-settings-mutation-DJDefwqW.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-DwbuKk1b.js → url-DdWrpIhi.js} +1 -1
- zenml/zen_server/dashboard/index.html +4 -4
- 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.290b95d5b43efa3368b3dc63d20c4782.js → precache-manifest.4f9db97de1b48fd5944e8a766c1300fe.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.840d1bf0.chunk.js → main.0fdd4aad.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.840d1bf0.chunk.js.map → main.0fdd4aad.chunk.js.map} +1 -1
- zenml/zen_server/routers/runs_endpoints.py +89 -3
- {zenml_nightly-0.66.0.dev20240924.dist-info → zenml_nightly-0.66.0.dev20240926.dist-info}/METADATA +8 -1
- {zenml_nightly-0.66.0.dev20240924.dist-info → zenml_nightly-0.66.0.dev20240926.dist-info}/RECORD +109 -102
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-BXeSvmMY.js +0 -1
- zenml/zen_server/dashboard/assets/EditSecretDialog-Du423_3U.js +0 -1
- zenml/zen_server/dashboard/assets/Infobox-BL9NOS37.js +0 -1
- zenml/zen_server/dashboard/assets/UsageReason-CCnzmwS8.js +0 -1
- zenml/zen_server/dashboard/assets/index-6DYjZgDn.css +0 -1
- zenml/zen_server/dashboard/assets/page-BFuJICXM.js +0 -9
- zenml/zen_server/dashboard/assets/page-CLiRGfWo.js +0 -1
- zenml/zen_server/dashboard/assets/page-CV44mQn9.js +0 -1
- zenml/zen_server/dashboard/assets/page-DI-qTWrm.js +0 -1
- zenml/zen_server/dashboard/assets/page-Dt8VgzbE.js +0 -1
- zenml/zen_server/dashboard/assets/page-oSqx9dkH.js +0 -1
- zenml/zen_server/dashboard/assets/page-p3GqEAUW.js +0 -1
- zenml/zen_server/dashboard/assets/page-qvcUVPE-.js +0 -1
- {zenml_nightly-0.66.0.dev20240924.dist-info → zenml_nightly-0.66.0.dev20240926.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.66.0.dev20240924.dist-info → zenml_nightly-0.66.0.dev20240926.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.66.0.dev20240924.dist-info → zenml_nightly-0.66.0.dev20240926.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
# Copyright (c) ZenML GmbH 2023. 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
|
+
"""Skypilot orchestrator Kubernetes flavor."""
|
15
|
+
|
16
|
+
from typing import TYPE_CHECKING, Optional, Type
|
17
|
+
|
18
|
+
from zenml.constants import KUBERNETES_CLUSTER_RESOURCE_TYPE
|
19
|
+
from zenml.integrations.skypilot.flavors.skypilot_orchestrator_base_vm_config import (
|
20
|
+
SkypilotBaseOrchestratorConfig,
|
21
|
+
SkypilotBaseOrchestratorSettings,
|
22
|
+
)
|
23
|
+
from zenml.integrations.skypilot_kubernetes import (
|
24
|
+
SKYPILOT_KUBERNETES_ORCHESTRATOR_FLAVOR,
|
25
|
+
)
|
26
|
+
from zenml.logger import get_logger
|
27
|
+
from zenml.models import ServiceConnectorRequirements
|
28
|
+
from zenml.orchestrators import BaseOrchestratorConfig, BaseOrchestratorFlavor
|
29
|
+
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from zenml.integrations.skypilot_kubernetes.orchestrators import (
|
32
|
+
SkypilotKubernetesOrchestrator,
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
logger = get_logger(__name__)
|
37
|
+
|
38
|
+
|
39
|
+
class SkypilotKubernetesOrchestratorSettings(SkypilotBaseOrchestratorSettings):
|
40
|
+
"""Skypilot orchestrator settings."""
|
41
|
+
|
42
|
+
|
43
|
+
class SkypilotKubernetesOrchestratorConfig(
|
44
|
+
SkypilotBaseOrchestratorConfig, SkypilotKubernetesOrchestratorSettings
|
45
|
+
):
|
46
|
+
"""Skypilot orchestrator config."""
|
47
|
+
|
48
|
+
|
49
|
+
class SkypilotKubernetesOrchestratorFlavor(BaseOrchestratorFlavor):
|
50
|
+
"""Flavor for the Skypilot Kubernetes orchestrator."""
|
51
|
+
|
52
|
+
@property
|
53
|
+
def name(self) -> str:
|
54
|
+
"""Name of the orchestrator flavor.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Name of the orchestrator flavor.
|
58
|
+
"""
|
59
|
+
return SKYPILOT_KUBERNETES_ORCHESTRATOR_FLAVOR
|
60
|
+
|
61
|
+
@property
|
62
|
+
def service_connector_requirements(
|
63
|
+
self,
|
64
|
+
) -> Optional[ServiceConnectorRequirements]:
|
65
|
+
"""Service connector resource requirements for service connectors.
|
66
|
+
|
67
|
+
Specifies resource requirements that are used to filter the available
|
68
|
+
service connector types that are compatible with this flavor.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
Requirements for compatible service connectors, if a service
|
72
|
+
connector is required for this flavor.
|
73
|
+
"""
|
74
|
+
return ServiceConnectorRequirements(
|
75
|
+
resource_type=KUBERNETES_CLUSTER_RESOURCE_TYPE,
|
76
|
+
)
|
77
|
+
|
78
|
+
@property
|
79
|
+
def docs_url(self) -> Optional[str]:
|
80
|
+
"""A url to point at docs explaining this flavor.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
A flavor docs url.
|
84
|
+
"""
|
85
|
+
return self.generate_default_docs_url()
|
86
|
+
|
87
|
+
@property
|
88
|
+
def sdk_docs_url(self) -> Optional[str]:
|
89
|
+
"""A url to point at SDK docs explaining this flavor.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
A flavor SDK docs url.
|
93
|
+
"""
|
94
|
+
return self.generate_default_sdk_docs_url()
|
95
|
+
|
96
|
+
@property
|
97
|
+
def logo_url(self) -> str:
|
98
|
+
"""A url to represent the flavor in the dashboard.
|
99
|
+
|
100
|
+
Returns:
|
101
|
+
The flavor logo.
|
102
|
+
"""
|
103
|
+
return "https://public-flavor-logos.s3.eu-central-1.amazonaws.com/orchestrator/kubernetes-skypilot.png"
|
104
|
+
|
105
|
+
@property
|
106
|
+
def config_class(self) -> Type[BaseOrchestratorConfig]:
|
107
|
+
"""Config class for the base orchestrator flavor.
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
The config class.
|
111
|
+
"""
|
112
|
+
return SkypilotKubernetesOrchestratorConfig
|
113
|
+
|
114
|
+
@property
|
115
|
+
def implementation_class(self) -> Type["SkypilotKubernetesOrchestrator"]:
|
116
|
+
"""Implementation class for this flavor.
|
117
|
+
|
118
|
+
Returns:
|
119
|
+
Implementation class for this flavor.
|
120
|
+
"""
|
121
|
+
from zenml.integrations.skypilot_kubernetes.orchestrators import (
|
122
|
+
SkypilotKubernetesOrchestrator,
|
123
|
+
)
|
124
|
+
|
125
|
+
return SkypilotKubernetesOrchestrator
|
@@ -0,0 +1,25 @@
|
|
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
|
+
"""Initialization of the Skypilot Kubernetes ZenML orchestrator."""
|
15
|
+
|
16
|
+
from zenml.integrations.skypilot.orchestrators.skypilot_base_vm_orchestrator import ( # noqa
|
17
|
+
SkypilotBaseOrchestrator,
|
18
|
+
)
|
19
|
+
from zenml.integrations.skypilot_kubernetes.orchestrators.skypilot_kubernetes_vm_orchestrator import ( # noqa
|
20
|
+
SkypilotKubernetesOrchestrator,
|
21
|
+
)
|
22
|
+
__all__ = [
|
23
|
+
"SkypilotBaseOrchestrator",
|
24
|
+
"SkypilotKubernetesOrchestrator",
|
25
|
+
]
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright (c) ZenML GmbH 2023. 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 a Skypilot based Kubernetes VM orchestrator."""
|
15
|
+
|
16
|
+
from typing import TYPE_CHECKING, Optional, Type, cast
|
17
|
+
|
18
|
+
import sky
|
19
|
+
|
20
|
+
from zenml.integrations.skypilot.orchestrators.skypilot_base_vm_orchestrator import (
|
21
|
+
SkypilotBaseOrchestrator,
|
22
|
+
)
|
23
|
+
from zenml.integrations.skypilot_kubernetes.flavors.skypilot_orchestrator_kubernetes_vm_flavor import (
|
24
|
+
SkypilotKubernetesOrchestratorConfig,
|
25
|
+
SkypilotKubernetesOrchestratorSettings,
|
26
|
+
)
|
27
|
+
from zenml.logger import get_logger
|
28
|
+
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
from zenml.config.base_settings import BaseSettings
|
31
|
+
|
32
|
+
logger = get_logger(__name__)
|
33
|
+
|
34
|
+
|
35
|
+
class SkypilotKubernetesOrchestrator(SkypilotBaseOrchestrator):
|
36
|
+
"""Orchestrator responsible for running pipelines remotely in a VM on Kubernetes.
|
37
|
+
|
38
|
+
This orchestrator does not support running on a schedule.
|
39
|
+
"""
|
40
|
+
|
41
|
+
@property
|
42
|
+
def cloud(self) -> sky.clouds.Cloud:
|
43
|
+
"""The type of sky cloud to use.
|
44
|
+
|
45
|
+
Returns:
|
46
|
+
A `sky.clouds.Cloud` instance.
|
47
|
+
"""
|
48
|
+
return sky.clouds.Kubernetes()
|
49
|
+
|
50
|
+
@property
|
51
|
+
def config(self) -> SkypilotKubernetesOrchestratorConfig:
|
52
|
+
"""Returns the `SkypilotKubernetesOrchestratorConfig` config.
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
The configuration.
|
56
|
+
"""
|
57
|
+
return cast(SkypilotKubernetesOrchestratorConfig, self._config)
|
58
|
+
|
59
|
+
@property
|
60
|
+
def settings_class(self) -> Optional[Type["BaseSettings"]]:
|
61
|
+
"""Settings class for the Skypilot orchestrator.
|
62
|
+
|
63
|
+
Returns:
|
64
|
+
The settings class.
|
65
|
+
"""
|
66
|
+
return SkypilotKubernetesOrchestratorSettings
|
67
|
+
|
68
|
+
def prepare_environment_variable(self, set: bool = True) -> None:
|
69
|
+
"""Set up Environment variables that are required for the orchestrator.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
set: Whether to set the environment variables or not.
|
73
|
+
"""
|
74
|
+
pass
|
@@ -21,6 +21,7 @@ from typing import (
|
|
21
21
|
List,
|
22
22
|
Optional,
|
23
23
|
Union,
|
24
|
+
cast,
|
24
25
|
)
|
25
26
|
from uuid import UUID
|
26
27
|
|
@@ -136,7 +137,8 @@ class PipelineRunUpdate(BaseModel):
|
|
136
137
|
"configured by this pipeline run explicitly.",
|
137
138
|
default=None,
|
138
139
|
)
|
139
|
-
# TODO: we should maybe have a different update model here, the upper
|
140
|
+
# TODO: we should maybe have a different update model here, the upper
|
141
|
+
# three attributes should only be for internal use
|
140
142
|
add_tags: Optional[List[str]] = Field(
|
141
143
|
default=None, title="New tags to add to the pipeline run."
|
142
144
|
)
|
@@ -235,6 +237,7 @@ class PipelineRunResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
235
237
|
description="Template used for the pipeline run.",
|
236
238
|
)
|
237
239
|
is_templatable: bool = Field(
|
240
|
+
default=False,
|
238
241
|
description="Whether a template can be created from this run.",
|
239
242
|
)
|
240
243
|
|
@@ -307,6 +310,64 @@ class PipelineRunResponse(
|
|
307
310
|
|
308
311
|
return get_artifacts_versions_of_pipeline_run(self, only_produced=True)
|
309
312
|
|
313
|
+
def refresh_run_status(self) -> "PipelineRunResponse":
|
314
|
+
"""Method to refresh the status of a run if it is initializing/running.
|
315
|
+
|
316
|
+
Returns:
|
317
|
+
The updated pipeline.
|
318
|
+
|
319
|
+
Raises:
|
320
|
+
ValueError: If the stack of the run response is None.
|
321
|
+
"""
|
322
|
+
if self.status in [
|
323
|
+
ExecutionStatus.INITIALIZING,
|
324
|
+
ExecutionStatus.RUNNING,
|
325
|
+
]:
|
326
|
+
# Check if the stack still accessible
|
327
|
+
if self.stack is None:
|
328
|
+
raise ValueError(
|
329
|
+
"The stack that this pipeline run response was executed on"
|
330
|
+
"has been deleted."
|
331
|
+
)
|
332
|
+
|
333
|
+
# Create the orchestrator instance
|
334
|
+
from zenml.enums import StackComponentType
|
335
|
+
from zenml.orchestrators.base_orchestrator import BaseOrchestrator
|
336
|
+
from zenml.stack.stack_component import StackComponent
|
337
|
+
|
338
|
+
# Check if the stack still accessible
|
339
|
+
orchestrator_list = self.stack.components.get(
|
340
|
+
StackComponentType.ORCHESTRATOR, []
|
341
|
+
)
|
342
|
+
if len(orchestrator_list) == 0:
|
343
|
+
raise ValueError(
|
344
|
+
"The orchestrator that this pipeline run response was "
|
345
|
+
"executed with has been deleted."
|
346
|
+
)
|
347
|
+
|
348
|
+
orchestrator = cast(
|
349
|
+
BaseOrchestrator,
|
350
|
+
StackComponent.from_model(
|
351
|
+
component_model=orchestrator_list[0]
|
352
|
+
),
|
353
|
+
)
|
354
|
+
|
355
|
+
# Fetch the status
|
356
|
+
status = orchestrator.fetch_status(run=self)
|
357
|
+
|
358
|
+
# If it is different from the current status, update it
|
359
|
+
if status != self.status:
|
360
|
+
from zenml.client import Client
|
361
|
+
from zenml.models import PipelineRunUpdate
|
362
|
+
|
363
|
+
client = Client()
|
364
|
+
return client.zen_store.update_run(
|
365
|
+
run_id=self.id,
|
366
|
+
run_update=PipelineRunUpdate(status=status),
|
367
|
+
)
|
368
|
+
|
369
|
+
return self
|
370
|
+
|
310
371
|
# Body and metadata properties
|
311
372
|
@property
|
312
373
|
def status(self) -> ExecutionStatus:
|
zenml/new/pipelines/run_utils.py
CHANGED
@@ -138,7 +138,10 @@ def deploy_pipeline(
|
|
138
138
|
previous_value = constants.SHOULD_PREVENT_PIPELINE_EXECUTION
|
139
139
|
constants.SHOULD_PREVENT_PIPELINE_EXECUTION = True
|
140
140
|
try:
|
141
|
-
stack.deploy_pipeline(
|
141
|
+
stack.deploy_pipeline(
|
142
|
+
deployment=deployment,
|
143
|
+
placeholder_run=placeholder_run,
|
144
|
+
)
|
142
145
|
except Exception as e:
|
143
146
|
if (
|
144
147
|
placeholder_run
|
@@ -14,12 +14,14 @@
|
|
14
14
|
"""Base orchestrator class."""
|
15
15
|
|
16
16
|
from abc import ABC, abstractmethod
|
17
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional, Type, cast
|
17
|
+
from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional, Type, cast
|
18
18
|
|
19
19
|
from pydantic import model_validator
|
20
20
|
|
21
|
-
from zenml.enums import StackComponentType
|
21
|
+
from zenml.enums import ExecutionStatus, StackComponentType
|
22
22
|
from zenml.logger import get_logger
|
23
|
+
from zenml.metadata.metadata_types import MetadataType
|
24
|
+
from zenml.orchestrators.publish_utils import publish_pipeline_run_metadata
|
23
25
|
from zenml.orchestrators.step_launcher import StepLauncher
|
24
26
|
from zenml.orchestrators.utils import get_config_environment_vars
|
25
27
|
from zenml.stack import Flavor, Stack, StackComponent, StackComponentConfig
|
@@ -27,7 +29,7 @@ from zenml.utils.pydantic_utils import before_validator_handler
|
|
27
29
|
|
28
30
|
if TYPE_CHECKING:
|
29
31
|
from zenml.config.step_configurations import Step
|
30
|
-
from zenml.models import PipelineDeploymentResponse
|
32
|
+
from zenml.models import PipelineDeploymentResponse, PipelineRunResponse
|
31
33
|
|
32
34
|
logger = get_logger(__name__)
|
33
35
|
|
@@ -124,7 +126,7 @@ class BaseOrchestrator(StackComponent, ABC):
|
|
124
126
|
deployment: "PipelineDeploymentResponse",
|
125
127
|
stack: "Stack",
|
126
128
|
environment: Dict[str, str],
|
127
|
-
) ->
|
129
|
+
) -> Optional[Iterator[Dict[str, MetadataType]]]:
|
128
130
|
"""The method needs to be implemented by the respective orchestrator.
|
129
131
|
|
130
132
|
Depending on the type of orchestrator you'll have to perform slightly
|
@@ -169,29 +171,41 @@ class BaseOrchestrator(StackComponent, ABC):
|
|
169
171
|
self,
|
170
172
|
deployment: "PipelineDeploymentResponse",
|
171
173
|
stack: "Stack",
|
174
|
+
placeholder_run: Optional["PipelineRunResponse"] = None,
|
172
175
|
) -> Any:
|
173
176
|
"""Runs a pipeline on a stack.
|
174
177
|
|
175
178
|
Args:
|
176
179
|
deployment: The pipeline deployment.
|
177
180
|
stack: The stack on which to run the pipeline.
|
178
|
-
|
179
|
-
|
180
|
-
Orchestrator-specific return value.
|
181
|
+
placeholder_run: An optional placeholder run for the deployment.
|
182
|
+
This will be deleted in case the pipeline deployment failed.
|
181
183
|
"""
|
182
184
|
self._prepare_run(deployment=deployment)
|
183
185
|
|
184
186
|
environment = get_config_environment_vars(deployment=deployment)
|
185
187
|
|
186
188
|
try:
|
187
|
-
|
188
|
-
deployment=deployment,
|
189
|
-
|
189
|
+
if metadata_iterator := self.prepare_or_run_pipeline(
|
190
|
+
deployment=deployment,
|
191
|
+
stack=stack,
|
192
|
+
environment=environment,
|
193
|
+
):
|
194
|
+
for metadata_dict in metadata_iterator:
|
195
|
+
try:
|
196
|
+
if placeholder_run:
|
197
|
+
publish_pipeline_run_metadata(
|
198
|
+
pipeline_run_id=placeholder_run.id,
|
199
|
+
pipeline_run_metadata={self.id: metadata_dict},
|
200
|
+
)
|
201
|
+
except Exception as e:
|
202
|
+
logger.debug(
|
203
|
+
"Something went went wrong trying to publish the"
|
204
|
+
f"run metadata: {e}"
|
205
|
+
)
|
190
206
|
finally:
|
191
207
|
self._cleanup_run()
|
192
208
|
|
193
|
-
return result
|
194
|
-
|
195
209
|
def run_step(self, step: "Step") -> None:
|
196
210
|
"""Runs the given step.
|
197
211
|
|
@@ -239,6 +253,21 @@ class BaseOrchestrator(StackComponent, ABC):
|
|
239
253
|
"""Cleans up the active run."""
|
240
254
|
self._active_deployment = None
|
241
255
|
|
256
|
+
def fetch_status(self, run: "PipelineRunResponse") -> ExecutionStatus:
|
257
|
+
"""Refreshes the status of a specific pipeline run.
|
258
|
+
|
259
|
+
Args:
|
260
|
+
run: A pipeline run response to fetch its status.
|
261
|
+
|
262
|
+
Raises:
|
263
|
+
NotImplementedError: If any orchestrator inheriting from the base
|
264
|
+
class does not implement this logic.
|
265
|
+
"""
|
266
|
+
raise NotImplementedError(
|
267
|
+
"The fetch status functionality is not implemented for the "
|
268
|
+
f"'{self.__class__.__name__}' orchestrator."
|
269
|
+
)
|
270
|
+
|
242
271
|
|
243
272
|
class BaseOrchestratorFlavor(Flavor):
|
244
273
|
"""Base orchestrator flavor class."""
|
zenml/stack/stack.py
CHANGED
@@ -62,7 +62,11 @@ if TYPE_CHECKING:
|
|
62
62
|
from zenml.image_builders import BaseImageBuilder
|
63
63
|
from zenml.model_deployers import BaseModelDeployer
|
64
64
|
from zenml.model_registries import BaseModelRegistry
|
65
|
-
from zenml.models import
|
65
|
+
from zenml.models import (
|
66
|
+
PipelineDeploymentBase,
|
67
|
+
PipelineDeploymentResponse,
|
68
|
+
PipelineRunResponse,
|
69
|
+
)
|
66
70
|
from zenml.orchestrators import BaseOrchestrator
|
67
71
|
from zenml.stack import StackComponent
|
68
72
|
from zenml.step_operators import BaseStepOperator
|
@@ -826,16 +830,21 @@ class Stack:
|
|
826
830
|
def deploy_pipeline(
|
827
831
|
self,
|
828
832
|
deployment: "PipelineDeploymentResponse",
|
833
|
+
placeholder_run: Optional["PipelineRunResponse"] = None,
|
829
834
|
) -> Any:
|
830
835
|
"""Deploys a pipeline on this stack.
|
831
836
|
|
832
837
|
Args:
|
833
838
|
deployment: The pipeline deployment.
|
839
|
+
placeholder_run: An optional placeholder run for the deployment.
|
840
|
+
This will be deleted in case the pipeline deployment failed.
|
834
841
|
|
835
842
|
Returns:
|
836
843
|
The return value of the call to `orchestrator.run_pipeline(...)`.
|
837
844
|
"""
|
838
|
-
return self.orchestrator.run(
|
845
|
+
return self.orchestrator.run(
|
846
|
+
deployment=deployment, stack=self, placeholder_run=placeholder_run
|
847
|
+
)
|
839
848
|
|
840
849
|
def _get_active_components_for_step(
|
841
850
|
self, step_config: "StepConfiguration"
|
zenml/zen_server/cloud_utils.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Utils concerning anything concerning the cloud control plane backend."""
|
2
2
|
|
3
3
|
import os
|
4
|
+
from datetime import datetime, timedelta, timezone
|
4
5
|
from typing import Any, Dict, Optional
|
5
6
|
|
6
7
|
import requests
|
@@ -19,11 +20,9 @@ class ZenMLCloudConfiguration(BaseModel):
|
|
19
20
|
"""ZenML Pro RBAC configuration."""
|
20
21
|
|
21
22
|
api_url: str
|
22
|
-
|
23
23
|
oauth2_client_id: str
|
24
24
|
oauth2_client_secret: str
|
25
25
|
oauth2_audience: str
|
26
|
-
auth0_domain: str
|
27
26
|
|
28
27
|
@field_validator("api_url")
|
29
28
|
@classmethod
|
@@ -68,6 +67,8 @@ class ZenMLCloudConnection:
|
|
68
67
|
"""Initialize the RBAC component."""
|
69
68
|
self._config = ZenMLCloudConfiguration.from_environment()
|
70
69
|
self._session: Optional[requests.Session] = None
|
70
|
+
self._token: Optional[str] = None
|
71
|
+
self._token_expires_at: Optional[datetime] = None
|
71
72
|
|
72
73
|
def get(
|
73
74
|
self, endpoint: str, params: Optional[Dict[str, Any]]
|
@@ -91,7 +92,8 @@ class ZenMLCloudConnection:
|
|
91
92
|
|
92
93
|
response = self.session.get(url=url, params=params, timeout=7)
|
93
94
|
if response.status_code == 401:
|
94
|
-
#
|
95
|
+
# If we get an Unauthorized error from the API serer, we refresh the
|
96
|
+
# auth token and try again
|
95
97
|
self._clear_session()
|
96
98
|
response = self.session.get(url=url, params=params, timeout=7)
|
97
99
|
|
@@ -186,6 +188,8 @@ class ZenMLCloudConnection:
|
|
186
188
|
def _clear_session(self) -> None:
|
187
189
|
"""Clear the authentication session."""
|
188
190
|
self._session = None
|
191
|
+
self._token = None
|
192
|
+
self._token_expires_at = None
|
189
193
|
|
190
194
|
def _fetch_auth_token(self) -> str:
|
191
195
|
"""Fetch an auth token for the Cloud API from auth0.
|
@@ -196,8 +200,16 @@ class ZenMLCloudConnection:
|
|
196
200
|
Returns:
|
197
201
|
Auth token.
|
198
202
|
"""
|
203
|
+
if (
|
204
|
+
self._token is not None
|
205
|
+
and self._token_expires_at is not None
|
206
|
+
and datetime.now(timezone.utc) + timedelta(minutes=5)
|
207
|
+
< self._token_expires_at
|
208
|
+
):
|
209
|
+
return self._token
|
210
|
+
|
199
211
|
# Get an auth token from auth0
|
200
|
-
|
212
|
+
login_url = f"{self._config.api_url}/auth/login"
|
201
213
|
headers = {"content-type": "application/x-www-form-urlencoded"}
|
202
214
|
payload = {
|
203
215
|
"client_id": self._config.oauth2_client_id,
|
@@ -207,18 +219,31 @@ class ZenMLCloudConnection:
|
|
207
219
|
}
|
208
220
|
try:
|
209
221
|
response = requests.post(
|
210
|
-
|
222
|
+
login_url, headers=headers, data=payload, timeout=7
|
211
223
|
)
|
212
224
|
response.raise_for_status()
|
213
225
|
except Exception as e:
|
214
226
|
raise RuntimeError(f"Error fetching auth token from auth0: {e}")
|
215
227
|
|
216
|
-
|
228
|
+
json_response = response.json()
|
229
|
+
access_token = json_response.get("access_token", "")
|
230
|
+
expires_in = json_response.get("expires_in", 0)
|
217
231
|
|
218
|
-
if
|
232
|
+
if (
|
233
|
+
not access_token
|
234
|
+
or not isinstance(access_token, str)
|
235
|
+
or not expires_in
|
236
|
+
or not isinstance(expires_in, int)
|
237
|
+
):
|
219
238
|
raise RuntimeError("Could not fetch auth token from auth0.")
|
220
239
|
|
221
|
-
|
240
|
+
self._token = access_token
|
241
|
+
self._token_expires_at = datetime.now(timezone.utc) + timedelta(
|
242
|
+
seconds=expires_in
|
243
|
+
)
|
244
|
+
|
245
|
+
assert self._token is not None
|
246
|
+
return self._token
|
222
247
|
|
223
248
|
|
224
249
|
def cloud_connection() -> ZenMLCloudConnection:
|
@@ -1 +1 @@
|
|
1
|
-
import{j as e}from"./@radix-DnFH_oo1.js";import{f as s,r as t}from"./index-
|
1
|
+
import{j as e}from"./@radix-DnFH_oo1.js";import{f as s,r as t}from"./index-D0bJjaey.js";import{E as r}from"./EmptyState-Cs3DEmso.js";import{H as a}from"./help-CwN931fX.js";import{L as o}from"./@react-router-APVeuk-U.js";import"./@tanstack-QbMbTrh5.js";import"./@reactflow-CEC2f0cl.js";function d(){return e.jsx("div",{className:"flex min-h-screen w-full flex-col",children:e.jsx(r,{icon:e.jsx(a,{className:"h-[120px] w-[120px] fill-neutral-300"}),children:e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"mb-2 text-display-xs font-semibold",children:"We can't find the page you are looking for"}),e.jsx("p",{className:"text-lg text-theme-text-secondary",children:"You can try typing a different URL or we can bring you back to your Homepage."}),e.jsx("div",{className:"mt-5 flex justify-center",children:e.jsx(s,{size:"md",asChild:!0,children:e.jsx(o,{className:"w-min self-center whitespace-nowrap",to:t.home,children:e.jsx("span",{className:"px-0.5",children:"Go to Home"})})})})]})})})}export{d as default};
|