zenml-nightly 0.61.0.dev20240714__py3-none-any.whl → 0.62.0.dev20240719__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 +1 -1
- RELEASE_NOTES.md +40 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +2 -0
- zenml/cli/stack.py +87 -228
- zenml/cli/stack_components.py +5 -3
- zenml/constants.py +2 -0
- zenml/entrypoints/entrypoint.py +3 -1
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/constants.py +1 -0
- zenml/integrations/databricks/__init__.py +52 -0
- zenml/integrations/databricks/flavors/__init__.py +30 -0
- zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +147 -0
- zenml/integrations/databricks/model_deployers/__init__.py +20 -0
- zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
- zenml/integrations/databricks/orchestrators/__init__.py +20 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +498 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
- zenml/integrations/databricks/services/__init__.py +19 -0
- zenml/integrations/databricks/services/databricks_deployment.py +407 -0
- zenml/integrations/databricks/utils/__init__.py +14 -0
- zenml/integrations/databricks/utils/databricks_utils.py +87 -0
- zenml/integrations/great_expectations/data_validators/ge_data_validator.py +12 -8
- zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +88 -3
- zenml/integrations/huggingface/steps/accelerate_runner.py +1 -7
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +7 -0
- zenml/integrations/kubernetes/pod_settings.py +2 -0
- zenml/integrations/lightgbm/__init__.py +1 -0
- zenml/integrations/mlflow/__init__.py +1 -1
- zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +6 -2
- zenml/integrations/mlflow/services/mlflow_deployment.py +1 -1
- zenml/integrations/skypilot_lambda/__init__.py +1 -1
- zenml/materializers/built_in_materializer.py +1 -1
- zenml/materializers/cloudpickle_materializer.py +1 -1
- zenml/model/model.py +1 -1
- zenml/models/v2/core/component.py +29 -0
- zenml/models/v2/misc/full_stack.py +32 -0
- zenml/orchestrators/__init__.py +4 -0
- zenml/orchestrators/wheeled_orchestrator.py +147 -0
- zenml/service_connectors/service_connector_utils.py +349 -0
- zenml/stack_deployments/gcp_stack_deployment.py +2 -4
- zenml/steps/base_step.py +7 -5
- zenml/utils/function_utils.py +1 -1
- zenml/utils/pipeline_docker_image_builder.py +8 -0
- zenml/zen_server/dashboard/assets/{404-DpJaNHKF.js → 404-B_YdvmwS.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-DJfzkHO1.js → @reactflow-l_1hUr1S.js} +1 -1
- zenml/zen_server/dashboard/assets/{AwarenessChannel-BYDLT2xC.js → AwarenessChannel-CFg5iX4Z.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-BkOuRmyq.js → CodeSnippet-Dvkx_82E.js} +1 -1
- zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +1 -0
- zenml/zen_server/dashboard/assets/{Commands-ZvWR1BRs.js → Commands-DoN1xrEq.js} +1 -1
- zenml/zen_server/dashboard/assets/{CopyButton-DVwLkafa.js → CopyButton-Cr7xYEPb.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-C2IiqX4I.js → CsvVizualization-Ck-nZ43m.js} +3 -3
- zenml/zen_server/dashboard/assets/{Error-CqX0VqW_.js → Error-kLtljEOM.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-BoLUXR9t.js → ExecutionStatus-DguLLgTK.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-LFydyVwh.js → Helpbox-BXUMP21n.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-DnENC0sh.js → Infobox-DSt0O-dm.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-CbJtYr0t.js → InlineAvatar-xsrsIGE-.js} +1 -1
- zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-BYBdbQDo.js → SetPassword-BXGTWiwj.js} +1 -1
- zenml/zen_server/dashboard/assets/{SuccessStep-Nx743hll.js → SuccessStep-DZC60t0x.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DF9gSzE0.js → UpdatePasswordSchemas-DGvwFWO1.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-BiEMg7rd.js → chevron-right-double-CZBOf6JM.js} +1 -1
- zenml/zen_server/dashboard/assets/cloud-only-C_yFCAkP.js +1 -0
- zenml/zen_server/dashboard/assets/index-BczVOqUf.js +55 -0
- zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-BUnVASxp.js → login-mutation-CrHrndTI.js} +1 -1
- zenml/zen_server/dashboard/assets/logs-D8k8BVFf.js +1 -0
- zenml/zen_server/dashboard/assets/{not-found-B4VnX8gK.js → not-found-DYa4pC-C.js} +1 -1
- zenml/zen_server/dashboard/assets/{package-CsUhPmou.js → package-B3fWP-Dh.js} +1 -1
- zenml/zen_server/dashboard/assets/page-1h_sD1jz.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Sxn82W-5.js → page-1iL8aMqs.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DMOYZppS.js → page-2grKx_MY.js} +1 -1
- zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +1 -0
- zenml/zen_server/dashboard/assets/{page-JyfeDUfu.js → page-8a4UMKXZ.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Bx6o0ARS.js → page-B6h3iaHJ.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BDns21Iz.js +1 -0
- zenml/zen_server/dashboard/assets/{page-3efNCDeb.js → page-BhgCDInH.js} +2 -2
- zenml/zen_server/dashboard/assets/{page-DKlIdAe5.js → page-Bi-wtWiO.js} +2 -2
- zenml/zen_server/dashboard/assets/{page-7zTHbhhI.js → page-BkeAAYwp.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CRTJ0UuR.js → page-BkuQDIf-.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BnaevhnB.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BEs6jK71.js → page-Bq0YxkLV.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +2 -0
- zenml/zen_server/dashboard/assets/{page-CUZIGO-3.js → page-C6-UGEbH.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Xu8JEjSU.js → page-CCNRIt_f.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DvCvroOM.js → page-CHNxpz3n.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BpSqIf4B.js → page-DgorQFqi.js} +1 -1
- zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Cx67M0QT.js → page-MFQyIJd3.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +1 -0
- zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +9 -0
- zenml/zen_server/dashboard/assets/{page-Dc_7KMQE.js → page-uA5prJGY.js} +1 -1
- zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +1 -0
- zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +1 -0
- zenml/zen_server/dashboard/assets/stack-detail-query-Cficsl6d.js +1 -0
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-7d8xi1tS.js +1 -0
- zenml/zen_server/dashboard/assets/{url-DuQMeqYA.js → url-D7mAQGUM.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.c8c57fb0d2132b1d3c2119e776b7dfb3.js → precache-manifest.12246c7548e71e2c4438e496360de80c.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/main.3b27024b.chunk.js +2 -0
- zenml/zen_server/dashboard_legacy/static/js/{main.382439a7.chunk.js.map → main.3b27024b.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/routers/service_connectors_endpoints.py +57 -0
- zenml/zen_stores/migrations/versions/0.62.0_release.py +23 -0
- zenml/zen_stores/rest_zen_store.py +4 -0
- zenml/zen_stores/schemas/component_schemas.py +14 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/METADATA +2 -2
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/RECORD +116 -98
- zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +0 -1
- zenml/zen_server/dashboard/assets/chevron-down-D_ZlKMqH.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +0 -1
- zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +0 -1
- zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +0 -55
- zenml/zen_server/dashboard/assets/index-inApY3KQ.css +0 -1
- zenml/zen_server/dashboard/assets/page-C43QGHTt.js +0 -9
- zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +0 -1
- zenml/zen_server/dashboard/assets/page-CaopxiU1.js +0 -1
- zenml/zen_server/dashboard/assets/page-D7Z399xy.js +0 -1
- zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +0 -1
- zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +0 -2
- zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +0 -1
- zenml/zen_server/dashboard/assets/page-TKXERe16.js +0 -1
- zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +0 -1
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-CR8e3Sir.js +0 -1
- zenml/zen_server/dashboard_legacy/static/js/main.382439a7.chunk.js +0 -2
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,30 @@
|
|
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
|
+
"""Databricks integration flavors."""
|
15
|
+
|
16
|
+
from zenml.integrations.databricks.flavors.databricks_orchestrator_flavor import (
|
17
|
+
DatabricksOrchestratorConfig,
|
18
|
+
DatabricksOrchestratorFlavor,
|
19
|
+
)
|
20
|
+
from zenml.integrations.databricks.flavors.databricks_model_deployer_flavor import (
|
21
|
+
DatabricksModelDeployerConfig,
|
22
|
+
DatabricksModelDeployerFlavor,
|
23
|
+
)
|
24
|
+
|
25
|
+
__all__ = [
|
26
|
+
"DatabricksOrchestratorFlavor",
|
27
|
+
"DatabricksOrchestratorConfig",
|
28
|
+
"DatabricksModelDeployerFlavor",
|
29
|
+
"DatabricksModelDeployerConfig",
|
30
|
+
]
|
@@ -0,0 +1,118 @@
|
|
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
|
+
"""Databricks model deployer flavor."""
|
15
|
+
|
16
|
+
from typing import TYPE_CHECKING, Dict, Optional, Type
|
17
|
+
|
18
|
+
from pydantic import BaseModel
|
19
|
+
|
20
|
+
from zenml.integrations.databricks import DATABRICKS_MODEL_DEPLOYER_FLAVOR
|
21
|
+
from zenml.model_deployers.base_model_deployer import (
|
22
|
+
BaseModelDeployerConfig,
|
23
|
+
BaseModelDeployerFlavor,
|
24
|
+
)
|
25
|
+
from zenml.utils.secret_utils import SecretField
|
26
|
+
|
27
|
+
if TYPE_CHECKING:
|
28
|
+
from zenml.integrations.databricks.model_deployers.databricks_model_deployer import (
|
29
|
+
DatabricksModelDeployer,
|
30
|
+
)
|
31
|
+
|
32
|
+
|
33
|
+
class DatabricksBaseConfig(BaseModel):
|
34
|
+
"""Databricks Inference Endpoint configuration."""
|
35
|
+
|
36
|
+
workload_size: str
|
37
|
+
scale_to_zero_enabled: bool = False
|
38
|
+
env_vars: Optional[Dict[str, str]] = None
|
39
|
+
workload_type: Optional[str] = None
|
40
|
+
endpoint_secret_name: Optional[str] = None
|
41
|
+
|
42
|
+
|
43
|
+
class DatabricksModelDeployerConfig(BaseModelDeployerConfig):
|
44
|
+
"""Configuration for the Databricks model deployer.
|
45
|
+
|
46
|
+
Attributes:
|
47
|
+
host: Databricks host.
|
48
|
+
secret_name: Secret name to use for authentication.
|
49
|
+
client_id: Databricks client id.
|
50
|
+
client_secret: Databricks client secret.
|
51
|
+
"""
|
52
|
+
|
53
|
+
host: str
|
54
|
+
secret_name: Optional[str] = None
|
55
|
+
client_id: Optional[str] = SecretField(default=None)
|
56
|
+
client_secret: Optional[str] = SecretField(default=None)
|
57
|
+
|
58
|
+
|
59
|
+
class DatabricksModelDeployerFlavor(BaseModelDeployerFlavor):
|
60
|
+
"""Databricks Endpoint model deployer flavor."""
|
61
|
+
|
62
|
+
@property
|
63
|
+
def name(self) -> str:
|
64
|
+
"""Name of the flavor.
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
The name of the flavor.
|
68
|
+
"""
|
69
|
+
return DATABRICKS_MODEL_DEPLOYER_FLAVOR
|
70
|
+
|
71
|
+
@property
|
72
|
+
def docs_url(self) -> Optional[str]:
|
73
|
+
"""A url to point at docs explaining this flavor.
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
A flavor docs url.
|
77
|
+
"""
|
78
|
+
return self.generate_default_docs_url()
|
79
|
+
|
80
|
+
@property
|
81
|
+
def sdk_docs_url(self) -> Optional[str]:
|
82
|
+
"""A url to point at SDK docs explaining this flavor.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
A flavor SDK docs url.
|
86
|
+
"""
|
87
|
+
return self.generate_default_sdk_docs_url()
|
88
|
+
|
89
|
+
@property
|
90
|
+
def logo_url(self) -> str:
|
91
|
+
"""A url to represent the flavor in the dashboard.
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
The flavor logo.
|
95
|
+
"""
|
96
|
+
return "https://public-flavor-logos.s3.eu-central-1.amazonaws.com/model_deployer/databricks.png"
|
97
|
+
|
98
|
+
@property
|
99
|
+
def config_class(self) -> Type[DatabricksModelDeployerConfig]:
|
100
|
+
"""Returns `DatabricksModelDeployerConfig` config class.
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
The config class.
|
104
|
+
"""
|
105
|
+
return DatabricksModelDeployerConfig
|
106
|
+
|
107
|
+
@property
|
108
|
+
def implementation_class(self) -> Type["DatabricksModelDeployer"]:
|
109
|
+
"""Implementation class for this flavor.
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
The implementation class.
|
113
|
+
"""
|
114
|
+
from zenml.integrations.databricks.model_deployers.databricks_model_deployer import (
|
115
|
+
DatabricksModelDeployer,
|
116
|
+
)
|
117
|
+
|
118
|
+
return DatabricksModelDeployer
|
@@ -0,0 +1,147 @@
|
|
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
|
+
"""Databricks orchestrator base config and settings."""
|
15
|
+
|
16
|
+
from typing import TYPE_CHECKING, Dict, Optional, Tuple, Type
|
17
|
+
|
18
|
+
from zenml.config.base_settings import BaseSettings
|
19
|
+
from zenml.integrations.databricks import DATABRICKS_ORCHESTRATOR_FLAVOR
|
20
|
+
from zenml.logger import get_logger
|
21
|
+
from zenml.orchestrators import BaseOrchestratorConfig
|
22
|
+
from zenml.orchestrators.base_orchestrator import BaseOrchestratorFlavor
|
23
|
+
from zenml.utils.secret_utils import SecretField
|
24
|
+
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from zenml.integrations.databricks.orchestrators import (
|
27
|
+
DatabricksOrchestrator,
|
28
|
+
)
|
29
|
+
|
30
|
+
|
31
|
+
logger = get_logger(__name__)
|
32
|
+
|
33
|
+
|
34
|
+
class DatabricksOrchestratorSettings(BaseSettings):
|
35
|
+
"""Databricks orchestrator base settings.
|
36
|
+
|
37
|
+
Attributes:
|
38
|
+
spark_version: Spark version.
|
39
|
+
num_workers: Number of workers.
|
40
|
+
node_type_id: Node type id.
|
41
|
+
policy_id: Policy id.
|
42
|
+
autotermination_minutes: Autotermination minutes.
|
43
|
+
autoscale: Autoscale.
|
44
|
+
single_user_name: Single user name.
|
45
|
+
spark_conf: Spark configuration.
|
46
|
+
spark_env_vars: Spark environment variables.
|
47
|
+
schedule_timezone: Schedule timezone.
|
48
|
+
"""
|
49
|
+
|
50
|
+
# Resources
|
51
|
+
spark_version: Optional[str] = None
|
52
|
+
num_workers: Optional[int] = None
|
53
|
+
node_type_id: Optional[str] = None
|
54
|
+
policy_id: Optional[str] = None
|
55
|
+
autotermination_minutes: Optional[int] = None
|
56
|
+
autoscale: Tuple[int, int] = (2, 3)
|
57
|
+
single_user_name: Optional[str] = None
|
58
|
+
spark_conf: Optional[Dict[str, str]] = None
|
59
|
+
spark_env_vars: Optional[Dict[str, str]] = None
|
60
|
+
schedule_timezone: Optional[str] = None
|
61
|
+
|
62
|
+
|
63
|
+
class DatabricksOrchestratorConfig(
|
64
|
+
BaseOrchestratorConfig, DatabricksOrchestratorSettings
|
65
|
+
):
|
66
|
+
"""Databricks orchestrator base config.
|
67
|
+
|
68
|
+
Attributes:
|
69
|
+
host: Databricks host.
|
70
|
+
client_id: Databricks client id.
|
71
|
+
client_secret: Databricks client secret.
|
72
|
+
"""
|
73
|
+
|
74
|
+
host: str
|
75
|
+
client_id: str = SecretField(default=None)
|
76
|
+
client_secret: str = SecretField(default=None)
|
77
|
+
|
78
|
+
@property
|
79
|
+
def is_local(self) -> bool:
|
80
|
+
"""Checks if this stack component is running locally.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
True if this config is for a local component, False otherwise.
|
84
|
+
"""
|
85
|
+
return False
|
86
|
+
|
87
|
+
|
88
|
+
class DatabricksOrchestratorFlavor(BaseOrchestratorFlavor):
|
89
|
+
"""Databricks orchestrator flavor."""
|
90
|
+
|
91
|
+
@property
|
92
|
+
def name(self) -> str:
|
93
|
+
"""Name of the flavor.
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
The name of the flavor.
|
97
|
+
"""
|
98
|
+
return DATABRICKS_ORCHESTRATOR_FLAVOR
|
99
|
+
|
100
|
+
@property
|
101
|
+
def docs_url(self) -> Optional[str]:
|
102
|
+
"""A url to point at docs explaining this flavor.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
A flavor docs url.
|
106
|
+
"""
|
107
|
+
return self.generate_default_docs_url()
|
108
|
+
|
109
|
+
@property
|
110
|
+
def sdk_docs_url(self) -> Optional[str]:
|
111
|
+
"""A url to point at SDK docs explaining this flavor.
|
112
|
+
|
113
|
+
Returns:
|
114
|
+
A flavor SDK docs url.
|
115
|
+
"""
|
116
|
+
return self.generate_default_sdk_docs_url()
|
117
|
+
|
118
|
+
@property
|
119
|
+
def logo_url(self) -> str:
|
120
|
+
"""A url to represent the flavor in the dashboard.
|
121
|
+
|
122
|
+
Returns:
|
123
|
+
The flavor logo.
|
124
|
+
"""
|
125
|
+
return "https://public-flavor-logos.s3.eu-central-1.amazonaws.com/orchestrator/databricks.png"
|
126
|
+
|
127
|
+
@property
|
128
|
+
def config_class(self) -> Type[DatabricksOrchestratorConfig]:
|
129
|
+
"""Returns `KubeflowOrchestratorConfig` config class.
|
130
|
+
|
131
|
+
Returns:
|
132
|
+
The config class.
|
133
|
+
"""
|
134
|
+
return DatabricksOrchestratorConfig
|
135
|
+
|
136
|
+
@property
|
137
|
+
def implementation_class(self) -> Type["DatabricksOrchestrator"]:
|
138
|
+
"""Implementation class for this flavor.
|
139
|
+
|
140
|
+
Returns:
|
141
|
+
The implementation class.
|
142
|
+
"""
|
143
|
+
from zenml.integrations.databricks.orchestrators import (
|
144
|
+
DatabricksOrchestrator,
|
145
|
+
)
|
146
|
+
|
147
|
+
return DatabricksOrchestrator
|
@@ -0,0 +1,20 @@
|
|
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
|
+
# http://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 Databricks model deployers."""
|
15
|
+
|
16
|
+
from zenml.integrations.databricks.model_deployers.databricks_model_deployer import ( # noqa
|
17
|
+
DatabricksModelDeployer,
|
18
|
+
)
|
19
|
+
|
20
|
+
__all__ = ["DatabricksModelDeployer"]
|
@@ -0,0 +1,249 @@
|
|
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 Databricks Model Deployer."""
|
15
|
+
|
16
|
+
from typing import ClassVar, Dict, Optional, Tuple, Type, cast
|
17
|
+
from uuid import UUID
|
18
|
+
|
19
|
+
from zenml.analytics.enums import AnalyticsEvent
|
20
|
+
from zenml.analytics.utils import track_handler
|
21
|
+
from zenml.client import Client
|
22
|
+
from zenml.integrations.databricks import DATABRICKS_SERVICE_ARTIFACT
|
23
|
+
from zenml.integrations.databricks.flavors.databricks_model_deployer_flavor import (
|
24
|
+
DatabricksModelDeployerConfig,
|
25
|
+
DatabricksModelDeployerFlavor,
|
26
|
+
)
|
27
|
+
from zenml.integrations.databricks.services.databricks_deployment import (
|
28
|
+
DatabricksDeploymentConfig,
|
29
|
+
DatabricksDeploymentService,
|
30
|
+
)
|
31
|
+
from zenml.logger import get_logger
|
32
|
+
from zenml.model_deployers import BaseModelDeployer
|
33
|
+
from zenml.model_deployers.base_model_deployer import (
|
34
|
+
DEFAULT_DEPLOYMENT_START_STOP_TIMEOUT,
|
35
|
+
BaseModelDeployerFlavor,
|
36
|
+
)
|
37
|
+
from zenml.services import BaseService, ServiceConfig
|
38
|
+
from zenml.stack.stack import Stack
|
39
|
+
from zenml.stack.stack_validator import StackValidator
|
40
|
+
|
41
|
+
logger = get_logger(__name__)
|
42
|
+
|
43
|
+
|
44
|
+
class DatabricksModelDeployer(BaseModelDeployer):
|
45
|
+
"""Databricks endpoint model deployer."""
|
46
|
+
|
47
|
+
NAME: ClassVar[str] = "Databricks"
|
48
|
+
FLAVOR: ClassVar[Type[BaseModelDeployerFlavor]] = (
|
49
|
+
DatabricksModelDeployerFlavor
|
50
|
+
)
|
51
|
+
|
52
|
+
@property
|
53
|
+
def config(self) -> DatabricksModelDeployerConfig:
|
54
|
+
"""Config class for the Databricks Model deployer settings class.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
The configuration.
|
58
|
+
"""
|
59
|
+
return cast(DatabricksModelDeployerConfig, self._config)
|
60
|
+
|
61
|
+
@property
|
62
|
+
def validator(self) -> Optional[StackValidator]:
|
63
|
+
"""Validates the stack.
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
A validator that checks that the stack contains a remote artifact
|
67
|
+
store.
|
68
|
+
"""
|
69
|
+
|
70
|
+
def _validate_if_secret_or_token_is_present(
|
71
|
+
stack: "Stack",
|
72
|
+
) -> Tuple[bool, str]:
|
73
|
+
"""Check if client id and client secret or secret name is present in the stack.
|
74
|
+
|
75
|
+
Args:
|
76
|
+
stack: The stack to validate.
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
A tuple with a boolean indicating whether the stack is valid
|
80
|
+
and a message describing the validation result.
|
81
|
+
"""
|
82
|
+
return bool(
|
83
|
+
(self.config.client_id and self.config.client_secret)
|
84
|
+
or self.config.secret_name
|
85
|
+
), (
|
86
|
+
"The Databricks model deployer requires either a secret name"
|
87
|
+
" or a client id and client secret to be present in the stack."
|
88
|
+
)
|
89
|
+
|
90
|
+
return StackValidator(
|
91
|
+
custom_validation_function=_validate_if_secret_or_token_is_present,
|
92
|
+
)
|
93
|
+
|
94
|
+
def _create_new_service(
|
95
|
+
self, id: UUID, timeout: int, config: DatabricksDeploymentConfig
|
96
|
+
) -> DatabricksDeploymentService:
|
97
|
+
"""Creates a new DatabricksDeploymentService.
|
98
|
+
|
99
|
+
Args:
|
100
|
+
id: the UUID of the model to be deployed with Databricks model deployer.
|
101
|
+
timeout: the timeout in seconds to wait for the Databricks inference endpoint
|
102
|
+
to be provisioned and successfully started or updated.
|
103
|
+
config: the configuration of the model to be deployed with Databricks model deployer.
|
104
|
+
|
105
|
+
Returns:
|
106
|
+
The DatabricksDeploymentConfig object that can be used to interact
|
107
|
+
with the Databricks inference endpoint.
|
108
|
+
"""
|
109
|
+
# create a new service for the new model
|
110
|
+
service = DatabricksDeploymentService(uuid=id, config=config)
|
111
|
+
logger.info(
|
112
|
+
f"Creating an artifact {DATABRICKS_SERVICE_ARTIFACT} with service instance attached as metadata."
|
113
|
+
" If there's an active pipeline and/or model this artifact will be associated with it."
|
114
|
+
)
|
115
|
+
service.start(timeout=timeout)
|
116
|
+
return service
|
117
|
+
|
118
|
+
def _clean_up_existing_service(
|
119
|
+
self,
|
120
|
+
timeout: int,
|
121
|
+
force: bool,
|
122
|
+
existing_service: DatabricksDeploymentService,
|
123
|
+
) -> None:
|
124
|
+
"""Stop existing services.
|
125
|
+
|
126
|
+
Args:
|
127
|
+
timeout: the timeout in seconds to wait for the Databricks
|
128
|
+
deployment to be stopped.
|
129
|
+
force: if True, force the service to stop
|
130
|
+
existing_service: Existing Databricks deployment service
|
131
|
+
"""
|
132
|
+
# stop the older service
|
133
|
+
existing_service.stop(timeout=timeout, force=force)
|
134
|
+
|
135
|
+
def perform_deploy_model(
|
136
|
+
self,
|
137
|
+
id: UUID,
|
138
|
+
config: ServiceConfig,
|
139
|
+
timeout: int = DEFAULT_DEPLOYMENT_START_STOP_TIMEOUT,
|
140
|
+
) -> BaseService:
|
141
|
+
"""Create a new Databricks deployment service or update an existing one.
|
142
|
+
|
143
|
+
This should serve the supplied model and deployment configuration.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
id: the UUID of the model to be deployed with Databricks.
|
147
|
+
config: the configuration of the model to be deployed with Databricks.
|
148
|
+
timeout: the timeout in seconds to wait for the Databricks endpoint
|
149
|
+
to be provisioned and successfully started or updated. If set
|
150
|
+
to 0, the method will return immediately after the Databricks
|
151
|
+
server is provisioned, without waiting for it to fully start.
|
152
|
+
|
153
|
+
Returns:
|
154
|
+
The ZenML Databricks deployment service object that can be used to
|
155
|
+
interact with the remote Databricks inference endpoint server.
|
156
|
+
"""
|
157
|
+
with track_handler(AnalyticsEvent.MODEL_DEPLOYED) as analytics_handler:
|
158
|
+
config = cast(DatabricksDeploymentConfig, config)
|
159
|
+
# create a new DatabricksDeploymentService instance
|
160
|
+
service = self._create_new_service(
|
161
|
+
id=id, timeout=timeout, config=config
|
162
|
+
)
|
163
|
+
logger.info(
|
164
|
+
f"Creating a new Databricks inference endpoint service: {service}"
|
165
|
+
)
|
166
|
+
# Add telemetry with metadata that gets the stack metadata and
|
167
|
+
# differentiates between pure model and custom code deployments
|
168
|
+
stack = Client().active_stack
|
169
|
+
stack_metadata = {
|
170
|
+
component_type.value: component.flavor
|
171
|
+
for component_type, component in stack.components.items()
|
172
|
+
}
|
173
|
+
analytics_handler.metadata = {
|
174
|
+
"store_type": Client().zen_store.type.value,
|
175
|
+
**stack_metadata,
|
176
|
+
}
|
177
|
+
|
178
|
+
return service
|
179
|
+
|
180
|
+
def perform_stop_model(
|
181
|
+
self,
|
182
|
+
service: BaseService,
|
183
|
+
timeout: int = DEFAULT_DEPLOYMENT_START_STOP_TIMEOUT,
|
184
|
+
force: bool = False,
|
185
|
+
) -> BaseService:
|
186
|
+
"""Method to stop a model server.
|
187
|
+
|
188
|
+
Args:
|
189
|
+
service: The service to stop.
|
190
|
+
timeout: Timeout in seconds to wait for the service to stop.
|
191
|
+
force: If True, force the service to stop.
|
192
|
+
|
193
|
+
Returns:
|
194
|
+
The stopped service.
|
195
|
+
"""
|
196
|
+
service.stop(timeout=timeout, force=force)
|
197
|
+
return service
|
198
|
+
|
199
|
+
def perform_start_model(
|
200
|
+
self,
|
201
|
+
service: BaseService,
|
202
|
+
timeout: int = DEFAULT_DEPLOYMENT_START_STOP_TIMEOUT,
|
203
|
+
) -> BaseService:
|
204
|
+
"""Method to start a model server.
|
205
|
+
|
206
|
+
Args:
|
207
|
+
service: The service to start.
|
208
|
+
timeout: Timeout in seconds to wait for the service to start.
|
209
|
+
|
210
|
+
Returns:
|
211
|
+
The started service.
|
212
|
+
"""
|
213
|
+
service.start(timeout=timeout)
|
214
|
+
return service
|
215
|
+
|
216
|
+
def perform_delete_model(
|
217
|
+
self,
|
218
|
+
service: BaseService,
|
219
|
+
timeout: int = DEFAULT_DEPLOYMENT_START_STOP_TIMEOUT,
|
220
|
+
force: bool = False,
|
221
|
+
) -> None:
|
222
|
+
"""Method to delete all configuration of a model server.
|
223
|
+
|
224
|
+
Args:
|
225
|
+
service: The service to delete.
|
226
|
+
timeout: Timeout in seconds to wait for the service to stop.
|
227
|
+
force: If True, force the service to stop.
|
228
|
+
"""
|
229
|
+
service = cast(DatabricksDeploymentService, service)
|
230
|
+
self._clean_up_existing_service(
|
231
|
+
existing_service=service, timeout=timeout, force=force
|
232
|
+
)
|
233
|
+
|
234
|
+
@staticmethod
|
235
|
+
def get_model_server_info( # type: ignore[override]
|
236
|
+
service_instance: "DatabricksDeploymentService",
|
237
|
+
) -> Dict[str, Optional[str]]:
|
238
|
+
"""Return implementation specific information that might be relevant to the user.
|
239
|
+
|
240
|
+
Args:
|
241
|
+
service_instance: Instance of a DatabricksDeploymentService
|
242
|
+
|
243
|
+
Returns:
|
244
|
+
Model server information.
|
245
|
+
"""
|
246
|
+
return {
|
247
|
+
"PREDICTION_URL": service_instance.get_prediction_url(),
|
248
|
+
"HEALTH_CHECK_URL": service_instance.get_healthcheck_url(),
|
249
|
+
}
|
@@ -0,0 +1,20 @@
|
|
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 Databricks ZenML orchestrator."""
|
15
|
+
|
16
|
+
from zenml.integrations.databricks.orchestrators.databricks_orchestrator import ( # noqa
|
17
|
+
DatabricksOrchestrator,
|
18
|
+
)
|
19
|
+
|
20
|
+
__all__ = ["DatabricksOrchestrator"]
|