zenml-nightly 0.75.0.dev20250318__py3-none-any.whl → 0.80.0.dev20250322__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/project.py +1 -1
- zenml/cli/server.py +6 -4
- zenml/cli/service_accounts.py +2 -2
- zenml/cli/service_connectors.py +1 -1
- zenml/cli/stack.py +1 -1
- zenml/cli/stack_components.py +1 -1
- zenml/cli/user_management.py +1 -1
- 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/__init__.py +0 -64
- 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/github/__init__.py +0 -2
- zenml/integrations/github/code_repositories/github_code_repository.py +7 -2
- 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/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 +124 -83
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +44 -10
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +33 -1
- 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/registry.py +34 -0
- 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/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/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/stack_deployments/aws_stack_deployment.py +10 -5
- zenml/stack_deployments/azure_stack_deployment.py +47 -41
- zenml/stack_deployments/constants.py +30 -0
- zenml/stack_deployments/gcp_stack_deployment.py +6 -0
- 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/routers/stack_deployment_endpoints.py +12 -4
- zenml/zen_server/utils.py +2 -86
- zenml/zen_stores/migrations/versions/0.80.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +2 -2
- zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +2 -2
- zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +2 -2
- 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.dev20250318.dist-info → zenml_nightly-0.80.0.dev20250322.dist-info}/METADATA +3 -3
- {zenml_nightly-0.75.0.dev20250318.dist-info → zenml_nightly-0.80.0.dev20250322.dist-info}/RECORD +237 -235
- 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.dev20250318.dist-info → zenml_nightly-0.80.0.dev20250322.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250318.dist-info → zenml_nightly-0.80.0.dev20250322.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250318.dist-info → zenml_nightly-0.80.0.dev20250322.dist-info}/entry_points.txt +0 -0
zenml/models/__init__.py
CHANGED
@@ -29,6 +29,7 @@ from zenml.models.v2.base.base import (
|
|
29
29
|
)
|
30
30
|
from zenml.models.v2.base.scoped import (
|
31
31
|
TaggableFilter,
|
32
|
+
RunMetadataFilterMixin,
|
32
33
|
UserScopedRequest,
|
33
34
|
UserScopedFilter,
|
34
35
|
UserScopedResponse,
|
@@ -389,6 +390,7 @@ from zenml.models.v2.misc.server_models import (
|
|
389
390
|
ServerDatabaseType,
|
390
391
|
ServerDeploymentType,
|
391
392
|
)
|
393
|
+
from zenml.models.v2.misc.service import ServiceType
|
392
394
|
from zenml.models.v2.core.server_settings import (
|
393
395
|
ServerActivationRequest,
|
394
396
|
ServerSettingsResponse,
|
@@ -516,6 +518,7 @@ __all__ = [
|
|
516
518
|
"NumericFilter",
|
517
519
|
"UUIDFilter",
|
518
520
|
"TaggableFilter",
|
521
|
+
"RunMetadataFilterMixin",
|
519
522
|
"Page",
|
520
523
|
# V2 Core
|
521
524
|
"ActionFilter",
|
@@ -760,6 +763,7 @@ __all__ = [
|
|
760
763
|
"ServerDatabaseType",
|
761
764
|
"ServerDeploymentType",
|
762
765
|
"ServerStatistics",
|
766
|
+
"ServiceType",
|
763
767
|
"StackDeploymentConfig",
|
764
768
|
"StackDeploymentInfo",
|
765
769
|
"OAuthDeviceAuthorizationRequest",
|
zenml/models/v2/base/filter.py
CHANGED
@@ -37,7 +37,7 @@ from pydantic import (
|
|
37
37
|
field_validator,
|
38
38
|
model_validator,
|
39
39
|
)
|
40
|
-
from sqlalchemy import Float, and_, asc, cast, desc
|
40
|
+
from sqlalchemy import Float, and_, asc, cast, desc, or_
|
41
41
|
from sqlmodel import SQLModel
|
42
42
|
|
43
43
|
from zenml.constants import (
|
@@ -171,8 +171,6 @@ class BoolFilter(Filter):
|
|
171
171
|
class StrFilter(Filter):
|
172
172
|
"""Filter for all string fields."""
|
173
173
|
|
174
|
-
json_encode_value: bool = False
|
175
|
-
|
176
174
|
ALLOWED_OPS: ClassVar[List[str]] = [
|
177
175
|
GenericFilterOps.EQUALS,
|
178
176
|
GenericFilterOps.NOT_EQUALS,
|
@@ -201,6 +199,23 @@ class StrFilter(Filter):
|
|
201
199
|
raise ValueError(ONEOF_ERROR)
|
202
200
|
return self
|
203
201
|
|
202
|
+
def _check_if_column_is_json_encoded(self, column: Any) -> bool:
|
203
|
+
"""Check if the column is json encoded.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
column: The column of an SQLModel table on which to filter.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
True if the column is json encoded, False otherwise.
|
210
|
+
"""
|
211
|
+
from zenml.zen_stores.schemas import RunMetadataSchema
|
212
|
+
|
213
|
+
JSON_ENCODED_COLUMNS = [RunMetadataSchema.value]
|
214
|
+
|
215
|
+
if column in JSON_ENCODED_COLUMNS:
|
216
|
+
return True
|
217
|
+
return False
|
218
|
+
|
204
219
|
def generate_query_conditions_from_column(self, column: Any) -> Any:
|
205
220
|
"""Generate query conditions for a string column.
|
206
221
|
|
@@ -209,70 +224,168 @@ class StrFilter(Filter):
|
|
209
224
|
|
210
225
|
Returns:
|
211
226
|
A list of query conditions.
|
212
|
-
|
213
|
-
Raises:
|
214
|
-
ValueError: the comparison of the column to a numeric value fails.
|
215
227
|
"""
|
228
|
+
# Handle numeric comparisons (GT, LT, GTE, LTE)
|
216
229
|
if self.operation in {
|
217
230
|
GenericFilterOps.GT,
|
218
231
|
GenericFilterOps.LT,
|
219
232
|
GenericFilterOps.GTE,
|
220
233
|
GenericFilterOps.LTE,
|
221
234
|
}:
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
if self.operation == GenericFilterOps.GT:
|
228
|
-
return and_(
|
229
|
-
numeric_column, numeric_column > float(self.value)
|
230
|
-
)
|
231
|
-
if self.operation == GenericFilterOps.LT:
|
232
|
-
return and_(
|
233
|
-
numeric_column, numeric_column < float(self.value)
|
234
|
-
)
|
235
|
-
if self.operation == GenericFilterOps.GTE:
|
236
|
-
return and_(
|
237
|
-
numeric_column, numeric_column >= float(self.value)
|
238
|
-
)
|
239
|
-
if self.operation == GenericFilterOps.LTE:
|
240
|
-
return and_(
|
241
|
-
numeric_column, numeric_column <= float(self.value)
|
242
|
-
)
|
243
|
-
except Exception as e:
|
244
|
-
raise ValueError(
|
245
|
-
f"Failed to compare the column '{column}' to the "
|
246
|
-
f"value '{self.value}' (must be numeric): {e}"
|
247
|
-
)
|
235
|
+
return self._handle_numeric_comparison(column)
|
236
|
+
|
237
|
+
# Handle operations that need special treatment for JSON-encoded columns
|
238
|
+
is_json_encoded = self._check_if_column_is_json_encoded(column)
|
248
239
|
|
240
|
+
# Handle list operations
|
249
241
|
if self.operation == GenericFilterOps.ONEOF:
|
250
242
|
assert isinstance(self.value, list)
|
251
|
-
|
252
|
-
json_list = (
|
253
|
-
[json.dumps(v) for v in self.value]
|
254
|
-
if self.json_encode_value
|
255
|
-
else self.value
|
256
|
-
)
|
257
|
-
return column.in_(json_list)
|
243
|
+
return self._handle_oneof(column, is_json_encoded)
|
258
244
|
|
259
|
-
#
|
260
|
-
# because the quotes around strings will mess with the comparison
|
245
|
+
# Handle pattern matching operations
|
261
246
|
if self.operation == GenericFilterOps.CONTAINS:
|
262
247
|
return column.like(f"%{self.value}%")
|
263
248
|
|
264
|
-
json_value = (
|
265
|
-
json.dumps(self.value) if self.json_encode_value else self.value
|
266
|
-
)
|
267
|
-
|
268
249
|
if self.operation == GenericFilterOps.STARTSWITH:
|
269
|
-
return
|
250
|
+
return self._handle_startswith(column, is_json_encoded)
|
251
|
+
|
270
252
|
if self.operation == GenericFilterOps.ENDSWITH:
|
271
|
-
return
|
253
|
+
return self._handle_endswith(column, is_json_encoded)
|
254
|
+
|
272
255
|
if self.operation == GenericFilterOps.NOT_EQUALS:
|
273
|
-
return column
|
256
|
+
return self._handle_not_equals(column, is_json_encoded)
|
274
257
|
|
275
|
-
|
258
|
+
# Default case (EQUALS)
|
259
|
+
return self._handle_equals(column, is_json_encoded)
|
260
|
+
|
261
|
+
def _handle_numeric_comparison(self, column: Any) -> Any:
|
262
|
+
"""Handle numeric comparison operations.
|
263
|
+
|
264
|
+
Args:
|
265
|
+
column: The column to compare.
|
266
|
+
|
267
|
+
Returns:
|
268
|
+
The query condition.
|
269
|
+
|
270
|
+
Raises:
|
271
|
+
ValueError: If the comparison fails.
|
272
|
+
"""
|
273
|
+
try:
|
274
|
+
numeric_column = cast(column, Float)
|
275
|
+
assert self.value is not None
|
276
|
+
|
277
|
+
operations = {
|
278
|
+
GenericFilterOps.GT: lambda col, val: and_(
|
279
|
+
col, col > float(val)
|
280
|
+
),
|
281
|
+
GenericFilterOps.LT: lambda col, val: and_(
|
282
|
+
col, col < float(val)
|
283
|
+
),
|
284
|
+
GenericFilterOps.GTE: lambda col, val: and_(
|
285
|
+
col, col >= float(val)
|
286
|
+
),
|
287
|
+
GenericFilterOps.LTE: lambda col, val: and_(
|
288
|
+
col, col <= float(val)
|
289
|
+
),
|
290
|
+
}
|
291
|
+
|
292
|
+
return operations[self.operation](numeric_column, self.value) # type: ignore[no-untyped-call]
|
293
|
+
except Exception as e:
|
294
|
+
raise ValueError(
|
295
|
+
f"Failed to compare the column '{column}' to the "
|
296
|
+
f"value '{self.value}' (must be numeric): {e}"
|
297
|
+
)
|
298
|
+
|
299
|
+
def _handle_oneof(self, column: Any, is_json_encoded: bool) -> Any:
|
300
|
+
"""Handle the ONEOF operation.
|
301
|
+
|
302
|
+
Args:
|
303
|
+
column: The column to check.
|
304
|
+
is_json_encoded: Whether the column is JSON encoded.
|
305
|
+
|
306
|
+
Returns:
|
307
|
+
The query condition.
|
308
|
+
"""
|
309
|
+
from sqlalchemy import or_
|
310
|
+
|
311
|
+
conditions = []
|
312
|
+
|
313
|
+
assert isinstance(self.value, list)
|
314
|
+
|
315
|
+
for value in self.value:
|
316
|
+
if is_json_encoded:
|
317
|
+
# For JSON encoded columns, add conditions for both raw and JSON-quoted values
|
318
|
+
conditions.append(column == value)
|
319
|
+
conditions.append(column == f'"{value}"')
|
320
|
+
else:
|
321
|
+
conditions.append(column == value)
|
322
|
+
|
323
|
+
return or_(*conditions)
|
324
|
+
|
325
|
+
def _handle_startswith(self, column: Any, is_json_encoded: bool) -> Any:
|
326
|
+
"""Handle the STARTSWITH operation.
|
327
|
+
|
328
|
+
Args:
|
329
|
+
column: The column to check.
|
330
|
+
is_json_encoded: Whether the column is JSON encoded.
|
331
|
+
|
332
|
+
Returns:
|
333
|
+
The query condition.
|
334
|
+
"""
|
335
|
+
if is_json_encoded:
|
336
|
+
return or_(
|
337
|
+
column.startswith(self.value),
|
338
|
+
column.startswith(f'"{self.value}'),
|
339
|
+
)
|
340
|
+
else:
|
341
|
+
return column.startswith(self.value)
|
342
|
+
|
343
|
+
def _handle_endswith(self, column: Any, is_json_encoded: bool) -> Any:
|
344
|
+
"""Handle the ENDSWITH operation.
|
345
|
+
|
346
|
+
Args:
|
347
|
+
column: The column to check.
|
348
|
+
is_json_encoded: Whether the column is JSON encoded.
|
349
|
+
|
350
|
+
Returns:
|
351
|
+
The query condition.
|
352
|
+
"""
|
353
|
+
if is_json_encoded:
|
354
|
+
return or_(
|
355
|
+
column.endswith(self.value), column.endswith(f'{self.value}"')
|
356
|
+
)
|
357
|
+
else:
|
358
|
+
return column.endswith(self.value)
|
359
|
+
|
360
|
+
def _handle_not_equals(self, column: Any, is_json_encoded: bool) -> Any:
|
361
|
+
"""Handle the NOT_EQUALS operation.
|
362
|
+
|
363
|
+
Args:
|
364
|
+
column: The column to check.
|
365
|
+
is_json_encoded: Whether the column is JSON encoded.
|
366
|
+
|
367
|
+
Returns:
|
368
|
+
The query condition.
|
369
|
+
"""
|
370
|
+
if is_json_encoded:
|
371
|
+
return and_(column != self.value, column != f'"{self.value}"')
|
372
|
+
else:
|
373
|
+
return column != self.value
|
374
|
+
|
375
|
+
def _handle_equals(self, column: Any, is_json_encoded: bool) -> Any:
|
376
|
+
"""Handle the EQUALS operation (default).
|
377
|
+
|
378
|
+
Args:
|
379
|
+
column: The column to check.
|
380
|
+
is_json_encoded: Whether the column is JSON encoded.
|
381
|
+
|
382
|
+
Returns:
|
383
|
+
The query condition.
|
384
|
+
"""
|
385
|
+
if is_json_encoded:
|
386
|
+
return or_(column == self.value, column == f'"{self.value}"')
|
387
|
+
else:
|
388
|
+
return column == self.value
|
276
389
|
|
277
390
|
|
278
391
|
class UUIDFilter(StrFilter):
|
@@ -751,7 +864,6 @@ class BaseFilter(BaseModel):
|
|
751
864
|
value: Any,
|
752
865
|
table: Type[SQLModel],
|
753
866
|
column: str,
|
754
|
-
json_encode_value: bool = False,
|
755
867
|
) -> "ColumnElement[bool]":
|
756
868
|
"""Generate custom filter conditions for a column of a table.
|
757
869
|
|
@@ -759,7 +871,6 @@ class BaseFilter(BaseModel):
|
|
759
871
|
value: The filter value.
|
760
872
|
table: The table which contains the column.
|
761
873
|
column: The column name.
|
762
|
-
json_encode_value: Whether to json encode the value.
|
763
874
|
|
764
875
|
Returns:
|
765
876
|
The query conditions.
|
@@ -768,9 +879,6 @@ class BaseFilter(BaseModel):
|
|
768
879
|
filter_ = FilterGenerator(table).define_filter(
|
769
880
|
column=column, value=value, operator=operator
|
770
881
|
)
|
771
|
-
if isinstance(filter_, StrFilter):
|
772
|
-
filter_.json_encode_value = json_encode_value
|
773
|
-
|
774
882
|
return filter_.generate_query_conditions(table=table)
|
775
883
|
|
776
884
|
@property
|
zenml/models/v2/base/scoped.py
CHANGED
@@ -426,6 +426,10 @@ class TaggableFilter(BaseFilter):
|
|
426
426
|
*BaseFilter.CUSTOM_SORTING_OPTIONS,
|
427
427
|
"tags",
|
428
428
|
]
|
429
|
+
API_MULTI_INPUT_PARAMS: ClassVar[List[str]] = [
|
430
|
+
*BaseFilter.API_MULTI_INPUT_PARAMS,
|
431
|
+
"tags",
|
432
|
+
]
|
429
433
|
|
430
434
|
@model_validator(mode="after")
|
431
435
|
def add_tag_to_tags(self) -> "TaggableFilter":
|
@@ -583,3 +587,131 @@ class TaggableFilter(BaseFilter):
|
|
583
587
|
return query
|
584
588
|
|
585
589
|
return super().apply_sorting(query=query, table=table)
|
590
|
+
|
591
|
+
|
592
|
+
class RunMetadataFilterMixin(BaseFilter):
|
593
|
+
"""Model to enable filtering and sorting by run metadata."""
|
594
|
+
|
595
|
+
run_metadata: Optional[List[str]] = Field(
|
596
|
+
default=None,
|
597
|
+
description="The run_metadata to filter the pipeline runs by.",
|
598
|
+
)
|
599
|
+
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
600
|
+
*BaseFilter.FILTER_EXCLUDE_FIELDS,
|
601
|
+
"run_metadata",
|
602
|
+
]
|
603
|
+
API_MULTI_INPUT_PARAMS: ClassVar[List[str]] = [
|
604
|
+
*BaseFilter.API_MULTI_INPUT_PARAMS,
|
605
|
+
"run_metadata",
|
606
|
+
]
|
607
|
+
|
608
|
+
@model_validator(mode="after")
|
609
|
+
def validate_run_metadata_format(self) -> "RunMetadataFilterMixin":
|
610
|
+
"""Validates that run_metadata entries are in the correct format.
|
611
|
+
|
612
|
+
Each run_metadata entry must be in one of the following formats:
|
613
|
+
1. "key:value" - Direct equality comparison (key equals value)
|
614
|
+
2. "key:filterop:value" - Where filterop is one of the GenericFilterOps:
|
615
|
+
- equals: Exact match
|
616
|
+
- notequals: Not equal to
|
617
|
+
- contains: String contains value
|
618
|
+
- startswith: String starts with value
|
619
|
+
- endswith: String ends with value
|
620
|
+
- oneof: Value is one of the specified options
|
621
|
+
- gte: Greater than or equal to
|
622
|
+
- gt: Greater than
|
623
|
+
- lte: Less than or equal to
|
624
|
+
- lt: Less than
|
625
|
+
- in: Value is in a list
|
626
|
+
|
627
|
+
Examples:
|
628
|
+
- "status:completed" - Find entries where status equals "completed"
|
629
|
+
- "name:contains:test" - Find entries where name contains "test"
|
630
|
+
- "duration:gt:10" - Find entries where duration is greater than 10
|
631
|
+
|
632
|
+
Returns:
|
633
|
+
self
|
634
|
+
|
635
|
+
Raises:
|
636
|
+
ValueError: If any entry in run_metadata does not contain a colon.
|
637
|
+
"""
|
638
|
+
if self.run_metadata:
|
639
|
+
for entry in self.run_metadata:
|
640
|
+
if ":" not in entry:
|
641
|
+
raise ValueError(
|
642
|
+
f"Invalid run_metadata entry format: '{entry}'. "
|
643
|
+
"Entry must be in format 'key:value' for direct "
|
644
|
+
"equality comparison or 'key:filterop:value' where "
|
645
|
+
"filterop is one of: equals, notequals, "
|
646
|
+
f"contains, startswith, endswith, oneof, gte, gt, "
|
647
|
+
f"lte, lt, in."
|
648
|
+
)
|
649
|
+
return self
|
650
|
+
|
651
|
+
def get_custom_filters(
|
652
|
+
self, table: Type["AnySchema"]
|
653
|
+
) -> List["ColumnElement[bool]"]:
|
654
|
+
"""Get custom run metadata filters.
|
655
|
+
|
656
|
+
Args:
|
657
|
+
table: The query table.
|
658
|
+
|
659
|
+
Returns:
|
660
|
+
A list of custom filters.
|
661
|
+
"""
|
662
|
+
custom_filters = super().get_custom_filters(table)
|
663
|
+
|
664
|
+
if self.run_metadata is not None:
|
665
|
+
from sqlmodel import exists, select
|
666
|
+
|
667
|
+
from zenml.enums import MetadataResourceTypes
|
668
|
+
from zenml.zen_stores.schemas import (
|
669
|
+
ArtifactVersionSchema,
|
670
|
+
ModelVersionSchema,
|
671
|
+
PipelineRunSchema,
|
672
|
+
RunMetadataResourceSchema,
|
673
|
+
RunMetadataSchema,
|
674
|
+
ScheduleSchema,
|
675
|
+
StepRunSchema,
|
676
|
+
)
|
677
|
+
|
678
|
+
resource_type_mapping = {
|
679
|
+
ArtifactVersionSchema: MetadataResourceTypes.ARTIFACT_VERSION,
|
680
|
+
ModelVersionSchema: MetadataResourceTypes.MODEL_VERSION,
|
681
|
+
PipelineRunSchema: MetadataResourceTypes.PIPELINE_RUN,
|
682
|
+
StepRunSchema: MetadataResourceTypes.STEP_RUN,
|
683
|
+
ScheduleSchema: MetadataResourceTypes.SCHEDULE,
|
684
|
+
}
|
685
|
+
|
686
|
+
# Create an EXISTS subquery for each run_metadata filter
|
687
|
+
for entry in self.run_metadata:
|
688
|
+
# Split at the first colon to get the key
|
689
|
+
key, value = entry.split(":", 1)
|
690
|
+
|
691
|
+
# Create an exists subquery
|
692
|
+
exists_subquery = exists(
|
693
|
+
select(RunMetadataResourceSchema.id)
|
694
|
+
.join(
|
695
|
+
RunMetadataSchema,
|
696
|
+
RunMetadataSchema.id # type: ignore[arg-type]
|
697
|
+
== RunMetadataResourceSchema.run_metadata_id,
|
698
|
+
)
|
699
|
+
.where(
|
700
|
+
RunMetadataResourceSchema.resource_id == table.id,
|
701
|
+
RunMetadataResourceSchema.resource_type
|
702
|
+
== resource_type_mapping[table].value,
|
703
|
+
self.generate_custom_query_conditions_for_column(
|
704
|
+
value=key,
|
705
|
+
table=RunMetadataSchema,
|
706
|
+
column="key",
|
707
|
+
),
|
708
|
+
self.generate_custom_query_conditions_for_column(
|
709
|
+
value=value,
|
710
|
+
table=RunMetadataSchema,
|
711
|
+
column="value",
|
712
|
+
),
|
713
|
+
)
|
714
|
+
)
|
715
|
+
custom_filters.append(exists_subquery)
|
716
|
+
|
717
|
+
return custom_filters
|
@@ -47,6 +47,7 @@ from zenml.models.v2.base.scoped import (
|
|
47
47
|
ProjectScopedResponseBody,
|
48
48
|
ProjectScopedResponseMetadata,
|
49
49
|
ProjectScopedResponseResources,
|
50
|
+
RunMetadataFilterMixin,
|
50
51
|
TaggableFilter,
|
51
52
|
)
|
52
53
|
from zenml.models.v2.core.artifact import ArtifactResponse
|
@@ -470,12 +471,15 @@ class ArtifactVersionResponse(
|
|
470
471
|
# ------------------ Filter Model ------------------
|
471
472
|
|
472
473
|
|
473
|
-
class ArtifactVersionFilter(
|
474
|
+
class ArtifactVersionFilter(
|
475
|
+
ProjectScopedFilter, TaggableFilter, RunMetadataFilterMixin
|
476
|
+
):
|
474
477
|
"""Model to enable advanced filtering of artifact versions."""
|
475
478
|
|
476
479
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
477
480
|
*ProjectScopedFilter.FILTER_EXCLUDE_FIELDS,
|
478
481
|
*TaggableFilter.FILTER_EXCLUDE_FIELDS,
|
482
|
+
*RunMetadataFilterMixin.FILTER_EXCLUDE_FIELDS,
|
479
483
|
"artifact_id",
|
480
484
|
"artifact",
|
481
485
|
"only_unused",
|
@@ -483,17 +487,23 @@ class ArtifactVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
483
487
|
"model",
|
484
488
|
"pipeline_run",
|
485
489
|
"model_version_id",
|
486
|
-
"run_metadata",
|
487
490
|
]
|
488
491
|
CUSTOM_SORTING_OPTIONS: ClassVar[List[str]] = [
|
489
492
|
*ProjectScopedFilter.CUSTOM_SORTING_OPTIONS,
|
490
493
|
*TaggableFilter.CUSTOM_SORTING_OPTIONS,
|
494
|
+
*RunMetadataFilterMixin.CUSTOM_SORTING_OPTIONS,
|
491
495
|
]
|
492
496
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
493
497
|
*ProjectScopedFilter.CLI_EXCLUDE_FIELDS,
|
494
498
|
*TaggableFilter.CLI_EXCLUDE_FIELDS,
|
499
|
+
*RunMetadataFilterMixin.CLI_EXCLUDE_FIELDS,
|
495
500
|
"artifact_id",
|
496
501
|
]
|
502
|
+
API_MULTI_INPUT_PARAMS: ClassVar[List[str]] = [
|
503
|
+
*ProjectScopedFilter.API_MULTI_INPUT_PARAMS,
|
504
|
+
*TaggableFilter.API_MULTI_INPUT_PARAMS,
|
505
|
+
*RunMetadataFilterMixin.API_MULTI_INPUT_PARAMS,
|
506
|
+
]
|
497
507
|
|
498
508
|
artifact: Optional[Union[UUID, str]] = Field(
|
499
509
|
default=None,
|
@@ -561,10 +571,6 @@ class ArtifactVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
561
571
|
description="Name/ID of a pipeline run that is associated with this "
|
562
572
|
"artifact version.",
|
563
573
|
)
|
564
|
-
run_metadata: Optional[Dict[str, Any]] = Field(
|
565
|
-
default=None,
|
566
|
-
description="The run_metadata to filter the artifact versions by.",
|
567
|
-
)
|
568
574
|
|
569
575
|
model_config = ConfigDict(protected_namespaces=())
|
570
576
|
|
@@ -590,8 +596,6 @@ class ArtifactVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
590
596
|
ModelVersionArtifactSchema,
|
591
597
|
ModelVersionSchema,
|
592
598
|
PipelineRunSchema,
|
593
|
-
RunMetadataResourceSchema,
|
594
|
-
RunMetadataSchema,
|
595
599
|
StepRunInputArtifactSchema,
|
596
600
|
StepRunOutputArtifactSchema,
|
597
601
|
StepRunSchema,
|
@@ -674,31 +678,6 @@ class ArtifactVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
674
678
|
)
|
675
679
|
custom_filters.append(pipeline_run_filter)
|
676
680
|
|
677
|
-
if self.run_metadata is not None:
|
678
|
-
from zenml.enums import MetadataResourceTypes
|
679
|
-
|
680
|
-
for key, value in self.run_metadata.items():
|
681
|
-
additional_filter = and_(
|
682
|
-
RunMetadataResourceSchema.resource_id
|
683
|
-
== ArtifactVersionSchema.id,
|
684
|
-
RunMetadataResourceSchema.resource_type
|
685
|
-
== MetadataResourceTypes.ARTIFACT_VERSION.value,
|
686
|
-
RunMetadataResourceSchema.run_metadata_id
|
687
|
-
== RunMetadataSchema.id,
|
688
|
-
self.generate_custom_query_conditions_for_column(
|
689
|
-
value=key,
|
690
|
-
table=RunMetadataSchema,
|
691
|
-
column="key",
|
692
|
-
),
|
693
|
-
self.generate_custom_query_conditions_for_column(
|
694
|
-
value=value,
|
695
|
-
table=RunMetadataSchema,
|
696
|
-
column="value",
|
697
|
-
json_encode_value=True,
|
698
|
-
),
|
699
|
-
)
|
700
|
-
custom_filters.append(additional_filter)
|
701
|
-
|
702
681
|
return custom_filters
|
703
682
|
|
704
683
|
@model_validator(mode="after")
|
@@ -40,14 +40,13 @@ from zenml.models.v2.base.scoped import (
|
|
40
40
|
ProjectScopedResponseBody,
|
41
41
|
ProjectScopedResponseMetadata,
|
42
42
|
ProjectScopedResponseResources,
|
43
|
+
RunMetadataFilterMixin,
|
43
44
|
TaggableFilter,
|
44
45
|
)
|
45
46
|
from zenml.models.v2.core.service import ServiceResponse
|
46
47
|
from zenml.models.v2.core.tag import TagResponse
|
47
48
|
|
48
49
|
if TYPE_CHECKING:
|
49
|
-
from sqlalchemy.sql.elements import ColumnElement
|
50
|
-
|
51
50
|
from zenml.model.model import Model
|
52
51
|
from zenml.models.v2.core.artifact_version import ArtifactVersionResponse
|
53
52
|
from zenml.models.v2.core.model import ModelResponse
|
@@ -566,24 +565,33 @@ class ModelVersionResponse(
|
|
566
565
|
# ------------------ Filter Model ------------------
|
567
566
|
|
568
567
|
|
569
|
-
class ModelVersionFilter(
|
568
|
+
class ModelVersionFilter(
|
569
|
+
ProjectScopedFilter, TaggableFilter, RunMetadataFilterMixin
|
570
|
+
):
|
570
571
|
"""Filter model for model versions."""
|
571
572
|
|
572
573
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
573
574
|
*ProjectScopedFilter.FILTER_EXCLUDE_FIELDS,
|
574
575
|
*TaggableFilter.FILTER_EXCLUDE_FIELDS,
|
576
|
+
*RunMetadataFilterMixin.FILTER_EXCLUDE_FIELDS,
|
575
577
|
"model",
|
576
|
-
"run_metadata",
|
577
578
|
]
|
578
579
|
CUSTOM_SORTING_OPTIONS: ClassVar[List[str]] = [
|
579
580
|
*ProjectScopedFilter.CUSTOM_SORTING_OPTIONS,
|
580
581
|
*TaggableFilter.CUSTOM_SORTING_OPTIONS,
|
582
|
+
*RunMetadataFilterMixin.CUSTOM_SORTING_OPTIONS,
|
581
583
|
]
|
582
584
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
583
585
|
*ProjectScopedFilter.CLI_EXCLUDE_FIELDS,
|
584
586
|
*TaggableFilter.CLI_EXCLUDE_FIELDS,
|
587
|
+
*RunMetadataFilterMixin.CLI_EXCLUDE_FIELDS,
|
585
588
|
"model",
|
586
589
|
]
|
590
|
+
API_MULTI_INPUT_PARAMS: ClassVar[List[str]] = [
|
591
|
+
*ProjectScopedFilter.API_MULTI_INPUT_PARAMS,
|
592
|
+
*TaggableFilter.API_MULTI_INPUT_PARAMS,
|
593
|
+
*RunMetadataFilterMixin.API_MULTI_INPUT_PARAMS,
|
594
|
+
]
|
587
595
|
|
588
596
|
name: Optional[str] = Field(
|
589
597
|
default=None,
|
@@ -598,10 +606,6 @@ class ModelVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
598
606
|
default=None,
|
599
607
|
union_mode="left_to_right",
|
600
608
|
)
|
601
|
-
run_metadata: Optional[Dict[str, str]] = Field(
|
602
|
-
default=None,
|
603
|
-
description="The run_metadata to filter the model versions by.",
|
604
|
-
)
|
605
609
|
model: Optional[Union[str, UUID]] = Field(
|
606
610
|
default=None,
|
607
611
|
description="The name or ID of the model which the search is scoped "
|
@@ -611,48 +615,6 @@ class ModelVersionFilter(ProjectScopedFilter, TaggableFilter):
|
|
611
615
|
union_mode="left_to_right",
|
612
616
|
)
|
613
617
|
|
614
|
-
def get_custom_filters(
|
615
|
-
self, table: Type["AnySchema"]
|
616
|
-
) -> List["ColumnElement[bool]"]:
|
617
|
-
"""Get custom filters.
|
618
|
-
|
619
|
-
Args:
|
620
|
-
table: The query table.
|
621
|
-
|
622
|
-
Returns:
|
623
|
-
A list of custom filters.
|
624
|
-
"""
|
625
|
-
custom_filters = super().get_custom_filters(table)
|
626
|
-
|
627
|
-
from sqlmodel import and_
|
628
|
-
|
629
|
-
from zenml.zen_stores.schemas import (
|
630
|
-
ModelVersionSchema,
|
631
|
-
RunMetadataResourceSchema,
|
632
|
-
RunMetadataSchema,
|
633
|
-
)
|
634
|
-
|
635
|
-
if self.run_metadata is not None:
|
636
|
-
from zenml.enums import MetadataResourceTypes
|
637
|
-
|
638
|
-
for key, value in self.run_metadata.items():
|
639
|
-
additional_filter = and_(
|
640
|
-
RunMetadataResourceSchema.resource_id
|
641
|
-
== ModelVersionSchema.id,
|
642
|
-
RunMetadataResourceSchema.resource_type
|
643
|
-
== MetadataResourceTypes.MODEL_VERSION,
|
644
|
-
RunMetadataResourceSchema.run_metadata_id
|
645
|
-
== RunMetadataSchema.id,
|
646
|
-
self.generate_custom_query_conditions_for_column(
|
647
|
-
value=value,
|
648
|
-
table=RunMetadataSchema,
|
649
|
-
column="value",
|
650
|
-
),
|
651
|
-
)
|
652
|
-
custom_filters.append(additional_filter)
|
653
|
-
|
654
|
-
return custom_filters
|
655
|
-
|
656
618
|
def apply_filter(
|
657
619
|
self,
|
658
620
|
query: AnyQuery,
|