zenml-nightly 0.75.0.dev20250317__py3-none-any.whl → 0.80.0.dev20250321__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/__init__.py +3 -1
- zenml/artifacts/artifact_config.py +2 -2
- zenml/artifacts/utils.py +4 -8
- zenml/cli/__init__.py +6 -6
- zenml/cli/base.py +2 -2
- zenml/cli/login.py +2 -2
- zenml/cli/server.py +6 -4
- zenml/cli/utils.py +3 -3
- zenml/client.py +9 -9
- zenml/config/compiler.py +1 -1
- zenml/config/server_config.py +1 -1
- zenml/constants.py +2 -1
- zenml/enums.py +12 -0
- zenml/integrations/airflow/__init__.py +0 -2
- zenml/integrations/argilla/__init__.py +0 -1
- zenml/integrations/aws/__init__.py +0 -3
- zenml/integrations/azure/__init__.py +0 -2
- zenml/integrations/azure/service_connectors/azure_service_connector.py +1 -1
- zenml/integrations/bentoml/__init__.py +0 -2
- zenml/integrations/bentoml/services/bentoml_container_deployment.py +2 -2
- zenml/integrations/bentoml/services/bentoml_local_deployment.py +1 -1
- zenml/integrations/bentoml/steps/bentoml_deployer.py +1 -1
- zenml/integrations/bitbucket/__init__.py +0 -2
- zenml/integrations/comet/__init__.py +0 -2
- zenml/integrations/databricks/__init__.py +0 -2
- zenml/integrations/databricks/services/databricks_deployment.py +3 -1
- zenml/integrations/deepchecks/__init__.py +0 -2
- zenml/integrations/discord/__init__.py +0 -2
- zenml/integrations/evidently/__init__.py +0 -2
- zenml/integrations/facets/__init__.py +0 -2
- zenml/integrations/feast/__init__.py +0 -2
- zenml/integrations/gcp/__init__.py +0 -3
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +5 -0
- zenml/integrations/github/__init__.py +0 -2
- zenml/integrations/github/code_repositories/github_code_repository.py +10 -3
- zenml/integrations/gitlab/__init__.py +0 -1
- zenml/integrations/gitlab/code_repositories/gitlab_code_repository.py +5 -2
- zenml/integrations/great_expectations/__init__.py +0 -3
- zenml/integrations/huggingface/__init__.py +0 -1
- zenml/integrations/huggingface/services/huggingface_deployment.py +3 -1
- zenml/integrations/hyperai/__init__.py +0 -2
- zenml/integrations/kaniko/__init__.py +0 -2
- zenml/integrations/kubeflow/__init__.py +0 -1
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +6 -0
- zenml/integrations/kubernetes/__init__.py +0 -2
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +4 -0
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +89 -1
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +82 -48
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +44 -10
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +45 -1
- zenml/integrations/kubernetes/pod_settings.py +52 -0
- zenml/integrations/label_studio/__init__.py +0 -2
- zenml/integrations/langchain/__init__.py +0 -2
- zenml/integrations/lightgbm/__init__.py +0 -1
- zenml/integrations/lightning/__init__.py +0 -2
- zenml/integrations/mlflow/__init__.py +1 -3
- zenml/integrations/mlflow/services/mlflow_deployment.py +1 -1
- zenml/integrations/modal/__init__.py +0 -1
- zenml/integrations/neptune/__init__.py +0 -2
- zenml/integrations/neural_prophet/__init__.py +0 -2
- zenml/integrations/numpy/__init__.py +0 -2
- zenml/integrations/openai/__init__.py +0 -1
- zenml/integrations/pandas/__init__.py +0 -2
- zenml/integrations/pigeon/__init__.py +0 -1
- zenml/integrations/pillow/__init__.py +0 -3
- zenml/integrations/polars/__init__.py +0 -2
- zenml/integrations/prodigy/__init__.py +0 -1
- zenml/integrations/pycaret/__init__.py +0 -2
- zenml/integrations/pytorch/__init__.py +0 -1
- zenml/integrations/pytorch_lightning/__init__.py +0 -2
- zenml/integrations/s3/__init__.py +0 -2
- zenml/integrations/scipy/__init__.py +0 -2
- zenml/integrations/seldon/__init__.py +0 -2
- zenml/integrations/seldon/services/seldon_deployment.py +3 -2
- zenml/integrations/sklearn/__init__.py +1 -1
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +43 -18
- zenml/integrations/skypilot_aws/__init__.py +1 -3
- zenml/integrations/skypilot_azure/__init__.py +1 -2
- zenml/integrations/skypilot_gcp/__init__.py +1 -3
- zenml/integrations/skypilot_kubernetes/__init__.py +1 -3
- zenml/integrations/skypilot_lambda/__init__.py +1 -3
- zenml/integrations/slack/__init__.py +0 -1
- zenml/integrations/spark/__init__.py +0 -1
- zenml/integrations/tekton/__init__.py +0 -1
- zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +5 -0
- zenml/integrations/tensorboard/__init__.py +0 -2
- zenml/integrations/tensorboard/services/tensorboard_service.py +1 -1
- zenml/integrations/tensorflow/__init__.py +0 -2
- zenml/integrations/vllm/__init__.py +0 -1
- zenml/integrations/vllm/services/vllm_deployment.py +1 -1
- zenml/integrations/wandb/__init__.py +0 -1
- zenml/integrations/whylogs/__init__.py +0 -1
- zenml/integrations/xgboost/__init__.py +0 -2
- zenml/login/credentials.py +1 -1
- zenml/login/pro/utils.py +1 -0
- zenml/materializers/__init__.py +1 -0
- zenml/model_deployers/base_model_deployer.py +1 -1
- zenml/models/__init__.py +4 -0
- zenml/models/v2/base/filter.py +162 -54
- zenml/models/v2/base/scoped.py +132 -0
- zenml/models/v2/core/artifact_version.py +12 -33
- zenml/models/v2/core/model_version.py +12 -50
- zenml/models/v2/core/pipeline_run.py +12 -32
- zenml/models/v2/core/service.py +2 -2
- zenml/models/v2/core/step_run.py +15 -32
- zenml/{services/service_type.py → models/v2/misc/service.py} +1 -1
- zenml/orchestrators/step_run_utils.py +1 -1
- zenml/orchestrators/utils.py +1 -1
- zenml/services/__init__.py +3 -5
- zenml/services/container/container_service.py +2 -1
- zenml/services/local/local_service.py +2 -1
- zenml/services/service.py +3 -2
- zenml/services/service_endpoint.py +2 -1
- zenml/services/service_monitor.py +1 -1
- zenml/services/service_status.py +1 -12
- zenml/steps/entrypoint_function_utils.py +1 -1
- zenml/utils/dashboard_utils.py +73 -8
- zenml/utils/server_utils.py +52 -0
- zenml/zen_server/dashboard/assets/{404-BbAvjc7Z.js → 404-2I8egBQu.js} +1 -1
- zenml/zen_server/dashboard/assets/@reactflow-BHoFKFSZ.js +17 -0
- zenml/zen_server/dashboard/assets/{AlertDialogDropdownItem-XL2NfFgP.js → AlertDialogDropdownItem-D7KZcPFw.js} +1 -1
- zenml/zen_server/dashboard/assets/CodeSnippet-DUkCnBpQ.js +9 -0
- zenml/zen_server/dashboard/assets/{CollapsibleCard-Djtd_ocf.js → CollapsibleCard-B5-5Plnd.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-V-hH_IKQ.js → Commands-CbOMmarC.js} +1 -1
- zenml/zen_server/dashboard/assets/{ComponentBadge-CVN2FsiW.js → ComponentBadge-FrujKBC6.js} +1 -1
- zenml/zen_server/dashboard/assets/ComponentIcon-Dx5fBrDX.js +1 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-CWaQcWIN.js → CsvVizualization-B8E3p9we.js} +1 -1
- zenml/zen_server/dashboard/assets/{DeleteAlertDialog-CTLRrcFM.js → DeleteAlertDialog-BgTZbbAt.js} +1 -1
- zenml/zen_server/dashboard/assets/{DialogItem-ST291Hsl.js → DialogItem-CNWLiJcc.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-CIBjAdSc.js → Error-BkUP4Luv.js} +1 -1
- zenml/zen_server/dashboard/assets/ExecutionStatus-CD8Vj7sp.js +1 -0
- zenml/zen_server/dashboard/assets/{Helpbox-cwQNH06F.js → Helpbox-DIx6mDOH.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-DYKoAVhW.js → Infobox-BHEdNmME.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-Bk4QLPTU.js → InlineAvatar-Bin9UPKJ.js} +1 -1
- zenml/zen_server/dashboard/assets/{NestedCollapsible-CE4OF670.js → NestedCollapsible-Da-k0Mff.js} +1 -1
- zenml/zen_server/dashboard/assets/{Partials-cL1-u_sT.js → Partials-TNaYjHsV.js} +1 -1
- zenml/zen_server/dashboard/assets/ProBadge-BfPp-B97.js +1 -0
- zenml/zen_server/dashboard/assets/{ProCta-DtUutIul.js → ProCta-7_FtpX3I.js} +1 -1
- zenml/zen_server/dashboard/assets/ProviderIcon-CxeziA5a.js +1 -0
- zenml/zen_server/dashboard/assets/{ProviderRadio-C4bltH6-.js → ProviderRadio-DPmZHff_.js} +1 -1
- zenml/zen_server/dashboard/assets/RunSelector-BVKB4Z8F.js +1 -0
- zenml/zen_server/dashboard/assets/{RunsBody-D2VoO-cR.js → RunsBody-Cj4sIqQB.js} +1 -1
- zenml/zen_server/dashboard/assets/{SearchField-DfNxVtjV.js → SearchField-DjAOZic5.js} +1 -1
- zenml/zen_server/dashboard/assets/SecretTooltip-mMAAP4dM.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-CWl2mwz8.js → SetPassword-B0o5kSJU.js} +1 -1
- zenml/zen_server/dashboard/assets/{StackList-C8KNd00o.js → StackList-5UB8LoEq.js} +1 -1
- zenml/zen_server/dashboard/assets/{Tabs-BEWDPvPV.js → Tabs-AuhCyzle.js} +1 -1
- zenml/zen_server/dashboard/assets/Tick-CHW0jc8Y.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DCuCj7NK.js → UpdatePasswordSchemas-Bauivjf-.js} +1 -1
- zenml/zen_server/dashboard/assets/{UsageReason-CwUrEwEz.js → UsageReason-Dr5ca5M4.js} +1 -1
- zenml/zen_server/dashboard/assets/{Wizard-CynnoHg4.js → Wizard-XEp9rGmf.js} +1 -1
- zenml/zen_server/dashboard/assets/{WizardFooter-B2bYs89C.js → WizardFooter-BtL1Gi1k.js} +1 -1
- zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-B509kMlL.js → all-pipeline-runs-query-COvsm3bC.js} +1 -1
- zenml/zen_server/dashboard/assets/configuration-form-BJUCr0wl.js +1 -0
- zenml/zen_server/dashboard/assets/{create-stack-BjWXz5nx.js → create-stack-B2c98UlP.js} +1 -1
- zenml/zen_server/dashboard/assets/{delete-run-CzPWbsBy.js → delete-run-Do3XyF4W.js} +1 -1
- zenml/zen_server/dashboard/assets/flavor-select-D8CranSY.js +1 -0
- zenml/zen_server/dashboard/assets/{form-schemas-B6u3P_a4.js → form-schemas-Bm-dTV3L.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-BCKg1Y5r.css → index-6mLFgFwe.css} +1 -1
- zenml/zen_server/dashboard/assets/{index-Bjeu4_0O.js → index-CzhJC6pc.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-CaRx22lH.js → index-D-n6tspq.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-DWoLoYDY.js → index-DPjvk73v.js} +8 -8
- zenml/zen_server/dashboard/assets/{index-Dba8yULY.js → index-eIIP-0dQ.js} +1 -1
- zenml/zen_server/dashboard/assets/login-mutation-D6uiKsKk.js +1 -0
- zenml/zen_server/dashboard/assets/{not-found-DGQ8rm7B.js → not-found-DFrksY0r.js} +1 -1
- zenml/zen_server/dashboard/assets/page-B-uHUFcm.js +1 -0
- zenml/zen_server/dashboard/assets/page-B0Llmzo_.js +1 -0
- zenml/zen_server/dashboard/assets/page-B150LbzG.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CfeQbejg.js → page-B1Un9vAU.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CxrLV30P.js → page-B80TE04v.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BIseZTJt.js +2 -0
- zenml/zen_server/dashboard/assets/{page-C5xq6rqE.js → page-BJ15SGwt.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-B6msmF1h.js → page-BJrZsPSh.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BMZaECzB.js +1 -0
- zenml/zen_server/dashboard/assets/{page-D1upvSPi.js → page-BTvnIFGR.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DLw1Apss.js → page-BXh1mF-D.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BZUxCBoD.js +1 -0
- zenml/zen_server/dashboard/assets/page-BeFiRx31.js +1 -0
- zenml/zen_server/dashboard/assets/{page-C89bN6VV.js → page-BnUwQBeg.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-k-UXKVnV.js → page-BqQ6y8Hb.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BwAFqFCf.js +1 -0
- zenml/zen_server/dashboard/assets/page-BzlVs5tC.js +1 -0
- zenml/zen_server/dashboard/assets/{page-C3BbJ-5n.js → page-C11vPVkH.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-AnG2ilmi.js → page-CAKBSE9f.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CPe9nQSo.js +1 -0
- zenml/zen_server/dashboard/assets/page-D0Zt2-7X.js +1 -0
- zenml/zen_server/dashboard/assets/page-D2F0Rvak.js +1 -0
- zenml/zen_server/dashboard/assets/{page-2EzZ5aWS.js → page-D5GZlpKq.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CxoG4zme.js → page-DBNBYSwq.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DDvwWgKP.js +6 -0
- zenml/zen_server/dashboard/assets/page-DF9q7ySu.js +1 -0
- zenml/zen_server/dashboard/assets/page-DOzFoJuo.js +1 -0
- zenml/zen_server/dashboard/assets/page-DaHH2ZEF.js +1 -0
- zenml/zen_server/dashboard/assets/{page-B9ELcPAy.js → page-Dd-0y3SU.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Dy6HYsJr.js → page-DhNnHHmX.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CZ_3LB0U.js → page-DkJfgcDi.js} +1 -1
- zenml/zen_server/dashboard/assets/page-EhqRFAZc.js +1 -0
- zenml/zen_server/dashboard/assets/{page-nHAZvd76.js → page-NIWnUdVg.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DazwBcbq.js → page-kYlFrH53.js} +1 -1
- zenml/zen_server/dashboard/assets/page-ygCPGHAV.js +1 -0
- zenml/zen_server/dashboard/assets/{persist-BglceT_t.js → persist-C5RlwSq6.js} +1 -1
- zenml/zen_server/dashboard/assets/{persist-CMkLV2Cs.js → persist-DHGuHP2H.js} +1 -1
- zenml/zen_server/dashboard/assets/{service-DNKY_ZYd.js → service-Do7yitqe.js} +1 -1
- zenml/zen_server/dashboard/assets/{sharedSchema-BOmQa793.js → sharedSchema-i_9Y4WcA.js} +1 -1
- zenml/zen_server/dashboard/assets/stack-detail-query-omCumL7U.js +1 -0
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-B4eE33z-.js +1 -0
- zenml/zen_server/dashboard/index.html +4 -4
- zenml/zen_server/deploy/daemon/daemon_zen_server.py +1 -1
- zenml/zen_server/deploy/deployment.py +1 -2
- zenml/zen_server/deploy/docker/docker_zen_server.py +1 -1
- zenml/zen_server/rbac/endpoint_utils.py +1 -2
- zenml/zen_server/routers/projects_endpoints.py +14 -3
- zenml/zen_server/utils.py +2 -86
- zenml/zen_stores/migrations/versions/0.80.0_release.py +23 -0
- zenml/zen_stores/schemas/artifact_visualization_schemas.py +1 -1
- zenml/zen_stores/schemas/model_schemas.py +1 -1
- zenml/zen_stores/schemas/service_schemas.py +1 -1
- zenml/zen_stores/schemas/step_run_schemas.py +1 -1
- zenml/zen_stores/schemas/trigger_schemas.py +1 -1
- zenml/zen_stores/sql_zen_store.py +5 -0
- {zenml_nightly-0.75.0.dev20250317.dist-info → zenml_nightly-0.80.0.dev20250321.dist-info}/METADATA +7 -8
- {zenml_nightly-0.75.0.dev20250317.dist-info → zenml_nightly-0.80.0.dev20250321.dist-info}/RECORD +226 -225
- zenml/zen_server/dashboard/assets/@reactflow-DMaYqp8l.js +0 -17
- zenml/zen_server/dashboard/assets/CodeSnippet-D8ptwPjg.js +0 -9
- zenml/zen_server/dashboard/assets/ComponentIcon-gpMJ2Y2e.js +0 -1
- zenml/zen_server/dashboard/assets/ExecutionStatus-DHiK3Am-.js +0 -1
- zenml/zen_server/dashboard/assets/ProBadge-ypma7R8i.js +0 -1
- zenml/zen_server/dashboard/assets/ProviderIcon-DKN3Gdcg.js +0 -1
- zenml/zen_server/dashboard/assets/RunSelector-CYmRHGdm.js +0 -1
- zenml/zen_server/dashboard/assets/SecretTooltip-CHPWF0bu.js +0 -1
- zenml/zen_server/dashboard/assets/Tick-DgU4udUn.js +0 -1
- zenml/zen_server/dashboard/assets/configuration-form-BEwWCxqY.js +0 -1
- zenml/zen_server/dashboard/assets/flavor-select-C1pyy8gq.js +0 -1
- zenml/zen_server/dashboard/assets/login-mutation-7WFxPe10.js +0 -1
- zenml/zen_server/dashboard/assets/page-BKN4SYXY.js +0 -1
- zenml/zen_server/dashboard/assets/page-BNrOW_3T.js +0 -2
- zenml/zen_server/dashboard/assets/page-BX6ZrAVH.js +0 -1
- zenml/zen_server/dashboard/assets/page-BnOdORy3.js +0 -1
- zenml/zen_server/dashboard/assets/page-BtkfcEI7.js +0 -1
- zenml/zen_server/dashboard/assets/page-Bz_grLBY.js +0 -1
- zenml/zen_server/dashboard/assets/page-CCEwuGU4.js +0 -1
- zenml/zen_server/dashboard/assets/page-COAGXWJu.js +0 -1
- zenml/zen_server/dashboard/assets/page-CaibMa0l.js +0 -1
- zenml/zen_server/dashboard/assets/page-CskoTYOC.js +0 -1
- zenml/zen_server/dashboard/assets/page-Cyoe7AtN.js +0 -1
- zenml/zen_server/dashboard/assets/page-D03wm5f1.js +0 -1
- zenml/zen_server/dashboard/assets/page-D8UimvyP.js +0 -1
- zenml/zen_server/dashboard/assets/page-DEnmFyzi.js +0 -1
- zenml/zen_server/dashboard/assets/page-TiOZeeo0.js +0 -1
- zenml/zen_server/dashboard/assets/page-cveasWUr.js +0 -6
- zenml/zen_server/dashboard/assets/page-iTvxfhgZ.js +0 -1
- zenml/zen_server/dashboard/assets/page-niRD8Hqz.js +0 -1
- zenml/zen_server/dashboard/assets/stack-detail-query-CI_YMUx6.js +0 -1
- zenml/zen_server/dashboard/assets/transform-DKsRLKTv.js +0 -1
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-CNYCc-FU.js +0 -1
- {zenml_nightly-0.75.0.dev20250317.dist-info → zenml_nightly-0.80.0.dev20250321.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250317.dist-info → zenml_nightly-0.80.0.dev20250321.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250317.dist-info → zenml_nightly-0.80.0.dev20250321.dist-info}/entry_points.txt +0 -0
@@ -28,11 +28,13 @@ from huggingface_hub.errors import HfHubHTTPError
|
|
28
28
|
from pydantic import Field
|
29
29
|
|
30
30
|
from zenml.client import Client
|
31
|
+
from zenml.enums import ServiceState
|
31
32
|
from zenml.integrations.huggingface.flavors.huggingface_model_deployer_flavor import (
|
32
33
|
HuggingFaceBaseConfig,
|
33
34
|
)
|
34
35
|
from zenml.logger import get_logger
|
35
|
-
from zenml.
|
36
|
+
from zenml.models.v2.misc.service import ServiceType
|
37
|
+
from zenml.services import ServiceStatus
|
36
38
|
from zenml.services.service import BaseDeploymentService, ServiceConfig
|
37
39
|
|
38
40
|
logger = get_logger(__name__)
|
@@ -578,6 +578,12 @@ class KubeflowOrchestrator(ContainerizedOrchestrator):
|
|
578
578
|
"Volume mounts are set but not supported in "
|
579
579
|
"Kubeflow with Kubeflow Pipelines 2.x. Ignoring..."
|
580
580
|
)
|
581
|
+
if pod_settings.env or pod_settings.env_from:
|
582
|
+
logger.warning(
|
583
|
+
"Environment variables are set but not supported "
|
584
|
+
"in Kubeflow with Kubeflow Pipelines 2.x. "
|
585
|
+
"Ignoring..."
|
586
|
+
)
|
581
587
|
|
582
588
|
# apply pod settings
|
583
589
|
if (
|
@@ -85,6 +85,9 @@ class KubernetesOrchestratorConfig(
|
|
85
85
|
parallel_step_startup_waiting_period: How long to wait in between
|
86
86
|
starting parallel steps. This can be used to distribute server
|
87
87
|
load when running pipelines with a huge amount of parallel steps.
|
88
|
+
pass_zenml_token_as_secret: If `True`, the ZenML token will be passed
|
89
|
+
as a Kubernetes secret to the pods. For this to work, the Kubernetes
|
90
|
+
client must have permissions to create secrets in the namespace.
|
88
91
|
"""
|
89
92
|
|
90
93
|
incluster: bool = False
|
@@ -93,6 +96,7 @@ class KubernetesOrchestratorConfig(
|
|
93
96
|
local: bool = False
|
94
97
|
skip_local_validations: bool = False
|
95
98
|
parallel_step_startup_waiting_period: Optional[float] = None
|
99
|
+
pass_zenml_token_as_secret: bool = False
|
96
100
|
|
97
101
|
@property
|
98
102
|
def is_remote(self) -> bool:
|
@@ -34,7 +34,7 @@ Adjusted from https://github.com/tensorflow/tfx/blob/master/tfx/utils/kube_utils
|
|
34
34
|
import enum
|
35
35
|
import re
|
36
36
|
import time
|
37
|
-
from typing import Any, Callable, Optional, TypeVar, cast
|
37
|
+
from typing import Any, Callable, Dict, Optional, TypeVar, cast
|
38
38
|
|
39
39
|
from kubernetes import client as k8s_client
|
40
40
|
from kubernetes import config as k8s_config
|
@@ -43,6 +43,7 @@ from kubernetes.client.rest import ApiException
|
|
43
43
|
from zenml.integrations.kubernetes.orchestrators.manifest_utils import (
|
44
44
|
build_namespace_manifest,
|
45
45
|
build_role_binding_manifest_for_service_account,
|
46
|
+
build_secret_manifest,
|
46
47
|
build_service_account_manifest,
|
47
48
|
)
|
48
49
|
from zenml.logger import get_logger
|
@@ -371,3 +372,90 @@ def create_namespace(core_api: k8s_client.CoreV1Api, namespace: str) -> None:
|
|
371
372
|
"""
|
372
373
|
manifest = build_namespace_manifest(namespace)
|
373
374
|
_if_not_exists(core_api.create_namespace)(body=manifest)
|
375
|
+
|
376
|
+
|
377
|
+
def create_secret(
|
378
|
+
core_api: k8s_client.CoreV1Api,
|
379
|
+
namespace: str,
|
380
|
+
secret_name: str,
|
381
|
+
data: Dict[str, Optional[str]],
|
382
|
+
) -> None:
|
383
|
+
"""Create a Kubernetes secret.
|
384
|
+
|
385
|
+
Args:
|
386
|
+
core_api: Client of Core V1 API of Kubernetes API.
|
387
|
+
namespace: The namespace in which to create the secret.
|
388
|
+
secret_name: The name of the secret to create.
|
389
|
+
data: The secret data.
|
390
|
+
"""
|
391
|
+
core_api.create_namespaced_secret(
|
392
|
+
namespace=namespace,
|
393
|
+
body=build_secret_manifest(name=secret_name, data=data),
|
394
|
+
)
|
395
|
+
|
396
|
+
|
397
|
+
def update_secret(
|
398
|
+
core_api: k8s_client.CoreV1Api,
|
399
|
+
namespace: str,
|
400
|
+
secret_name: str,
|
401
|
+
data: Dict[str, Optional[str]],
|
402
|
+
) -> None:
|
403
|
+
"""Update a Kubernetes secret.
|
404
|
+
|
405
|
+
Args:
|
406
|
+
core_api: Client of Core V1 API of Kubernetes API.
|
407
|
+
namespace: The namespace in which to update the secret.
|
408
|
+
secret_name: The name of the secret to update.
|
409
|
+
data: The secret data. If the value is None, the key will be removed
|
410
|
+
from the secret.
|
411
|
+
"""
|
412
|
+
core_api.patch_namespaced_secret(
|
413
|
+
namespace=namespace,
|
414
|
+
name=secret_name,
|
415
|
+
body=build_secret_manifest(name=secret_name, data=data),
|
416
|
+
)
|
417
|
+
|
418
|
+
|
419
|
+
def create_or_update_secret(
|
420
|
+
core_api: k8s_client.CoreV1Api,
|
421
|
+
namespace: str,
|
422
|
+
secret_name: str,
|
423
|
+
data: Dict[str, Optional[str]],
|
424
|
+
) -> None:
|
425
|
+
"""Create a Kubernetes secret if it doesn't exist, or update it if it does.
|
426
|
+
|
427
|
+
Args:
|
428
|
+
core_api: Client of Core V1 API of Kubernetes API.
|
429
|
+
namespace: The namespace in which to create or update the secret.
|
430
|
+
secret_name: The name of the secret to create or update.
|
431
|
+
data: The secret data. If the value is None, the key will be removed
|
432
|
+
from the secret.
|
433
|
+
|
434
|
+
Raises:
|
435
|
+
ApiException: If the secret creation failed for any reason other than
|
436
|
+
the secret already existing.
|
437
|
+
"""
|
438
|
+
try:
|
439
|
+
create_secret(core_api, namespace, secret_name, data)
|
440
|
+
except ApiException as e:
|
441
|
+
if e.status != 409:
|
442
|
+
raise
|
443
|
+
update_secret(core_api, namespace, secret_name, data)
|
444
|
+
|
445
|
+
|
446
|
+
def delete_secret(
|
447
|
+
core_api: k8s_client.CoreV1Api,
|
448
|
+
namespace: str,
|
449
|
+
secret_name: str,
|
450
|
+
) -> None:
|
451
|
+
"""Delete a Kubernetes secret.
|
452
|
+
|
453
|
+
Args:
|
454
|
+
core_api: Client of Core V1 API of Kubernetes API.
|
455
|
+
namespace: The namespace in which to delete the secret.
|
456
|
+
secret_name: The name of the secret to delete.
|
457
|
+
"""
|
458
|
+
core_api.delete_namespaced_secret(
|
459
|
+
name=secret_name,
|
460
|
+
namespace=namespace,
|
461
|
+
)
|
@@ -41,6 +41,7 @@ from typing import (
|
|
41
41
|
Type,
|
42
42
|
cast,
|
43
43
|
)
|
44
|
+
from uuid import UUID
|
44
45
|
|
45
46
|
from kubernetes import client as k8s_client
|
46
47
|
from kubernetes import config as k8s_config
|
@@ -72,6 +73,7 @@ if TYPE_CHECKING:
|
|
72
73
|
logger = get_logger(__name__)
|
73
74
|
|
74
75
|
ENV_ZENML_KUBERNETES_RUN_ID = "ZENML_KUBERNETES_RUN_ID"
|
76
|
+
KUBERNETES_SECRET_TOKEN_KEY_NAME = "zenml_api_token"
|
75
77
|
|
76
78
|
|
77
79
|
class KubernetesOrchestrator(ContainerizedOrchestrator):
|
@@ -368,6 +370,17 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
|
|
368
370
|
|
369
371
|
return pod_settings
|
370
372
|
|
373
|
+
def get_token_secret_name(self, deployment_id: UUID) -> str:
|
374
|
+
"""Returns the name of the secret that contains the ZenML token.
|
375
|
+
|
376
|
+
Args:
|
377
|
+
deployment_id: The ID of the deployment.
|
378
|
+
|
379
|
+
Returns:
|
380
|
+
The name of the secret that contains the ZenML token.
|
381
|
+
"""
|
382
|
+
return f"zenml-token-{deployment_id}"
|
383
|
+
|
371
384
|
def prepare_or_run_pipeline(
|
372
385
|
self,
|
373
386
|
deployment: "PipelineDeploymentResponse",
|
@@ -439,6 +452,38 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
|
|
439
452
|
# Authorize pod to run Kubernetes commands inside the cluster.
|
440
453
|
service_account_name = self._get_service_account_name(settings)
|
441
454
|
|
455
|
+
# We set some default minimum resource requests for the orchestrator pod
|
456
|
+
# here if the user has not specified any, because the orchestrator pod
|
457
|
+
# takes up some memory resources itself and, if not specified, the pod
|
458
|
+
# will be scheduled on any node regardless of available memory and risk
|
459
|
+
# negatively impacting or even crashing the node due to memory pressure.
|
460
|
+
orchestrator_pod_settings = self.apply_default_resource_requests(
|
461
|
+
memory="400Mi",
|
462
|
+
cpu="100m",
|
463
|
+
pod_settings=settings.orchestrator_pod_settings,
|
464
|
+
)
|
465
|
+
|
466
|
+
if self.config.pass_zenml_token_as_secret:
|
467
|
+
secret_name = self.get_token_secret_name(deployment.id)
|
468
|
+
token = environment.pop("ZENML_STORE_API_TOKEN")
|
469
|
+
kube_utils.create_or_update_secret(
|
470
|
+
core_api=self._k8s_core_api,
|
471
|
+
namespace=self.config.kubernetes_namespace,
|
472
|
+
secret_name=secret_name,
|
473
|
+
data={KUBERNETES_SECRET_TOKEN_KEY_NAME: token},
|
474
|
+
)
|
475
|
+
orchestrator_pod_settings.env.append(
|
476
|
+
{
|
477
|
+
"name": "ZENML_STORE_API_TOKEN",
|
478
|
+
"valueFrom": {
|
479
|
+
"secretKeyRef": {
|
480
|
+
"name": secret_name,
|
481
|
+
"key": KUBERNETES_SECRET_TOKEN_KEY_NAME,
|
482
|
+
}
|
483
|
+
},
|
484
|
+
}
|
485
|
+
)
|
486
|
+
|
442
487
|
# Schedule as CRON job if CRON schedule is given.
|
443
488
|
if deployment.schedule:
|
444
489
|
if not deployment.schedule.cron_expression:
|
@@ -458,7 +503,7 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
|
|
458
503
|
args=args,
|
459
504
|
service_account_name=service_account_name,
|
460
505
|
privileged=False,
|
461
|
-
pod_settings=
|
506
|
+
pod_settings=orchestrator_pod_settings,
|
462
507
|
env=environment,
|
463
508
|
mount_local_stores=self.config.is_local,
|
464
509
|
)
|
@@ -472,57 +517,46 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
|
|
472
517
|
f'`"{cron_expression}"`.'
|
473
518
|
)
|
474
519
|
return
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
# will be scheduled on any node regardless of available memory and risk
|
480
|
-
# negatively impacting or even crashing the node due to memory pressure.
|
481
|
-
orchestrator_pod_settings = self.apply_default_resource_requests(
|
482
|
-
memory="400Mi",
|
483
|
-
cpu="100m",
|
484
|
-
pod_settings=settings.orchestrator_pod_settings,
|
485
|
-
)
|
486
|
-
|
487
|
-
# Create and run the orchestrator pod.
|
488
|
-
pod_manifest = build_pod_manifest(
|
489
|
-
run_name=orchestrator_run_name,
|
490
|
-
pod_name=pod_name,
|
491
|
-
pipeline_name=pipeline_name,
|
492
|
-
image_name=image,
|
493
|
-
command=command,
|
494
|
-
args=args,
|
495
|
-
privileged=False,
|
496
|
-
pod_settings=orchestrator_pod_settings,
|
497
|
-
service_account_name=service_account_name,
|
498
|
-
env=environment,
|
499
|
-
mount_local_stores=self.config.is_local,
|
500
|
-
)
|
501
|
-
|
502
|
-
self._k8s_core_api.create_namespaced_pod(
|
503
|
-
namespace=self.config.kubernetes_namespace,
|
504
|
-
body=pod_manifest,
|
505
|
-
)
|
506
|
-
|
507
|
-
# Wait for the orchestrator pod to finish and stream logs.
|
508
|
-
if settings.synchronous:
|
509
|
-
logger.info("Waiting for Kubernetes orchestrator pod...")
|
510
|
-
kube_utils.wait_pod(
|
511
|
-
kube_client_fn=self.get_kube_client,
|
520
|
+
else:
|
521
|
+
# Create and run the orchestrator pod.
|
522
|
+
pod_manifest = build_pod_manifest(
|
523
|
+
run_name=orchestrator_run_name,
|
512
524
|
pod_name=pod_name,
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
525
|
+
pipeline_name=pipeline_name,
|
526
|
+
image_name=image,
|
527
|
+
command=command,
|
528
|
+
args=args,
|
529
|
+
privileged=False,
|
530
|
+
pod_settings=orchestrator_pod_settings,
|
531
|
+
service_account_name=service_account_name,
|
532
|
+
env=environment,
|
533
|
+
mount_local_stores=self.config.is_local,
|
517
534
|
)
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
f"Run the following command to inspect the logs: "
|
523
|
-
f"`kubectl logs {pod_name} -n {self.config.kubernetes_namespace}`."
|
535
|
+
|
536
|
+
self._k8s_core_api.create_namespaced_pod(
|
537
|
+
namespace=self.config.kubernetes_namespace,
|
538
|
+
body=pod_manifest,
|
524
539
|
)
|
525
540
|
|
541
|
+
# Wait for the orchestrator pod to finish and stream logs.
|
542
|
+
if settings.synchronous:
|
543
|
+
logger.info("Waiting for Kubernetes orchestrator pod...")
|
544
|
+
kube_utils.wait_pod(
|
545
|
+
kube_client_fn=self.get_kube_client,
|
546
|
+
pod_name=pod_name,
|
547
|
+
namespace=self.config.kubernetes_namespace,
|
548
|
+
exit_condition_lambda=kube_utils.pod_is_done,
|
549
|
+
timeout_sec=settings.timeout,
|
550
|
+
stream_logs=True,
|
551
|
+
)
|
552
|
+
else:
|
553
|
+
logger.info(
|
554
|
+
f"Orchestration started asynchronously in pod "
|
555
|
+
f"`{self.config.kubernetes_namespace}:{pod_name}`. "
|
556
|
+
f"Run the following command to inspect the logs: "
|
557
|
+
f"`kubectl logs {pod_name} -n {self.config.kubernetes_namespace}`."
|
558
|
+
)
|
559
|
+
|
526
560
|
def _get_service_account_name(
|
527
561
|
self, settings: KubernetesOrchestratorSettings
|
528
562
|
) -> str:
|
@@ -28,6 +28,7 @@ from zenml.integrations.kubernetes.flavors.kubernetes_orchestrator_flavor import
|
|
28
28
|
from zenml.integrations.kubernetes.orchestrators import kube_utils
|
29
29
|
from zenml.integrations.kubernetes.orchestrators.kubernetes_orchestrator import (
|
30
30
|
ENV_ZENML_KUBERNETES_RUN_ID,
|
31
|
+
KUBERNETES_SECRET_TOKEN_KEY_NAME,
|
31
32
|
KubernetesOrchestrator,
|
32
33
|
)
|
33
34
|
from zenml.integrations.kubernetes.orchestrators.manifest_utils import (
|
@@ -82,6 +83,9 @@ def main() -> None:
|
|
82
83
|
kube_client = orchestrator.get_kube_client(incluster=True)
|
83
84
|
core_api = k8s_client.CoreV1Api(kube_client)
|
84
85
|
|
86
|
+
env = get_config_environment_vars()
|
87
|
+
env[ENV_ZENML_KUBERNETES_RUN_ID] = orchestrator_run_id
|
88
|
+
|
85
89
|
def run_step_on_kubernetes(step_name: str) -> None:
|
86
90
|
"""Run a pipeline step in a separate Kubernetes pod.
|
87
91
|
|
@@ -115,9 +119,6 @@ def main() -> None:
|
|
115
119
|
orchestrator_settings
|
116
120
|
)
|
117
121
|
|
118
|
-
env = get_config_environment_vars()
|
119
|
-
env[ENV_ZENML_KUBERNETES_RUN_ID] = orchestrator_run_id
|
120
|
-
|
121
122
|
# We set some default minimum memory resource requests for the step pod
|
122
123
|
# here if the user has not specified any, because the step pod takes up
|
123
124
|
# some memory resources itself and, if not specified, the pod will be
|
@@ -128,6 +129,23 @@ def main() -> None:
|
|
128
129
|
pod_settings=settings.pod_settings,
|
129
130
|
)
|
130
131
|
|
132
|
+
if orchestrator.config.pass_zenml_token_as_secret:
|
133
|
+
env.pop("ZENML_STORE_API_TOKEN", None)
|
134
|
+
secret_name = orchestrator.get_token_secret_name(
|
135
|
+
deployment_config.id
|
136
|
+
)
|
137
|
+
pod_settings.env.append(
|
138
|
+
{
|
139
|
+
"name": "ZENML_STORE_API_TOKEN",
|
140
|
+
"valueFrom": {
|
141
|
+
"secretKeyRef": {
|
142
|
+
"name": secret_name,
|
143
|
+
"key": KUBERNETES_SECRET_TOKEN_KEY_NAME,
|
144
|
+
}
|
145
|
+
},
|
146
|
+
}
|
147
|
+
)
|
148
|
+
|
131
149
|
# Define Kubernetes pod manifest.
|
132
150
|
pod_manifest = build_pod_manifest(
|
133
151
|
pod_name=pod_name,
|
@@ -166,13 +184,29 @@ def main() -> None:
|
|
166
184
|
parallel_node_startup_waiting_period = (
|
167
185
|
orchestrator.config.parallel_step_startup_waiting_period or 0.0
|
168
186
|
)
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
187
|
+
try:
|
188
|
+
ThreadedDagRunner(
|
189
|
+
dag=pipeline_dag,
|
190
|
+
run_fn=run_step_on_kubernetes,
|
191
|
+
parallel_node_startup_waiting_period=parallel_node_startup_waiting_period,
|
192
|
+
).run()
|
193
|
+
logger.info("Orchestration pod completed.")
|
194
|
+
finally:
|
195
|
+
if (
|
196
|
+
orchestrator.config.pass_zenml_token_as_secret
|
197
|
+
and deployment_config.schedule is None
|
198
|
+
):
|
199
|
+
secret_name = orchestrator.get_token_secret_name(
|
200
|
+
deployment_config.id
|
201
|
+
)
|
202
|
+
try:
|
203
|
+
kube_utils.delete_secret(
|
204
|
+
core_api=core_api,
|
205
|
+
namespace=args.kubernetes_namespace,
|
206
|
+
secret_name=secret_name,
|
207
|
+
)
|
208
|
+
except k8s_client.rest.ApiException as e:
|
209
|
+
logger.error(f"Error cleaning up secret {secret_name}: {e}")
|
176
210
|
|
177
211
|
|
178
212
|
if __name__ == "__main__":
|
@@ -13,9 +13,10 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Utility functions for building manifests for k8s pods."""
|
15
15
|
|
16
|
+
import base64
|
16
17
|
import os
|
17
18
|
import sys
|
18
|
-
from typing import Any, Dict, List, Optional
|
19
|
+
from typing import Any, Dict, List, Mapping, Optional
|
19
20
|
|
20
21
|
from kubernetes import client as k8s_client
|
21
22
|
|
@@ -222,6 +223,18 @@ def add_pod_settings(
|
|
222
223
|
else:
|
223
224
|
container.volume_mounts = settings.volume_mounts
|
224
225
|
|
226
|
+
if settings.env:
|
227
|
+
if container.env:
|
228
|
+
container.env.extend(settings.env)
|
229
|
+
else:
|
230
|
+
container.env = settings.env
|
231
|
+
|
232
|
+
if settings.env_from:
|
233
|
+
if container.env_from:
|
234
|
+
container.env_from.extend(settings.env_from)
|
235
|
+
else:
|
236
|
+
container.env_from = settings.env_from
|
237
|
+
|
225
238
|
if settings.volumes:
|
226
239
|
if pod_spec.volumes:
|
227
240
|
pod_spec.volumes.extend(settings.volumes)
|
@@ -378,3 +391,34 @@ def build_namespace_manifest(namespace: str) -> Dict[str, Any]:
|
|
378
391
|
"name": namespace,
|
379
392
|
},
|
380
393
|
}
|
394
|
+
|
395
|
+
|
396
|
+
def build_secret_manifest(
|
397
|
+
name: str,
|
398
|
+
data: Mapping[str, Optional[str]],
|
399
|
+
secret_type: str = "Opaque",
|
400
|
+
) -> Dict[str, Any]:
|
401
|
+
"""Builds a Kubernetes secret manifest.
|
402
|
+
|
403
|
+
Args:
|
404
|
+
name: Name of the secret.
|
405
|
+
data: The secret data.
|
406
|
+
secret_type: The secret type.
|
407
|
+
|
408
|
+
Returns:
|
409
|
+
The secret manifest.
|
410
|
+
"""
|
411
|
+
encoded_data = {
|
412
|
+
key: base64.b64encode(value.encode()).decode() if value else None
|
413
|
+
for key, value in data.items()
|
414
|
+
}
|
415
|
+
|
416
|
+
return {
|
417
|
+
"apiVersion": "v1",
|
418
|
+
"kind": "Secret",
|
419
|
+
"metadata": {
|
420
|
+
"name": name,
|
421
|
+
},
|
422
|
+
"type": secret_type,
|
423
|
+
"data": encoded_data,
|
424
|
+
}
|
@@ -35,6 +35,8 @@ class KubernetesPodSettings(BaseSettings):
|
|
35
35
|
host_ipc: Whether to enable host IPC for the pod.
|
36
36
|
image_pull_secrets: Image pull secrets to use for the pod.
|
37
37
|
labels: Labels to apply to the pod.
|
38
|
+
env: Environment variables to apply to the container.
|
39
|
+
env_from: Environment variables to apply to the container.
|
38
40
|
"""
|
39
41
|
|
40
42
|
node_selectors: Dict[str, str] = {}
|
@@ -47,6 +49,8 @@ class KubernetesPodSettings(BaseSettings):
|
|
47
49
|
host_ipc: bool = False
|
48
50
|
image_pull_secrets: List[str] = []
|
49
51
|
labels: Dict[str, str] = {}
|
52
|
+
env: List[Dict[str, Any]] = []
|
53
|
+
env_from: List[Dict[str, Any]] = []
|
50
54
|
|
51
55
|
@field_validator("volumes", mode="before")
|
52
56
|
@classmethod
|
@@ -155,3 +159,51 @@ class KubernetesPodSettings(BaseSettings):
|
|
155
159
|
return serialization_utils.serialize_kubernetes_model(value)
|
156
160
|
else:
|
157
161
|
return value
|
162
|
+
|
163
|
+
@field_validator("env", mode="before")
|
164
|
+
@classmethod
|
165
|
+
def _convert_env(cls, value: Any) -> Any:
|
166
|
+
"""Converts Kubernetes EnvVar to a dict.
|
167
|
+
|
168
|
+
Args:
|
169
|
+
value: The env value.
|
170
|
+
|
171
|
+
Returns:
|
172
|
+
The converted value.
|
173
|
+
"""
|
174
|
+
from kubernetes.client.models import V1EnvVar
|
175
|
+
|
176
|
+
result = []
|
177
|
+
for element in value:
|
178
|
+
if isinstance(element, V1EnvVar):
|
179
|
+
result.append(
|
180
|
+
serialization_utils.serialize_kubernetes_model(element)
|
181
|
+
)
|
182
|
+
else:
|
183
|
+
result.append(element)
|
184
|
+
|
185
|
+
return result
|
186
|
+
|
187
|
+
@field_validator("env_from", mode="before")
|
188
|
+
@classmethod
|
189
|
+
def _convert_env_from(cls, value: Any) -> Any:
|
190
|
+
"""Converts Kubernetes EnvFromSource to a dict.
|
191
|
+
|
192
|
+
Args:
|
193
|
+
value: The env from value.
|
194
|
+
|
195
|
+
Returns:
|
196
|
+
The converted value.
|
197
|
+
"""
|
198
|
+
from kubernetes.client.models import V1EnvFromSource
|
199
|
+
|
200
|
+
result = []
|
201
|
+
for element in value:
|
202
|
+
if isinstance(element, V1EnvFromSource):
|
203
|
+
result.append(
|
204
|
+
serialization_utils.serialize_kubernetes_model(element)
|
205
|
+
)
|
206
|
+
else:
|
207
|
+
result.append(element)
|
208
|
+
|
209
|
+
return result
|
@@ -58,7 +58,7 @@ class MlflowIntegration(Integration):
|
|
58
58
|
from zenml.integrations.pandas import PandasIntegration
|
59
59
|
|
60
60
|
reqs = [
|
61
|
-
"mlflow>=2.1.1,<
|
61
|
+
"mlflow>=2.1.1,<2.21.0",
|
62
62
|
# TODO: remove this requirement once rapidjson is fixed
|
63
63
|
"python-rapidjson<1.15",
|
64
64
|
# When you do:
|
@@ -111,5 +111,3 @@ class MlflowIntegration(Integration):
|
|
111
111
|
MLFlowModelRegistryFlavor,
|
112
112
|
]
|
113
113
|
|
114
|
-
|
115
|
-
MlflowIntegration.check_installation()
|
@@ -30,6 +30,7 @@ from zenml.integrations.mlflow.experiment_trackers.mlflow_experiment_tracker imp
|
|
30
30
|
MLFlowExperimentTracker,
|
31
31
|
)
|
32
32
|
from zenml.logger import get_logger
|
33
|
+
from zenml.models.v2.misc.service import ServiceType
|
33
34
|
from zenml.services import (
|
34
35
|
HTTPEndpointHealthMonitor,
|
35
36
|
HTTPEndpointHealthMonitorConfig,
|
@@ -38,7 +39,6 @@ from zenml.services import (
|
|
38
39
|
LocalDaemonServiceEndpoint,
|
39
40
|
LocalDaemonServiceEndpointConfig,
|
40
41
|
ServiceEndpointProtocol,
|
41
|
-
ServiceType,
|
42
42
|
)
|
43
43
|
from zenml.services.service import BaseDeploymentService
|
44
44
|
|