zenml-nightly 0.58.2.dev20240626__py3-none-any.whl → 0.61.0.dev20240712__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 +30 -9
- RELEASE_NOTES.md +240 -0
- zenml/VERSION +1 -1
- zenml/analytics/enums.py +3 -0
- zenml/cli/__init__.py +28 -0
- zenml/cli/artifact.py +1 -2
- zenml/cli/integration.py +9 -8
- zenml/cli/server.py +6 -0
- zenml/cli/stack.py +946 -39
- zenml/cli/stack_components.py +7 -0
- zenml/cli/text_utils.py +35 -1
- zenml/cli/utils.py +127 -10
- zenml/client.py +23 -14
- zenml/config/docker_settings.py +8 -5
- zenml/constants.py +10 -1
- zenml/container_registries/base_container_registry.py +1 -0
- zenml/enums.py +7 -0
- zenml/event_hub/event_hub.py +5 -8
- zenml/integrations/aws/__init__.py +1 -0
- zenml/integrations/azure/__init__.py +1 -0
- zenml/integrations/deepchecks/__init__.py +1 -0
- zenml/integrations/discord/__init__.py +1 -0
- zenml/integrations/evidently/__init__.py +1 -0
- zenml/integrations/facets/__init__.py +1 -0
- zenml/integrations/feast/__init__.py +1 -0
- zenml/integrations/gcp/__init__.py +3 -1
- zenml/integrations/gcp/google_credentials_mixin.py +1 -1
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
- zenml/integrations/huggingface/__init__.py +1 -0
- zenml/integrations/integration.py +24 -0
- zenml/integrations/kubeflow/__init__.py +3 -0
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
- zenml/integrations/kubernetes/__init__.py +3 -1
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
- zenml/integrations/langchain/__init__.py +1 -0
- zenml/integrations/mlflow/__init__.py +3 -1
- zenml/integrations/neural_prophet/__init__.py +1 -0
- zenml/integrations/polars/__init__.py +1 -0
- zenml/integrations/prodigy/__init__.py +1 -0
- zenml/integrations/pycaret/__init__.py +6 -0
- zenml/integrations/registry.py +37 -0
- zenml/integrations/s3/artifact_stores/s3_artifact_store.py +17 -6
- zenml/integrations/seldon/__init__.py +1 -0
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
- zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
- zenml/integrations/skypilot_aws/__init__.py +2 -1
- zenml/integrations/skypilot_azure/__init__.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
- zenml/integrations/slack/__init__.py +1 -0
- zenml/integrations/tekton/__init__.py +1 -0
- zenml/integrations/tensorboard/__init__.py +0 -1
- zenml/integrations/tensorflow/__init__.py +18 -6
- zenml/integrations/wandb/__init__.py +1 -0
- zenml/models/__init__.py +11 -0
- zenml/models/v2/core/component.py +18 -0
- zenml/models/v2/core/model.py +1 -2
- zenml/models/v2/core/service_connector.py +17 -0
- zenml/models/v2/core/stack.py +31 -0
- zenml/models/v2/misc/full_stack.py +97 -0
- zenml/models/v2/misc/stack_deployment.py +86 -0
- zenml/new/pipelines/pipeline.py +1 -1
- zenml/orchestrators/input_utils.py +3 -6
- zenml/stack/stack.py +3 -6
- zenml/stack_deployments/__init__.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +254 -0
- zenml/stack_deployments/gcp_stack_deployment.py +260 -0
- zenml/stack_deployments/stack_deployment.py +208 -0
- zenml/stack_deployments/utils.py +44 -0
- zenml/utils/function_utils.py +1 -1
- zenml/utils/pagination_utils.py +7 -5
- zenml/utils/pipeline_docker_image_builder.py +97 -68
- zenml/utils/pydantic_utils.py +6 -5
- zenml/zen_server/cloud_utils.py +18 -3
- zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
- zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
- zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
- zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
- zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
- zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
- zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
- zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
- zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
- zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
- zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
- zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
- zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
- zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
- zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
- zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
- zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
- zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
- zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
- zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
- zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
- zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
- zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
- zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
- zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
- zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
- zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
- zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
- zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
- zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
- zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
- zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
- zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
- zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
- zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
- zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
- zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
- zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
- zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
- zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
- zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
- zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
- zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
- zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
- zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
- zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
- zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
- zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
- zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
- zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
- zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
- zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
- zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.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.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.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/feature_gate/zenml_cloud_feature_gate.py +11 -5
- zenml/zen_server/pipeline_deployment/utils.py +57 -44
- zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
- zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
- zenml/zen_server/routers/workspaces_endpoints.py +64 -0
- zenml/zen_server/zen_server_api.py +2 -0
- zenml/zen_stores/migrations/utils.py +1 -1
- zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
- zenml/zen_stores/rest_zen_store.py +145 -4
- zenml/zen_stores/schemas/stack_schemas.py +10 -0
- zenml/zen_stores/schemas/step_run_schemas.py +27 -11
- zenml/zen_stores/sql_zen_store.py +300 -6
- zenml/zen_stores/zen_store_interface.py +80 -0
- {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +32 -10
- {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +178 -162
- zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
- zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
- zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
- zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
- zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
- zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
- zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
- zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
- zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
- zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
- zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
- zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
- zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
- zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
- zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
- zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
- zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
- zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
- zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
- zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
- zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
- zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
- zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
- zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
- zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
- zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
- zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
- zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
- zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
- zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
- zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
- zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
- zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
- {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
@@ -31,6 +31,9 @@ class KubeflowIntegration(Integration):
|
|
31
31
|
|
32
32
|
NAME = KUBEFLOW
|
33
33
|
REQUIREMENTS = ["kfp>=2.6.0", "kfp-kubernetes>=1.1.0"] # Only 1.x version that supports pyyaml 6
|
34
|
+
REQUIREMENTS_IGNORED_ON_UNINSTALL = [
|
35
|
+
"kfp", # it is used by GCP as well
|
36
|
+
]
|
34
37
|
|
35
38
|
@classmethod
|
36
39
|
def flavors(cls) -> List[Type[Flavor]]:
|
@@ -149,7 +149,7 @@ class KubeflowOrchestratorConfig(
|
|
149
149
|
|
150
150
|
kubeflow_hostname: Optional[str] = None
|
151
151
|
kubeflow_namespace: str = "kubeflow"
|
152
|
-
kubernetes_context: Optional[str] # TODO: Potential setting
|
152
|
+
kubernetes_context: Optional[str] = None # TODO: Potential setting
|
153
153
|
|
154
154
|
@model_validator(mode="before")
|
155
155
|
@classmethod
|
@@ -31,7 +31,9 @@ class KubernetesIntegration(Integration):
|
|
31
31
|
|
32
32
|
NAME = KUBERNETES
|
33
33
|
REQUIREMENTS = ["kubernetes>=21.7,<26"]
|
34
|
-
|
34
|
+
REQUIREMENTS_IGNORED_ON_UNINSTALL = [
|
35
|
+
"kfp", # it is used by many others
|
36
|
+
]
|
35
37
|
@classmethod
|
36
38
|
def flavors(cls) -> List[Type[Flavor]]:
|
37
39
|
"""Declare the stack component flavors for the Kubernetes integration.
|
@@ -225,8 +225,11 @@ def wait_pod(
|
|
225
225
|
response = core_api.read_namespaced_pod_log(
|
226
226
|
name=pod_name,
|
227
227
|
namespace=namespace,
|
228
|
+
_preload_content=False,
|
228
229
|
)
|
229
|
-
|
230
|
+
raw_data = response.data
|
231
|
+
decoded_log = raw_data.decode("utf-8", errors="replace")
|
232
|
+
logs = decoded_log.splitlines()
|
230
233
|
if len(logs) > logged_lines:
|
231
234
|
for line in logs[logged_lines:]:
|
232
235
|
logger.info(line)
|
@@ -45,9 +45,11 @@ class MlflowIntegration(Integration):
|
|
45
45
|
# This downgrades pydantic to v1 even though mlflow does not have
|
46
46
|
# any issues with v2. This is why we have to pin it here so a downgrade
|
47
47
|
# will not happen.
|
48
|
-
"pydantic>=2.7.0,<2.8.0"
|
48
|
+
"pydantic>=2.7.0,<2.8.0",
|
49
49
|
]
|
50
50
|
|
51
|
+
REQUIREMENTS_IGNORED_ON_UNINSTALL = ["python-rapidjson", "pydantic"]
|
52
|
+
|
51
53
|
@classmethod
|
52
54
|
def activate(cls) -> None:
|
53
55
|
"""Activate the MLflow integration."""
|
zenml/integrations/registry.py
CHANGED
@@ -124,6 +124,43 @@ class IntegrationRegistry(object):
|
|
124
124
|
)
|
125
125
|
]
|
126
126
|
|
127
|
+
def select_uninstall_requirements(
|
128
|
+
self,
|
129
|
+
integration_name: Optional[str] = None,
|
130
|
+
target_os: Optional[str] = None,
|
131
|
+
) -> List[str]:
|
132
|
+
"""Select the uninstall requirements for a given integration or all integrations.
|
133
|
+
|
134
|
+
Args:
|
135
|
+
integration_name: Name of the integration to check.
|
136
|
+
target_os: Target OS for the requirements.
|
137
|
+
|
138
|
+
Returns:
|
139
|
+
List of requirements for the integration uninstall.
|
140
|
+
|
141
|
+
Raises:
|
142
|
+
KeyError: If the integration is not found.
|
143
|
+
"""
|
144
|
+
if integration_name:
|
145
|
+
if integration_name in self.list_integration_names:
|
146
|
+
return self._integrations[
|
147
|
+
integration_name
|
148
|
+
].get_uninstall_requirements(target_os=target_os)
|
149
|
+
else:
|
150
|
+
raise KeyError(
|
151
|
+
f"Version {integration_name} does not exist. "
|
152
|
+
f"Currently the following integrations are implemented. "
|
153
|
+
f"{self.list_integration_names}"
|
154
|
+
)
|
155
|
+
else:
|
156
|
+
return [
|
157
|
+
requirement
|
158
|
+
for name in self.list_integration_names
|
159
|
+
for requirement in self._integrations[
|
160
|
+
name
|
161
|
+
].get_uninstall_requirements(target_os=target_os)
|
162
|
+
]
|
163
|
+
|
127
164
|
def is_installed(self, integration_name: Optional[str] = None) -> bool:
|
128
165
|
"""Checks if all requirements for an integration are installed.
|
129
166
|
|
@@ -122,7 +122,7 @@ class S3ArtifactStore(BaseArtifactStore, AuthenticationMixin):
|
|
122
122
|
|
123
123
|
def get_credentials(
|
124
124
|
self,
|
125
|
-
) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
125
|
+
) -> Tuple[Optional[str], Optional[str], Optional[str], Optional[str]]:
|
126
126
|
"""Gets authentication credentials.
|
127
127
|
|
128
128
|
If an authentication secret is configured, the secret values are
|
@@ -130,8 +130,8 @@ class S3ArtifactStore(BaseArtifactStore, AuthenticationMixin):
|
|
130
130
|
attributes.
|
131
131
|
|
132
132
|
Returns:
|
133
|
-
Tuple (key, secret, token) of credentials used to
|
134
|
-
the S3 filesystem.
|
133
|
+
Tuple (key, secret, token, region) of credentials used to
|
134
|
+
authenticate with the S3 filesystem.
|
135
135
|
|
136
136
|
Raises:
|
137
137
|
RuntimeError: If the AWS connector behaves unexpectedly.
|
@@ -151,6 +151,7 @@ class S3ArtifactStore(BaseArtifactStore, AuthenticationMixin):
|
|
151
151
|
credentials.access_key,
|
152
152
|
credentials.secret_key,
|
153
153
|
credentials.token,
|
154
|
+
client.meta.region_name,
|
154
155
|
)
|
155
156
|
|
156
157
|
secret = self.get_typed_authentication_secret(
|
@@ -161,9 +162,10 @@ class S3ArtifactStore(BaseArtifactStore, AuthenticationMixin):
|
|
161
162
|
secret.aws_access_key_id,
|
162
163
|
secret.aws_secret_access_key,
|
163
164
|
secret.aws_session_token,
|
165
|
+
None,
|
164
166
|
)
|
165
167
|
else:
|
166
|
-
return self.config.key, self.config.secret, self.config.token
|
168
|
+
return self.config.key, self.config.secret, self.config.token, None
|
167
169
|
|
168
170
|
@property
|
169
171
|
def filesystem(self) -> ZenMLS3Filesystem:
|
@@ -176,13 +178,22 @@ class S3ArtifactStore(BaseArtifactStore, AuthenticationMixin):
|
|
176
178
|
if self._filesystem and not self.connector_has_expired():
|
177
179
|
return self._filesystem
|
178
180
|
|
179
|
-
key, secret, token = self.get_credentials()
|
181
|
+
key, secret, token, region = self.get_credentials()
|
182
|
+
|
183
|
+
# Use the region from the connector if available, otherwise some
|
184
|
+
# remote workloads (e.g. Sagemaker) might not work correctly because
|
185
|
+
# they look for the bucket in the wrong region
|
186
|
+
client_kwargs = {}
|
187
|
+
if region:
|
188
|
+
client_kwargs["region_name"] = region
|
189
|
+
if self.config.client_kwargs:
|
190
|
+
client_kwargs.update(self.config.client_kwargs)
|
180
191
|
|
181
192
|
self._filesystem = ZenMLS3Filesystem(
|
182
193
|
key=key,
|
183
194
|
secret=secret,
|
184
195
|
token=token,
|
185
|
-
client_kwargs=
|
196
|
+
client_kwargs=client_kwargs,
|
186
197
|
config_kwargs=self.config.config_kwargs,
|
187
198
|
s3_additional_kwargs=self.config.s3_additional_kwargs,
|
188
199
|
)
|
@@ -43,7 +43,7 @@ class SkypilotBaseOrchestratorSettings(BaseSettings):
|
|
43
43
|
`{'tpu_vm': True, 'runtime_version': 'tpu-vm-base'}` for TPUs.
|
44
44
|
use_spot: whether to use spot instances. If None, defaults to
|
45
45
|
False.
|
46
|
-
|
46
|
+
job_recovery: the spot recovery strategy to use for the managed
|
47
47
|
spot to recover the cluster from preemption. Refer to
|
48
48
|
`recovery_strategy module <https://github.com/skypilot-org/skypilot/blob/master/sky/spot/recovery_strategy.py>`__ # pylint: disable=line-too-long
|
49
49
|
for more details.
|
@@ -103,7 +103,7 @@ class SkypilotBaseOrchestratorSettings(BaseSettings):
|
|
103
103
|
)
|
104
104
|
accelerator_args: Optional[Dict[str, str]] = None
|
105
105
|
use_spot: Optional[bool] = None
|
106
|
-
|
106
|
+
job_recovery: Optional[str] = None
|
107
107
|
region: Optional[str] = None
|
108
108
|
zone: Optional[str] = None
|
109
109
|
image_id: Union[Dict[str, str], str, None] = Field(
|
@@ -303,7 +303,7 @@ class SkypilotBaseOrchestrator(ContainerizedOrchestrator):
|
|
303
303
|
accelerators=settings.accelerators,
|
304
304
|
accelerator_args=settings.accelerator_args,
|
305
305
|
use_spot=settings.use_spot,
|
306
|
-
|
306
|
+
job_recovery=settings.job_recovery,
|
307
307
|
region=settings.region,
|
308
308
|
zone=settings.zone,
|
309
309
|
image_id=settings.image_id,
|
@@ -136,7 +136,7 @@ def main() -> None:
|
|
136
136
|
settings.disk_size, # Assuming disk_size is part of the settings
|
137
137
|
settings.disk_tier, # Assuming disk_tier is part of the settings
|
138
138
|
settings.use_spot,
|
139
|
-
settings.
|
139
|
+
settings.job_recovery,
|
140
140
|
settings.region,
|
141
141
|
settings.zone,
|
142
142
|
accelerators_hashable,
|
@@ -213,7 +213,7 @@ def main() -> None:
|
|
213
213
|
accelerators=settings.accelerators,
|
214
214
|
accelerator_args=settings.accelerator_args,
|
215
215
|
use_spot=settings.use_spot,
|
216
|
-
|
216
|
+
job_recovery=settings.job_recovery,
|
217
217
|
region=settings.region,
|
218
218
|
zone=settings.zone,
|
219
219
|
image_id=settings.image_id,
|
@@ -31,7 +31,8 @@ class SkypilotAWSIntegration(Integration):
|
|
31
31
|
"""Definition of Skypilot AWS Integration for ZenML."""
|
32
32
|
|
33
33
|
NAME = SKYPILOT_AWS
|
34
|
-
|
34
|
+
# all 0.6.x versions of skypilot[aws] are compatible
|
35
|
+
REQUIREMENTS = ["skypilot[aws]~=0.6.0"]
|
35
36
|
APT_PACKAGES = ["openssh-client", "rsync"]
|
36
37
|
|
37
38
|
@classmethod
|
@@ -33,7 +33,7 @@ class SkypilotAzureIntegration(Integration):
|
|
33
33
|
"""Definition of Skypilot (Azure) Integration for ZenML."""
|
34
34
|
|
35
35
|
NAME = SKYPILOT_AZURE
|
36
|
-
REQUIREMENTS = ["skypilot[azure]
|
36
|
+
REQUIREMENTS = ["skypilot[azure]~=0.6.0"]
|
37
37
|
APT_PACKAGES = ["openssh-client", "rsync"]
|
38
38
|
|
39
39
|
@classmethod
|
@@ -31,7 +31,7 @@ class SkypilotGCPIntegration(Integration):
|
|
31
31
|
"""Definition of Skypilot (GCP) Integration for ZenML."""
|
32
32
|
|
33
33
|
NAME = SKYPILOT_GCP
|
34
|
-
REQUIREMENTS = ["skypilot[gcp]
|
34
|
+
REQUIREMENTS = ["skypilot[gcp]~=0.6.0"]
|
35
35
|
APT_PACKAGES = ["openssh-client", "rsync"]
|
36
36
|
|
37
37
|
@classmethod
|
@@ -31,7 +31,7 @@ class SkypilotLambdaIntegration(Integration):
|
|
31
31
|
"""Definition of Skypilot Lambda Integration for ZenML."""
|
32
32
|
|
33
33
|
NAME = SKYPILOT_LAMBDA
|
34
|
-
REQUIREMENTS = ["skypilot[lambda]<=0.
|
34
|
+
REQUIREMENTS = ["skypilot[lambda]<=0.6.0"]
|
35
35
|
|
36
36
|
@classmethod
|
37
37
|
def flavors(cls) -> List[Type[Flavor]]:
|
@@ -40,7 +40,7 @@ class SkypilotLambdaOrchestratorSettings(SkypilotBaseOrchestratorSettings):
|
|
40
40
|
|
41
41
|
_UNSUPPORTED_FEATURES = {
|
42
42
|
"use_spot": "Spot instances not supported for Lambda orchestrator.",
|
43
|
-
"
|
43
|
+
"job_recovery": "Job recovery not supported for Lambda orchestrator.",
|
44
44
|
"image_id": "Custom image IDs not supported for Lambda orchestrator.",
|
45
45
|
# Add other unsupported features as needed
|
46
46
|
}
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Initialization for TensorBoard integration."""
|
15
15
|
|
16
|
-
import sys
|
17
16
|
from typing import List, Optional
|
18
17
|
from zenml.integrations.constants import TENSORBOARD
|
19
18
|
from zenml.integrations.integration import Integration
|
@@ -18,6 +18,9 @@ import sys
|
|
18
18
|
from typing import List, Optional
|
19
19
|
from zenml.integrations.constants import TENSORFLOW
|
20
20
|
from zenml.integrations.integration import Integration
|
21
|
+
from zenml.logger import get_logger
|
22
|
+
|
23
|
+
logger = get_logger(__name__)
|
21
24
|
|
22
25
|
|
23
26
|
class TensorflowIntegration(Integration):
|
@@ -25,20 +28,27 @@ class TensorflowIntegration(Integration):
|
|
25
28
|
|
26
29
|
NAME = TENSORFLOW
|
27
30
|
REQUIREMENTS = []
|
31
|
+
REQUIREMENTS_IGNORED_ON_UNINSTALL = ["typing-extensions"]
|
28
32
|
|
29
33
|
@classmethod
|
30
34
|
def activate(cls) -> None:
|
31
35
|
"""Activates the integration."""
|
32
36
|
# need to import this explicitly to load the Tensorflow file IO support
|
33
37
|
# for S3 and other file systems
|
34
|
-
if (
|
35
|
-
not platform.system() == "Darwin"
|
36
|
-
or not platform.machine() == "arm64"
|
37
|
-
):
|
38
|
+
if not platform.system() == "Darwin" or not platform.machine() == "arm64":
|
38
39
|
import tensorflow_io # type: ignore
|
39
40
|
|
40
41
|
from zenml.integrations.tensorflow import materializers # noqa
|
41
42
|
|
43
|
+
if sys.version_info.minor == 8:
|
44
|
+
logger.warning(
|
45
|
+
"Python 3.8 with TensorFlow is not fully "
|
46
|
+
"compatible with Pydantic 2 requirements. "
|
47
|
+
"Consider upgrading to a higher Python "
|
48
|
+
"version if you would like to use the "
|
49
|
+
"Tensorflow integration."
|
50
|
+
)
|
51
|
+
|
42
52
|
@classmethod
|
43
53
|
def get_requirements(cls, target_os: Optional[str] = None) -> List[str]:
|
44
54
|
"""Defines platform specific requirements for the integration.
|
@@ -52,13 +62,15 @@ class TensorflowIntegration(Integration):
|
|
52
62
|
target_os = target_os or platform.system()
|
53
63
|
if target_os == "Darwin" and platform.machine() == "arm64":
|
54
64
|
requirements = [
|
55
|
-
|
65
|
+
"tensorflow-macos>=2.12,<=2.15",
|
56
66
|
]
|
57
67
|
else:
|
58
68
|
requirements = [
|
59
|
-
|
69
|
+
"tensorflow>=2.12,<=2.15",
|
60
70
|
"tensorflow_io>=0.24.0",
|
61
71
|
]
|
72
|
+
if sys.version_info.minor == 8:
|
73
|
+
requirements.append("typing-extensions>=4.6.1")
|
62
74
|
return requirements
|
63
75
|
|
64
76
|
|
zenml/models/__init__.py
CHANGED
@@ -327,6 +327,7 @@ from zenml.models.v2.misc.service_connector_type import (
|
|
327
327
|
ResourceTypeModel,
|
328
328
|
)
|
329
329
|
from zenml.models.v2.misc.server_models import ServerDatabaseType, ServerModel
|
330
|
+
from zenml.models.v2.misc.full_stack import FullStackRequest
|
330
331
|
from zenml.models.v2.core.trigger import (
|
331
332
|
TriggerRequest,
|
332
333
|
TriggerFilter,
|
@@ -386,6 +387,11 @@ from zenml.models.v2.core.server_settings import (
|
|
386
387
|
ServerSettingsResponseMetadata,
|
387
388
|
ServerSettingsUpdate,
|
388
389
|
)
|
390
|
+
from zenml.models.v2.misc.stack_deployment import (
|
391
|
+
DeployedStack,
|
392
|
+
StackDeploymentConfig,
|
393
|
+
StackDeploymentInfo,
|
394
|
+
)
|
389
395
|
|
390
396
|
# ----------------------------- Forward References -----------------------------
|
391
397
|
|
@@ -405,6 +411,7 @@ EventSourceResponseMetadata.model_rebuild()
|
|
405
411
|
EventSourceResponseResources.model_rebuild()
|
406
412
|
FlavorResponseBody.model_rebuild()
|
407
413
|
FlavorResponseMetadata.model_rebuild()
|
414
|
+
FullStackRequest.model_rebuild()
|
408
415
|
LazyArtifactVersionResponse.model_rebuild()
|
409
416
|
LazyRunMetadataResponse.model_rebuild()
|
410
417
|
ModelResponseBody.model_rebuild()
|
@@ -701,11 +708,13 @@ __all__ = [
|
|
701
708
|
"WorkspaceResponseMetadata",
|
702
709
|
# V2 Misc
|
703
710
|
"AuthenticationMethodModel",
|
711
|
+
"DeployedStack",
|
704
712
|
"ServiceConnectorResourcesModel",
|
705
713
|
"ServiceConnectorTypeModel",
|
706
714
|
"ServiceConnectorTypedResourcesModel",
|
707
715
|
"ServiceConnectorRequirements",
|
708
716
|
"ResourceTypeModel",
|
717
|
+
"FullStackRequest",
|
709
718
|
"UserAuthModel",
|
710
719
|
"ExternalUserModel",
|
711
720
|
"BuildItem",
|
@@ -718,6 +727,8 @@ __all__ = [
|
|
718
727
|
"ServerModel",
|
719
728
|
"ServerDatabaseType",
|
720
729
|
"ServerDeploymentType",
|
730
|
+
"StackDeploymentConfig",
|
731
|
+
"StackDeploymentInfo",
|
721
732
|
"OAuthDeviceAuthorizationRequest",
|
722
733
|
"OAuthDeviceAuthorizationResponse",
|
723
734
|
"OAuthDeviceTokenRequest",
|
@@ -238,6 +238,24 @@ class ComponentResponse(
|
|
238
238
|
max_length=STR_FIELD_MAX_LENGTH,
|
239
239
|
)
|
240
240
|
|
241
|
+
def get_analytics_metadata(self) -> Dict[str, Any]:
|
242
|
+
"""Add the component labels to analytics metadata.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
Dict of analytics metadata.
|
246
|
+
"""
|
247
|
+
metadata = super().get_analytics_metadata()
|
248
|
+
|
249
|
+
if self.labels is not None:
|
250
|
+
metadata.update(
|
251
|
+
{
|
252
|
+
label[6:]: value
|
253
|
+
for label, value in self.labels.items()
|
254
|
+
if label.startswith("zenml:")
|
255
|
+
}
|
256
|
+
)
|
257
|
+
return metadata
|
258
|
+
|
241
259
|
def get_hydrated_version(self) -> "ComponentResponse":
|
242
260
|
"""Get the hydrated version of this component.
|
243
261
|
|
zenml/models/v2/core/model.py
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing models."""
|
15
15
|
|
16
|
-
from functools import partial
|
17
16
|
from typing import TYPE_CHECKING, ClassVar, List, Optional, Union
|
18
17
|
from uuid import UUID
|
19
18
|
|
@@ -303,7 +302,7 @@ class ModelResponse(
|
|
303
302
|
|
304
303
|
client = Client()
|
305
304
|
model_versions = depaginate(
|
306
|
-
|
305
|
+
client.list_model_versions, model_name_or_id=self.id
|
307
306
|
)
|
308
307
|
return [
|
309
308
|
mv.to_model_class(suppress_class_validation_warnings=True)
|
@@ -493,6 +493,23 @@ class ServiceConnectorResponse(
|
|
493
493
|
max_length=STR_FIELD_MAX_LENGTH,
|
494
494
|
)
|
495
495
|
|
496
|
+
def get_analytics_metadata(self) -> Dict[str, Any]:
|
497
|
+
"""Add the service connector labels to analytics metadata.
|
498
|
+
|
499
|
+
Returns:
|
500
|
+
Dict of analytics metadata.
|
501
|
+
"""
|
502
|
+
metadata = super().get_analytics_metadata()
|
503
|
+
|
504
|
+
metadata.update(
|
505
|
+
{
|
506
|
+
label[6:]: value
|
507
|
+
for label, value in self.labels.items()
|
508
|
+
if label.startswith("zenml:")
|
509
|
+
}
|
510
|
+
)
|
511
|
+
return metadata
|
512
|
+
|
496
513
|
def get_hydrated_version(self) -> "ServiceConnectorResponse":
|
497
514
|
"""Get the hydrated version of this service connector.
|
498
515
|
|
zenml/models/v2/core/stack.py
CHANGED
@@ -36,6 +36,7 @@ from zenml.models.v2.core.component import ComponentResponse
|
|
36
36
|
if TYPE_CHECKING:
|
37
37
|
from sqlalchemy.sql.elements import ColumnElement
|
38
38
|
|
39
|
+
|
39
40
|
# ------------------ Request Model ------------------
|
40
41
|
|
41
42
|
|
@@ -59,6 +60,10 @@ class StackRequest(WorkspaceScopedRequest):
|
|
59
60
|
title="A mapping of stack component types to the actual"
|
60
61
|
"instances of components of this type.",
|
61
62
|
)
|
63
|
+
labels: Optional[Dict[str, Any]] = Field(
|
64
|
+
default=None,
|
65
|
+
title="The stack labels.",
|
66
|
+
)
|
62
67
|
|
63
68
|
@property
|
64
69
|
def is_valid(self) -> bool:
|
@@ -109,6 +114,10 @@ class StackUpdate(BaseUpdate):
|
|
109
114
|
"instances of components of this type.",
|
110
115
|
default=None,
|
111
116
|
)
|
117
|
+
labels: Optional[Dict[str, Any]] = Field(
|
118
|
+
default=None,
|
119
|
+
title="The stack labels.",
|
120
|
+
)
|
112
121
|
|
113
122
|
|
114
123
|
# ------------------ Response Model ------------------
|
@@ -134,6 +143,10 @@ class StackResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
134
143
|
default=None,
|
135
144
|
title="The path to the stack spec used for mlstacks deployments.",
|
136
145
|
)
|
146
|
+
labels: Optional[Dict[str, Any]] = Field(
|
147
|
+
default=None,
|
148
|
+
title="The stack labels.",
|
149
|
+
)
|
137
150
|
|
138
151
|
|
139
152
|
class StackResponseResources(WorkspaceScopedResponseResources):
|
@@ -214,6 +227,15 @@ class StackResponse(
|
|
214
227
|
"""
|
215
228
|
metadata = super().get_analytics_metadata()
|
216
229
|
metadata.update({ct: c[0].flavor for ct, c in self.components.items()})
|
230
|
+
|
231
|
+
if self.labels is not None:
|
232
|
+
metadata.update(
|
233
|
+
{
|
234
|
+
label[6:]: value
|
235
|
+
for label, value in self.labels.items()
|
236
|
+
if label.startswith("zenml:")
|
237
|
+
}
|
238
|
+
)
|
217
239
|
return metadata
|
218
240
|
|
219
241
|
@property
|
@@ -243,6 +265,15 @@ class StackResponse(
|
|
243
265
|
"""
|
244
266
|
return self.get_metadata().components
|
245
267
|
|
268
|
+
@property
|
269
|
+
def labels(self) -> Optional[Dict[str, Any]]:
|
270
|
+
"""The `labels` property.
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
the value of the property.
|
274
|
+
"""
|
275
|
+
return self.get_metadata().labels
|
276
|
+
|
246
277
|
|
247
278
|
# ------------------ Filter Model ------------------
|
248
279
|
|