zenml-nightly 0.55.0.dev20240124__py3-none-any.whl → 0.72.0.dev20250115__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 +9 -12
- zenml/actions/__init__.py +14 -0
- zenml/actions/base_action.py +682 -0
- zenml/actions/pipeline_run/__init__.py +0 -0
- zenml/actions/pipeline_run/pipeline_run_action.py +223 -0
- zenml/analytics/context.py +70 -15
- zenml/analytics/enums.py +21 -17
- zenml/analytics/models.py +1 -0
- zenml/analytics/utils.py +19 -7
- zenml/annotators/base_annotator.py +4 -3
- zenml/artifact_stores/base_artifact_store.py +155 -72
- zenml/artifact_stores/local_artifact_store.py +3 -2
- zenml/artifacts/artifact_config.py +67 -58
- zenml/artifacts/external_artifact.py +24 -39
- zenml/artifacts/external_artifact_config.py +27 -37
- zenml/artifacts/preexisting_data_materializer.py +90 -0
- zenml/artifacts/unmaterialized_artifact.py +2 -12
- zenml/artifacts/utils.py +521 -220
- zenml/cli/__init__.py +1511 -456
- zenml/cli/annotator.py +48 -14
- zenml/cli/artifact.py +22 -4
- zenml/cli/authorized_device.py +1 -0
- zenml/cli/base.py +185 -22
- zenml/cli/code_repository.py +1 -0
- zenml/cli/formatter.py +1 -1
- zenml/cli/integration.py +119 -24
- zenml/cli/login.py +977 -0
- zenml/cli/model.py +42 -15
- zenml/cli/model_registry.py +1 -2
- zenml/cli/pipeline.py +168 -82
- zenml/cli/secret.py +1 -2
- zenml/cli/served_model.py +56 -26
- zenml/cli/server.py +467 -619
- zenml/cli/service_accounts.py +55 -14
- zenml/cli/service_connectors.py +97 -6
- zenml/cli/stack.py +821 -531
- zenml/cli/stack_components.py +15 -598
- zenml/cli/tag.py +1 -0
- zenml/cli/text_utils.py +36 -2
- zenml/cli/user_management.py +204 -6
- zenml/cli/utils.py +411 -290
- zenml/client.py +1742 -298
- zenml/client_lazy_loader.py +224 -0
- zenml/code_repositories/base_code_repository.py +5 -4
- zenml/code_repositories/git/local_git_repository_context.py +1 -0
- zenml/code_repositories/local_repository_context.py +1 -0
- zenml/config/__init__.py +2 -0
- zenml/config/base_settings.py +6 -6
- zenml/config/build_configuration.py +43 -17
- zenml/config/compiler.py +82 -49
- zenml/config/docker_settings.py +139 -83
- zenml/config/global_config.py +260 -234
- zenml/config/pipeline_configurations.py +32 -11
- zenml/config/pipeline_run_configuration.py +15 -3
- zenml/config/pipeline_spec.py +6 -6
- zenml/config/resource_settings.py +8 -9
- zenml/config/retry_config.py +27 -0
- zenml/config/schedule.py +27 -18
- zenml/config/secret_reference_mixin.py +8 -4
- zenml/config/secrets_store_config.py +16 -24
- zenml/config/server_config.py +297 -39
- zenml/config/settings_resolver.py +2 -1
- zenml/config/source.py +97 -31
- zenml/config/step_configurations.py +83 -39
- zenml/config/step_run_info.py +3 -0
- zenml/config/store_config.py +20 -54
- zenml/config/strict_base_model.py +2 -6
- zenml/console.py +0 -1
- zenml/constants.py +241 -74
- zenml/container_registries/azure_container_registry.py +1 -0
- zenml/container_registries/base_container_registry.py +7 -3
- zenml/container_registries/default_container_registry.py +4 -3
- zenml/container_registries/dockerhub_container_registry.py +1 -0
- zenml/container_registries/gcp_container_registry.py +1 -0
- zenml/container_registries/github_container_registry.py +2 -10
- zenml/data_validators/base_data_validator.py +2 -2
- zenml/entrypoints/base_entrypoint_configuration.py +76 -17
- zenml/entrypoints/pipeline_entrypoint_configuration.py +1 -0
- zenml/entrypoints/step_entrypoint_configuration.py +21 -2
- zenml/enums.py +91 -9
- zenml/environment.py +52 -319
- zenml/{steps/base_parameters.py → event_hub/__init__.py} +5 -7
- zenml/event_hub/base_event_hub.py +196 -0
- zenml/event_hub/event_hub.py +181 -0
- zenml/event_sources/__init__.py +14 -0
- zenml/{lineage_graph/edge.py → event_sources/base_event.py} +5 -7
- zenml/event_sources/base_event_source.py +695 -0
- zenml/event_sources/webhooks/__init__.py +14 -0
- zenml/event_sources/webhooks/base_webhook_event_source.py +231 -0
- zenml/exceptions.py +40 -41
- zenml/feature_stores/base_feature_store.py +4 -6
- zenml/hooks/hook_validators.py +3 -11
- zenml/image_builders/base_image_builder.py +5 -2
- zenml/image_builders/build_context.py +24 -80
- zenml/image_builders/local_image_builder.py +14 -6
- zenml/integrations/__init__.py +16 -4
- zenml/integrations/airflow/__init__.py +3 -5
- zenml/integrations/airflow/flavors/airflow_orchestrator_flavor.py +15 -7
- zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +15 -252
- zenml/integrations/airflow/orchestrators/dag_generator.py +5 -3
- zenml/integrations/argilla/__init__.py +46 -0
- zenml/integrations/argilla/annotators/__init__.py +20 -0
- zenml/integrations/argilla/annotators/argilla_annotator.py +443 -0
- zenml/{post_execution → integrations/argilla/flavors}/__init__.py +9 -13
- zenml/integrations/argilla/flavors/argilla_annotator_flavor.py +150 -0
- zenml/integrations/aws/__init__.py +7 -3
- zenml/integrations/aws/container_registries/aws_container_registry.py +44 -8
- zenml/integrations/aws/flavors/__init__.py +6 -0
- zenml/integrations/aws/flavors/aws_container_registry_flavor.py +3 -2
- zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
- zenml/integrations/aws/flavors/sagemaker_orchestrator_flavor.py +104 -16
- zenml/integrations/aws/flavors/sagemaker_step_operator_flavor.py +6 -2
- zenml/integrations/aws/image_builders/__init__.py +20 -0
- zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +421 -133
- zenml/integrations/aws/service_connectors/aws_service_connector.py +175 -48
- zenml/integrations/aws/step_operators/sagemaker_step_operator.py +1 -1
- zenml/integrations/azure/__init__.py +14 -5
- zenml/integrations/azure/azureml_utils.py +201 -0
- zenml/integrations/azure/flavors/__init__.py +11 -0
- zenml/integrations/azure/flavors/azureml.py +139 -0
- zenml/integrations/azure/flavors/azureml_orchestrator_flavor.py +166 -0
- zenml/integrations/azure/flavors/azureml_step_operator_flavor.py +71 -18
- zenml/integrations/azure/orchestrators/__init__.py +19 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +583 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py +82 -0
- zenml/integrations/azure/service_connectors/azure_service_connector.py +15 -6
- zenml/integrations/azure/step_operators/azureml_step_operator.py +78 -173
- zenml/integrations/bentoml/__init__.py +1 -1
- zenml/integrations/bentoml/constants.py +1 -1
- zenml/integrations/bentoml/materializers/bentoml_bento_materializer.py +19 -31
- zenml/integrations/bentoml/model_deployers/bentoml_model_deployer.py +128 -239
- zenml/integrations/bentoml/services/__init__.py +15 -4
- zenml/integrations/bentoml/services/bentoml_container_deployment.py +399 -0
- zenml/integrations/bentoml/services/{bentoml_deployment.py → bentoml_local_deployment.py} +85 -43
- zenml/integrations/bentoml/services/deployment_type.py +23 -0
- zenml/integrations/bentoml/steps/bento_builder.py +2 -0
- zenml/integrations/bentoml/steps/bentoml_deployer.py +97 -47
- zenml/integrations/bitbucket/__init__.py +42 -0
- zenml/integrations/bitbucket/plugins/__init__.py +20 -0
- zenml/integrations/bitbucket/plugins/bitbucket_webhook_event_source_flavor.py +43 -0
- zenml/integrations/bitbucket/plugins/event_sources/__init__.py +0 -0
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +486 -0
- zenml/integrations/comet/__init__.py +49 -0
- zenml/integrations/{kserve/services → comet/experiment_trackers}/__init__.py +5 -6
- zenml/integrations/comet/experiment_trackers/comet_experiment_tracker.py +175 -0
- zenml/integrations/comet/flavors/__init__.py +24 -0
- zenml/integrations/comet/flavors/comet_experiment_tracker_flavor.py +129 -0
- zenml/integrations/constants.py +14 -2
- zenml/integrations/databricks/__init__.py +70 -0
- zenml/{lineage_graph → integrations/databricks/flavors}/__init__.py +14 -18
- zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +174 -0
- zenml/integrations/{kserve → databricks}/model_deployers/__init__.py +5 -5
- zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
- zenml/integrations/databricks/orchestrators/__init__.py +20 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +501 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
- zenml/integrations/databricks/services/__init__.py +19 -0
- zenml/integrations/databricks/services/databricks_deployment.py +407 -0
- zenml/integrations/{gcp/orchestrators/vertex_scheduler → databricks/utils}/__init__.py +2 -2
- zenml/integrations/databricks/utils/databricks_utils.py +87 -0
- zenml/integrations/deepchecks/__init__.py +30 -10
- zenml/integrations/deepchecks/data_validators/deepchecks_data_validator.py +59 -18
- zenml/integrations/deepchecks/materializers/deepchecks_dataset_materializer.py +3 -1
- zenml/integrations/deepchecks/materializers/deepchecks_results_materializer.py +3 -3
- zenml/integrations/deepchecks/validation_checks.py +62 -35
- zenml/integrations/discord/__init__.py +1 -0
- zenml/integrations/discord/steps/discord_alerter_ask_step.py +1 -0
- zenml/integrations/discord/steps/discord_alerter_post_step.py +1 -0
- zenml/integrations/evidently/__init__.py +22 -4
- zenml/integrations/evidently/column_mapping.py +11 -3
- zenml/integrations/evidently/data_validators/evidently_data_validator.py +24 -6
- zenml/integrations/evidently/metrics.py +7 -8
- zenml/integrations/evidently/tests.py +7 -8
- zenml/integrations/facets/__init__.py +22 -5
- zenml/integrations/facets/models.py +2 -7
- zenml/integrations/feast/__init__.py +19 -3
- zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -32
- zenml/integrations/gcp/__init__.py +6 -6
- zenml/integrations/gcp/artifact_stores/gcp_artifact_store.py +6 -0
- zenml/integrations/gcp/flavors/gcp_artifact_store_flavor.py +1 -0
- zenml/integrations/gcp/flavors/vertex_orchestrator_flavor.py +24 -2
- zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py +14 -1
- zenml/integrations/gcp/google_credentials_mixin.py +1 -1
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +519 -296
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +788 -113
- zenml/integrations/gcp/step_operators/vertex_step_operator.py +9 -1
- zenml/integrations/github/__init__.py +15 -0
- zenml/integrations/github/code_repositories/github_code_repository.py +3 -2
- zenml/integrations/github/plugins/__init__.py +19 -0
- zenml/integrations/github/plugins/event_sources/__init__.py +0 -0
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +510 -0
- zenml/integrations/github/plugins/github_webhook_event_source_flavor.py +43 -0
- zenml/integrations/gitlab/code_repositories/gitlab_code_repository.py +7 -1
- zenml/integrations/great_expectations/__init__.py +22 -10
- zenml/integrations/great_expectations/data_validators/ge_data_validator.py +61 -57
- zenml/integrations/great_expectations/flavors/great_expectations_data_validator_flavor.py +35 -2
- zenml/integrations/great_expectations/ge_store_backend.py +24 -11
- zenml/integrations/great_expectations/materializers/ge_materializer.py +9 -9
- zenml/integrations/great_expectations/utils.py +5 -5
- zenml/integrations/huggingface/__init__.py +52 -1
- zenml/integrations/huggingface/flavors/__init__.py +26 -0
- zenml/integrations/huggingface/flavors/huggingface_model_deployer_flavor.py +130 -0
- zenml/integrations/huggingface/materializers/__init__.py +3 -0
- zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +102 -19
- zenml/integrations/huggingface/materializers/huggingface_pt_model_materializer.py +18 -19
- zenml/integrations/huggingface/materializers/huggingface_t5_materializer.py +104 -0
- zenml/integrations/huggingface/materializers/huggingface_tf_model_materializer.py +18 -19
- zenml/integrations/huggingface/materializers/huggingface_tokenizer_materializer.py +13 -15
- zenml/integrations/huggingface/model_deployers/__init__.py +20 -0
- zenml/integrations/huggingface/model_deployers/huggingface_model_deployer.py +247 -0
- zenml/integrations/huggingface/services/__init__.py +19 -0
- zenml/integrations/huggingface/services/huggingface_deployment.py +292 -0
- zenml/integrations/huggingface/steps/__init__.py +21 -0
- zenml/integrations/huggingface/steps/accelerate_runner.py +166 -0
- zenml/integrations/huggingface/steps/huggingface_deployer.py +110 -0
- zenml/integrations/hyperai/__init__.py +53 -0
- zenml/integrations/hyperai/flavors/__init__.py +20 -0
- zenml/integrations/hyperai/flavors/hyperai_orchestrator_flavor.py +170 -0
- zenml/integrations/hyperai/orchestrators/__init__.py +21 -0
- zenml/integrations/hyperai/orchestrators/hyperai_orchestrator.py +510 -0
- zenml/integrations/hyperai/service_connectors/__init__.py +20 -0
- zenml/integrations/hyperai/service_connectors/hyperai_service_connector.py +375 -0
- zenml/integrations/integration.py +101 -47
- zenml/integrations/kaniko/flavors/kaniko_image_builder_flavor.py +6 -44
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +9 -6
- zenml/integrations/kubeflow/__init__.py +4 -1
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +67 -82
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +306 -248
- zenml/integrations/kubernetes/__init__.py +6 -3
- zenml/integrations/kubernetes/flavors/__init__.py +8 -0
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +43 -2
- zenml/integrations/kubernetes/flavors/kubernetes_step_operator_flavor.py +166 -0
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +67 -12
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +89 -21
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +39 -7
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +42 -19
- zenml/integrations/kubernetes/pod_settings.py +21 -31
- zenml/integrations/kubernetes/serialization_utils.py +3 -3
- zenml/integrations/kubernetes/service_connectors/kubernetes_service_connector.py +14 -11
- zenml/integrations/kubernetes/step_operators/__init__.py +22 -0
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +236 -0
- zenml/integrations/label_studio/__init__.py +1 -3
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +46 -14
- zenml/integrations/label_studio/flavors/__init__.py +2 -0
- zenml/integrations/label_studio/flavors/label_studio_annotator_flavor.py +20 -5
- zenml/integrations/langchain/__init__.py +7 -1
- zenml/integrations/langchain/materializers/document_materializer.py +44 -8
- zenml/integrations/langchain/materializers/openai_embedding_materializer.py +28 -2
- zenml/integrations/lightgbm/__init__.py +1 -0
- zenml/integrations/lightgbm/materializers/lightgbm_booster_materializer.py +8 -15
- zenml/integrations/lightgbm/materializers/lightgbm_dataset_materializer.py +11 -16
- zenml/integrations/lightning/__init__.py +48 -0
- zenml/integrations/lightning/flavors/__init__.py +23 -0
- zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +168 -0
- zenml/integrations/lightning/orchestrators/__init__.py +23 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +617 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator_entrypoint.py +303 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator_entrypoint_configuration.py +77 -0
- zenml/integrations/lightning/orchestrators/utils.py +67 -0
- zenml/integrations/mlflow/__init__.py +55 -8
- zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +31 -13
- zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +32 -37
- zenml/integrations/mlflow/model_deployers/mlflow_model_deployer.py +42 -233
- zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +42 -49
- zenml/integrations/mlflow/services/mlflow_deployment.py +30 -5
- zenml/integrations/mlflow/steps/mlflow_deployer.py +25 -27
- zenml/integrations/mlflow/steps/mlflow_registry.py +3 -1
- zenml/integrations/modal/__init__.py +46 -0
- zenml/integrations/modal/flavors/__init__.py +26 -0
- zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
- zenml/integrations/modal/step_operators/__init__.py +22 -0
- zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
- zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
- zenml/integrations/neptune/experiment_trackers/run_state.py +71 -55
- zenml/integrations/neptune/flavors/neptune_experiment_tracker_flavor.py +1 -1
- zenml/integrations/neural_prophet/__init__.py +6 -1
- zenml/integrations/numpy/__init__.py +32 -0
- zenml/integrations/{kserve/constants.py → numpy/materializers/__init__.py} +5 -4
- zenml/integrations/numpy/materializers/numpy_materializer.py +246 -0
- zenml/integrations/openai/__init__.py +1 -1
- zenml/integrations/openai/hooks/open_ai_failure_hook.py +39 -14
- zenml/{steps/external_artifact.py → integrations/pandas/__init__.py} +17 -11
- zenml/integrations/{kserve/custom_deployer → pandas/materializers}/__init__.py +5 -5
- zenml/integrations/pandas/materializers/pandas_materializer.py +192 -0
- zenml/integrations/pigeon/__init__.py +44 -0
- zenml/integrations/pigeon/annotators/__init__.py +20 -0
- zenml/integrations/pigeon/annotators/pigeon_annotator.py +330 -0
- zenml/integrations/{kserve → pigeon}/flavors/__init__.py +7 -7
- zenml/integrations/pigeon/flavors/pigeon_annotator_flavor.py +104 -0
- zenml/integrations/pillow/materializers/pillow_image_materializer.py +17 -20
- zenml/integrations/polars/__init__.py +1 -0
- zenml/integrations/polars/materializers/dataframe_materializer.py +26 -39
- zenml/integrations/prodigy/__init__.py +48 -0
- zenml/integrations/prodigy/annotators/__init__.py +20 -0
- zenml/integrations/prodigy/annotators/prodigy_annotator.py +275 -0
- zenml/integrations/prodigy/flavors/__init__.py +24 -0
- zenml/integrations/prodigy/flavors/prodigy_annotator_flavor.py +101 -0
- zenml/integrations/pycaret/__init__.py +6 -0
- zenml/integrations/pycaret/materializers/model_materializer.py +7 -22
- zenml/integrations/pytorch/materializers/base_pytorch_materializer.py +8 -2
- zenml/integrations/pytorch/materializers/pytorch_module_materializer.py +4 -1
- zenml/integrations/registry.py +38 -1
- zenml/integrations/s3/__init__.py +2 -3
- zenml/integrations/s3/artifact_stores/s3_artifact_store.py +191 -9
- zenml/integrations/s3/flavors/s3_artifact_store_flavor.py +22 -45
- zenml/integrations/s3/utils.py +39 -0
- zenml/integrations/seldon/__init__.py +18 -2
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +19 -141
- zenml/integrations/seldon/secret_schemas/secret_schemas.py +2 -2
- zenml/integrations/seldon/seldon_client.py +55 -70
- zenml/integrations/seldon/services/seldon_deployment.py +4 -5
- zenml/integrations/seldon/steps/seldon_deployer.py +21 -20
- zenml/integrations/sklearn/__init__.py +1 -1
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +29 -7
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +47 -28
- zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
- zenml/integrations/skypilot_aws/__init__.py +3 -2
- zenml/integrations/skypilot_aws/flavors/skypilot_orchestrator_aws_vm_flavor.py +1 -1
- zenml/integrations/skypilot_azure/__init__.py +2 -4
- zenml/integrations/skypilot_azure/flavors/skypilot_orchestrator_azure_vm_flavor.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +3 -2
- zenml/integrations/skypilot_gcp/flavors/skypilot_orchestrator_gcp_vm_flavor.py +1 -1
- zenml/integrations/skypilot_kubernetes/__init__.py +52 -0
- zenml/integrations/skypilot_kubernetes/flavors/__init__.py +26 -0
- zenml/integrations/skypilot_kubernetes/flavors/skypilot_orchestrator_kubernetes_vm_flavor.py +125 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/__init__.py +25 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/skypilot_kubernetes_vm_orchestrator.py +74 -0
- zenml/integrations/skypilot_lambda/__init__.py +50 -0
- zenml/integrations/{kserve/secret_schemas → skypilot_lambda/flavors}/__init__.py +9 -12
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +130 -0
- zenml/{lineage_graph/node → integrations/skypilot_lambda/orchestrators}/__init__.py +8 -15
- zenml/integrations/skypilot_lambda/orchestrators/skypilot_lambda_vm_orchestrator.py +92 -0
- zenml/integrations/slack/__init__.py +1 -0
- zenml/integrations/slack/alerters/slack_alerter.py +22 -2
- zenml/integrations/slack/flavors/__init__.py +2 -0
- zenml/integrations/slack/flavors/slack_alerter_flavor.py +13 -4
- zenml/integrations/slack/steps/slack_alerter_ask_step.py +1 -0
- zenml/integrations/slack/steps/slack_alerter_post_step.py +1 -0
- zenml/integrations/spark/flavors/spark_step_operator_flavor.py +2 -39
- zenml/integrations/spark/step_operators/kubernetes_step_operator.py +1 -0
- zenml/integrations/spark/step_operators/spark_entrypoint_configuration.py +1 -0
- zenml/integrations/spark/step_operators/spark_step_operator.py +2 -0
- zenml/integrations/tekton/__init__.py +2 -1
- zenml/integrations/tekton/flavors/tekton_orchestrator_flavor.py +66 -23
- zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +549 -235
- zenml/integrations/tensorboard/__init__.py +1 -13
- zenml/integrations/tensorboard/services/tensorboard_service.py +3 -4
- zenml/integrations/tensorboard/visualizers/tensorboard_visualizer.py +66 -59
- zenml/integrations/tensorflow/__init__.py +10 -15
- zenml/integrations/tensorflow/materializers/keras_materializer.py +24 -27
- zenml/integrations/tensorflow/materializers/tf_dataset_materializer.py +9 -16
- zenml/integrations/vllm/__init__.py +50 -0
- zenml/integrations/vllm/flavors/__init__.py +21 -0
- zenml/integrations/vllm/flavors/vllm_model_deployer_flavor.py +91 -0
- zenml/integrations/vllm/model_deployers/__init__.py +19 -0
- zenml/integrations/vllm/model_deployers/vllm_model_deployer.py +263 -0
- zenml/integrations/vllm/services/__init__.py +19 -0
- zenml/integrations/vllm/services/vllm_deployment.py +206 -0
- zenml/integrations/wandb/__init__.py +1 -0
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +21 -18
- zenml/integrations/whylogs/__init__.py +18 -2
- zenml/integrations/whylogs/data_validators/whylogs_data_validator.py +3 -3
- zenml/integrations/whylogs/flavors/whylogs_data_validator_flavor.py +1 -1
- zenml/integrations/whylogs/materializers/whylogs_materializer.py +14 -21
- zenml/integrations/xgboost/materializers/xgboost_booster_materializer.py +11 -22
- zenml/integrations/xgboost/materializers/xgboost_dmatrix_materializer.py +10 -19
- zenml/io/fileio.py +1 -0
- zenml/io/filesystem.py +2 -2
- zenml/io/local_filesystem.py +3 -3
- zenml/logger.py +41 -17
- zenml/logging/__init__.py +5 -0
- zenml/logging/step_logging.py +280 -32
- zenml/{new/steps → login}/__init__.py +4 -1
- zenml/login/credentials.py +346 -0
- zenml/login/credentials_store.py +603 -0
- zenml/{new/pipelines → login/pro}/__init__.py +4 -1
- zenml/login/pro/client.py +496 -0
- zenml/login/pro/constants.py +34 -0
- zenml/{zen_stores/schemas/identity_schemas.py → login/pro/models.py} +9 -11
- zenml/login/pro/organization/__init__.py +14 -0
- zenml/login/pro/organization/client.py +79 -0
- zenml/{lineage_graph/node/base_node.py → login/pro/organization/models.py} +13 -12
- zenml/{_hub → login/pro/tenant}/__init__.py +2 -2
- zenml/login/pro/tenant/client.py +92 -0
- zenml/login/pro/tenant/models.py +174 -0
- zenml/login/pro/utils.py +121 -0
- zenml/{cli → login}/web_login.py +66 -21
- zenml/materializers/__init__.py +2 -4
- zenml/materializers/base_materializer.py +180 -51
- zenml/materializers/built_in_materializer.py +50 -23
- zenml/materializers/cloudpickle_materializer.py +4 -5
- zenml/materializers/numpy_materializer.py +23 -233
- zenml/materializers/pandas_materializer.py +22 -174
- zenml/materializers/pydantic_materializer.py +2 -2
- zenml/materializers/service_materializer.py +12 -10
- zenml/materializers/structured_string_materializer.py +12 -6
- zenml/materializers/uuid_materializer.py +79 -0
- zenml/metadata/lazy_load.py +33 -17
- zenml/metadata/metadata_types.py +112 -3
- zenml/model/lazy_load.py +85 -4
- zenml/model/model.py +236 -226
- zenml/model/utils.py +99 -141
- zenml/model_deployers/base_model_deployer.py +319 -47
- zenml/model_registries/base_model_registry.py +17 -15
- zenml/models/__init__.py +254 -175
- zenml/models/v2/base/base.py +254 -112
- zenml/models/v2/base/base_plugin_flavor.py +76 -0
- zenml/models/v2/base/filter.py +530 -199
- zenml/models/v2/base/page.py +2 -12
- zenml/models/v2/base/scoped.py +292 -22
- zenml/models/v2/core/action.py +276 -0
- zenml/models/v2/core/action_flavor.py +57 -0
- zenml/models/v2/core/api_key.py +35 -12
- zenml/models/v2/core/artifact.py +126 -6
- zenml/models/v2/core/artifact_version.py +289 -65
- zenml/models/v2/core/artifact_visualization.py +10 -4
- zenml/models/v2/core/code_reference.py +13 -4
- zenml/models/v2/core/code_repository.py +39 -16
- zenml/models/v2/core/component.py +113 -61
- zenml/models/v2/core/device.py +25 -5
- zenml/models/v2/core/event_source.py +244 -0
- zenml/models/v2/core/event_source_flavor.py +67 -0
- zenml/models/v2/core/flavor.py +90 -27
- zenml/models/v2/core/logs.py +81 -12
- zenml/models/v2/core/model.py +91 -42
- zenml/models/v2/core/model_version.py +100 -55
- zenml/models/v2/core/model_version_artifact.py +96 -89
- zenml/models/v2/core/model_version_pipeline_run.py +86 -53
- zenml/models/v2/core/pipeline.py +205 -80
- zenml/models/v2/core/pipeline_build.py +110 -21
- zenml/models/v2/core/pipeline_deployment.py +101 -36
- zenml/models/v2/core/pipeline_run.py +545 -33
- zenml/models/v2/core/run_metadata.py +23 -181
- zenml/models/v2/core/run_template.py +439 -0
- zenml/models/v2/core/schedule.py +66 -29
- zenml/models/v2/core/secret.py +33 -21
- zenml/models/v2/core/server_settings.py +224 -0
- zenml/models/v2/core/service.py +500 -0
- zenml/models/v2/core/service_account.py +40 -15
- zenml/models/v2/core/service_connector.py +247 -49
- zenml/models/v2/core/stack.py +163 -70
- zenml/models/v2/core/step_run.py +210 -48
- zenml/models/v2/core/tag.py +21 -8
- zenml/models/v2/core/tag_resource.py +13 -4
- zenml/models/v2/core/trigger.py +422 -0
- zenml/models/v2/core/trigger_execution.py +119 -0
- zenml/models/v2/core/user.py +136 -69
- zenml/models/v2/core/workspace.py +26 -7
- zenml/models/v2/misc/auth_models.py +11 -2
- zenml/models/v2/misc/build_item.py +3 -3
- zenml/models/v2/misc/external_user.py +3 -6
- zenml/models/v2/misc/info_models.py +78 -0
- zenml/models/v2/misc/loaded_visualization.py +2 -2
- zenml/models/v2/misc/run_metadata.py +38 -0
- zenml/models/v2/misc/server_models.py +56 -0
- zenml/models/v2/misc/service_connector_type.py +9 -17
- zenml/models/v2/misc/stack_deployment.py +96 -0
- zenml/models/v2/misc/user_auth.py +7 -9
- zenml/orchestrators/__init__.py +4 -0
- zenml/orchestrators/base_orchestrator.py +136 -25
- zenml/orchestrators/containerized_orchestrator.py +1 -0
- zenml/orchestrators/dag_runner.py +18 -3
- zenml/orchestrators/input_utils.py +109 -48
- zenml/orchestrators/local/local_orchestrator.py +10 -0
- zenml/orchestrators/local_docker/local_docker_orchestrator.py +14 -42
- zenml/orchestrators/output_utils.py +16 -6
- zenml/orchestrators/publish_utils.py +12 -5
- zenml/orchestrators/step_launcher.py +142 -194
- zenml/orchestrators/step_run_utils.py +386 -0
- zenml/orchestrators/step_runner.py +181 -270
- zenml/orchestrators/utils.py +219 -84
- zenml/orchestrators/wheeled_orchestrator.py +147 -0
- zenml/pipelines/__init__.py +3 -16
- zenml/{new/pipelines → pipelines}/build_utils.py +287 -47
- zenml/{new/pipelines → pipelines}/pipeline_context.py +6 -2
- zenml/pipelines/pipeline_decorator.py +40 -64
- zenml/{new/pipelines/pipeline.py → pipelines/pipeline_definition.py} +376 -440
- zenml/pipelines/run_utils.py +358 -0
- zenml/plugins/__init__.py +0 -0
- zenml/plugins/base_plugin_flavor.py +88 -0
- zenml/plugins/plugin_flavor_registry.py +342 -0
- zenml/secret/base_secret.py +7 -8
- zenml/secret/schemas/basic_auth_secret_schema.py +0 -1
- zenml/service_connectors/docker_service_connector.py +19 -4
- zenml/service_connectors/service_connector.py +12 -14
- zenml/service_connectors/service_connector_registry.py +71 -55
- zenml/service_connectors/service_connector_utils.py +418 -0
- zenml/services/__init__.py +0 -2
- zenml/services/container/container_service.py +9 -6
- zenml/services/container/container_service_endpoint.py +1 -1
- zenml/services/container/entrypoint.py +3 -2
- zenml/services/local/local_daemon_entrypoint.py +9 -6
- zenml/services/local/local_service.py +1 -1
- zenml/services/local/local_service_endpoint.py +1 -1
- zenml/services/service.py +222 -130
- zenml/services/service_status.py +2 -1
- zenml/services/service_type.py +6 -5
- zenml/stack/flavor.py +25 -18
- zenml/stack/flavor_registry.py +4 -4
- zenml/stack/stack.py +20 -131
- zenml/stack/stack_component.py +136 -110
- zenml/stack/utils.py +36 -15
- zenml/stack_deployments/__init__.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +320 -0
- zenml/stack_deployments/azure_stack_deployment.py +315 -0
- zenml/stack_deployments/gcp_stack_deployment.py +315 -0
- zenml/stack_deployments/stack_deployment.py +232 -0
- zenml/stack_deployments/utils.py +48 -0
- zenml/step_operators/step_operator_entrypoint_configuration.py +2 -1
- zenml/steps/__init__.py +3 -9
- zenml/steps/base_step.py +172 -315
- zenml/{new/steps → steps}/decorated_step.py +1 -0
- zenml/steps/entrypoint_function_utils.py +33 -93
- zenml/{new/steps → steps}/step_context.py +70 -50
- zenml/steps/step_decorator.py +47 -93
- zenml/steps/step_invocation.py +22 -60
- zenml/steps/utils.py +161 -48
- zenml/types.py +14 -1
- zenml/utils/archivable.py +178 -0
- zenml/utils/callback_registry.py +71 -0
- zenml/utils/code_repository_utils.py +1 -0
- zenml/utils/code_utils.py +346 -0
- zenml/utils/cuda_utils.py +50 -0
- zenml/utils/dashboard_utils.py +67 -21
- zenml/utils/deprecation_utils.py +22 -24
- zenml/utils/dict_utils.py +22 -0
- zenml/utils/docker_utils.py +34 -5
- zenml/utils/downloaded_repository_context.py +1 -0
- zenml/utils/env_utils.py +55 -1
- zenml/utils/filesync_model.py +65 -28
- zenml/utils/function_utils.py +260 -0
- zenml/utils/integration_utils.py +1 -0
- zenml/utils/json_utils.py +131 -0
- zenml/utils/materializer_utils.py +1 -1
- zenml/utils/metadata_utils.py +368 -0
- zenml/utils/notebook_utils.py +136 -0
- zenml/utils/package_utils.py +89 -0
- zenml/utils/pagination_utils.py +9 -7
- zenml/utils/pipeline_docker_image_builder.py +152 -149
- zenml/utils/pydantic_utils.py +276 -66
- zenml/utils/requirements_utils.py +71 -0
- zenml/utils/secret_utils.py +66 -12
- zenml/utils/settings_utils.py +2 -1
- zenml/utils/singleton.py +15 -3
- zenml/utils/source_code_utils.py +1 -0
- zenml/utils/source_utils.py +236 -14
- zenml/utils/string_utils.py +140 -0
- zenml/utils/typed_model.py +5 -3
- zenml/utils/typing_utils.py +223 -0
- zenml/utils/visualization_utils.py +5 -3
- zenml/utils/yaml_utils.py +1 -1
- zenml/zen_server/auth.py +295 -52
- zenml/zen_server/cache.py +208 -0
- zenml/zen_server/cloud_utils.py +261 -0
- zenml/zen_server/dashboard/assets/404-Dfq64Boz.js +1 -0
- zenml/zen_server/dashboard/assets/@radix-DeK6qiuw.js +85 -0
- zenml/zen_server/dashboard/assets/@react-router-B3Z5rLr2.js +29 -0
- zenml/zen_server/dashboard/assets/@reactflow-BUNIMFeC.js +17 -0
- zenml/zen_server/dashboard/assets/@reactflow-C26Olbza.css +1 -0
- zenml/zen_server/dashboard/assets/@tanstack-DT5WLu9C.js +22 -0
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-B73Vs10T.js +1 -0
- zenml/zen_server/dashboard/assets/CodeSnippet-Bbx6fIb6.css +1 -0
- zenml/zen_server/dashboard/assets/CodeSnippet-DIJRT2NT.js +9 -0
- zenml/zen_server/dashboard/assets/CollapsibleCard-BzUHGZOU.js +1 -0
- zenml/zen_server/dashboard/assets/Commands-BEGyld4c.js +1 -0
- zenml/zen_server/dashboard/assets/ComponentBadge-xyKiek1s.js +1 -0
- zenml/zen_server/dashboard/assets/CopyButton-DhW-mapu.js +2 -0
- zenml/zen_server/dashboard/assets/CsvVizualization-D8oazBiE.js +15 -0
- zenml/zen_server/dashboard/assets/DeleteAlertDialog-WkSIIgfy.js +1 -0
- zenml/zen_server/dashboard/assets/DialogItem-Bgroeg29.js +1 -0
- zenml/zen_server/dashboard/assets/DisplayDate-CDMUcQHS.js +1 -0
- zenml/zen_server/dashboard/assets/EmptyState-BzdlCwp3.js +1 -0
- zenml/zen_server/dashboard/assets/Error-CY5tlu17.js +1 -0
- zenml/zen_server/dashboard/assets/ExecutionStatus-G8mjIaeA.js +1 -0
- zenml/zen_server/dashboard/assets/Helpbox-Bb1ed--O.js +1 -0
- zenml/zen_server/dashboard/assets/Infobox-Da6-76M2.js +1 -0
- zenml/zen_server/dashboard/assets/InlineAvatar-DqnZaBNq.js +1 -0
- zenml/zen_server/dashboard/assets/Lock-CYYy18Mm.js +1 -0
- zenml/zen_server/dashboard/assets/MarkdownVisualization-ylXaAxev.js +14 -0
- zenml/zen_server/dashboard/assets/NestedCollapsible-aK5ojKoF.js +1 -0
- zenml/zen_server/dashboard/assets/NumberBox-Dtp3J6g5.js +1 -0
- zenml/zen_server/dashboard/assets/Partials-CqZp5NMX.js +1 -0
- zenml/zen_server/dashboard/assets/PasswordChecker-B0nadgh6.js +1 -0
- zenml/zen_server/dashboard/assets/ProBadge-B4tRUYve.js +1 -0
- zenml/zen_server/dashboard/assets/ProCta-CZuP29Qz.js +1 -0
- zenml/zen_server/dashboard/assets/ProviderIcon-Bd7GUQ1_.js +1 -0
- zenml/zen_server/dashboard/assets/ProviderRadio-mstdqzsS.js +1 -0
- zenml/zen_server/dashboard/assets/RunSelector-CsruSB4i.js +1 -0
- zenml/zen_server/dashboard/assets/RunsBody-DxxtWVYz.js +1 -0
- zenml/zen_server/dashboard/assets/SearchField-D6tPxyqw.js +1 -0
- zenml/zen_server/dashboard/assets/SecretTooltip-CLzJIYW_.js +1 -0
- zenml/zen_server/dashboard/assets/SetPassword-Yn50ooBC.js +1 -0
- zenml/zen_server/dashboard/assets/StackList-U537qoYd.js +1 -0
- zenml/zen_server/dashboard/assets/Tabs-CNv-eTYM.js +1 -0
- zenml/zen_server/dashboard/assets/Tick-jEIevzVf.js +1 -0
- zenml/zen_server/dashboard/assets/UpdatePasswordSchemas-C16GW-kX.js +1 -0
- zenml/zen_server/dashboard/assets/UsageReason-Bf2tzhv1.js +1 -0
- zenml/zen_server/dashboard/assets/WizardFooter-D6i-AP1K.js +1 -0
- zenml/zen_server/dashboard/assets/acp-DOsXjFc7.webp +0 -0
- zenml/zen_server/dashboard/assets/adam-e-y0WnB_.webp +0 -0
- zenml/zen_server/dashboard/assets/alex-DcCuDHPg.webp +0 -0
- zenml/zen_server/dashboard/assets/all-pipeline-runs-query-DUti43aF.js +1 -0
- zenml/zen_server/dashboard/assets/baris-C0ZrZ10g.webp +0 -0
- zenml/zen_server/dashboard/assets/check-DloQpStc.js +1 -0
- zenml/zen_server/dashboard/assets/check-circle-jNbX5-sR.js +1 -0
- zenml/zen_server/dashboard/assets/chevron-down-6JyMkfjR.js +1 -0
- zenml/zen_server/dashboard/assets/chevron-right-double-D7ojK9Co.js +1 -0
- zenml/zen_server/dashboard/assets/cloud-squares-DeRLMopf.svg +43 -0
- zenml/zen_server/dashboard/assets/code-browser-CUFUIHfp.js +1 -0
- zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
- zenml/zen_server/dashboard/assets/components-Br2ezRib.js +1 -0
- zenml/zen_server/dashboard/assets/connectors-video-C9qY4syJ.svg +21 -0
- zenml/zen_server/dashboard/assets/copy-C8XQA2Ug.js +1 -0
- zenml/zen_server/dashboard/assets/create-stack-Ch2WPs9U.js +1 -0
- zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
- zenml/zen_server/dashboard/assets/delete-run-Byf9hTjA.js +1 -0
- zenml/zen_server/dashboard/assets/docker-BdA9vrnW.js +1 -0
- zenml/zen_server/dashboard/assets/dots-horizontal-otGBOSDJ.js +1 -0
- zenml/zen_server/dashboard/assets/flyte-Cj-xy_8I.svg +10 -0
- zenml/zen_server/dashboard/assets/form-schemas-BZqKBPBF.js +1 -0
- zenml/zen_server/dashboard/assets/gcp-CFtm4BA7.js +1 -0
- zenml/zen_server/dashboard/assets/hamza-NKKOZz1I.webp +0 -0
- zenml/zen_server/dashboard/assets/help-Cc9bBIJH.js +1 -0
- zenml/zen_server/dashboard/assets/index-CE0aQlv8.js +55 -0
- zenml/zen_server/dashboard/assets/index-CtdYkjUi.js +1 -0
- zenml/zen_server/dashboard/assets/index-CyBKZcpO.js +1 -0
- zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
- zenml/zen_server/dashboard/assets/index-Uu49AX48.js +1 -0
- zenml/zen_server/dashboard/assets/index-v6gQjDEo.js +1 -0
- zenml/zen_server/dashboard/assets/index.esm-Dy6Z9Ung.js +1 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-400-normal-BLGc9T1a.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-400-normal-ZzOtrSSW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-500-normal-D4Vwzodn.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-500-normal-DH2hs3aW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-600-normal-BGBWG807.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-600-normal-BuzJQFbW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-400-normal-BPnxn4xp.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-400-normal-Dc4VJyIJ.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-500-normal-BShVwWPj.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-500-normal-CUiC4oBV.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-600-normal-Bt9VVOA-.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-600-normal-CaqZN2hq.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-400-normal-BZzXV7-1.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-400-normal-DxZsaF_h.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-500-normal-CeQXL5ds.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-500-normal-d_eO-yCQ.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-600-normal-CwicyhtI.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-600-normal-Dhlb-90d.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-400-normal-Bput3-QP.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-400-normal-DCpCPQOf.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-500-normal-B6guLgqG.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-500-normal-M2hEX8vc.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-600-normal-C9WLioJ8.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-600-normal-Cnui8OiR.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-400-normal-BOOGhInR.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-400-normal-gitzw0hO.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-500-normal-D2bGa7uu.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-500-normal-deR1Tlfd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-600-normal-B5cFAncS.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-600-normal-D273HNI0.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-400-normal-C1t-h-pH.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-400-normal-hnt3BR84.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-500-normal-CIS2RHJS.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-500-normal-UMdmhHu2.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-600-normal-BnYJhD27.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-600-normal-CAF0vJDd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-400-normal-BUNmGMP1.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-500-normal-DQPw2Hwd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-600-normal-Cm6aH8_k.woff +0 -0
- zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
- zenml/zen_server/dashboard/assets/kubernetes-B2wmAJ1d.js +1 -0
- zenml/zen_server/dashboard/assets/layout-BtHBmE4w.js +1 -0
- zenml/zen_server/dashboard/assets/link-external-b9AXw_sW.js +1 -0
- zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
- zenml/zen_server/dashboard/assets/login-mutation-DNDVp_2H.js +1 -0
- zenml/zen_server/dashboard/assets/logs-WMSM52RF.js +1 -0
- zenml/zen_server/dashboard/assets/mcp-Cb1aMeoq.webp +0 -0
- zenml/zen_server/dashboard/assets/metaflow-weOkWNyT.svg +10 -0
- zenml/zen_server/dashboard/assets/not-found-Bmup4ctE.js +1 -0
- zenml/zen_server/dashboard/assets/package-C6uypY4h.js +1 -0
- zenml/zen_server/dashboard/assets/page--XLMzHrn.js +1 -0
- zenml/zen_server/dashboard/assets/page-ANYGfEUL.js +1 -0
- zenml/zen_server/dashboard/assets/page-B5Sr8pib.js +1 -0
- zenml/zen_server/dashboard/assets/page-BC27C_OI.js +2 -0
- zenml/zen_server/dashboard/assets/page-BNxYrN0q.js +1 -0
- zenml/zen_server/dashboard/assets/page-BYJfqgLN.js +1 -0
- zenml/zen_server/dashboard/assets/page-B_0XkV48.js +1 -0
- zenml/zen_server/dashboard/assets/page-BrmJp1Wt.js +1 -0
- zenml/zen_server/dashboard/assets/page-C2nU3Gxn.js +1 -0
- zenml/zen_server/dashboard/assets/page-C70wZtV2.js +1 -0
- zenml/zen_server/dashboard/assets/page-CHRn1fQm.js +1 -0
- zenml/zen_server/dashboard/assets/page-CWr96ZKN.js +1 -0
- zenml/zen_server/dashboard/assets/page-CXAbSyp9.js +1 -0
- zenml/zen_server/dashboard/assets/page-CaeI9ptC.js +1 -0
- zenml/zen_server/dashboard/assets/page-Cc8ZEuj4.js +1 -0
- zenml/zen_server/dashboard/assets/page-CltCNL0T.js +1 -0
- zenml/zen_server/dashboard/assets/page-CmlYj7Nl.js +1 -0
- zenml/zen_server/dashboard/assets/page-D6Ev5P8V.js +1 -0
- zenml/zen_server/dashboard/assets/page-D9Oh05fl.js +1 -0
- zenml/zen_server/dashboard/assets/page-DGlm1RVc.js +1 -0
- zenml/zen_server/dashboard/assets/page-DN4BVIOL.js +1 -0
- zenml/zen_server/dashboard/assets/page-Dif8CWyZ.js +1 -0
- zenml/zen_server/dashboard/assets/page-DlIi5ThM.js +1 -0
- zenml/zen_server/dashboard/assets/page-DoW7YxTu.js +1 -0
- zenml/zen_server/dashboard/assets/page-Dth9X1Ih.js +1 -0
- zenml/zen_server/dashboard/assets/page-DweqqCkF.js +1 -0
- zenml/zen_server/dashboard/assets/page-DyOJ_pq3.js +1 -0
- zenml/zen_server/dashboard/assets/page-Hn8q9iJZ.js +1 -0
- zenml/zen_server/dashboard/assets/page-IhckKFnD.js +6 -0
- zenml/zen_server/dashboard/assets/page-LyZ_l8vR.js +1 -0
- zenml/zen_server/dashboard/assets/page-PamGpk0j.js +1 -0
- zenml/zen_server/dashboard/assets/page-PxOWfKgF.js +2 -0
- zenml/zen_server/dashboard/assets/persist-DeXRG61d.js +1 -0
- zenml/zen_server/dashboard/assets/persist-vP0-Xl4f.js +1 -0
- zenml/zen_server/dashboard/assets/plus-tf1V2hTJ.js +1 -0
- zenml/zen_server/dashboard/assets/refresh-BjOeWlEq.js +1 -0
- zenml/zen_server/dashboard/assets/repos-video-D8kpu60k.svg +9 -0
- zenml/zen_server/dashboard/assets/rocket-DjT2cDvG.js +1 -0
- zenml/zen_server/dashboard/assets/service-DH_oUqQj.js +2 -0
- zenml/zen_server/dashboard/assets/settings_preview-0JLrRgHP.webp +0 -0
- zenml/zen_server/dashboard/assets/sharedSchema-Bw1_Wa7l.js +14 -0
- zenml/zen_server/dashboard/assets/stack-detail-query-B_0R_fd6.js +1 -0
- zenml/zen_server/dashboard/assets/stefan-B08Ftbba.webp +0 -0
- zenml/zen_server/dashboard/assets/templates-1S_8WeSK.webp +0 -0
- zenml/zen_server/dashboard/assets/tick-circle-BEX_Tp4v.js +1 -0
- zenml/zen_server/dashboard/assets/tour-cover-BYfeen6M.webp +0 -0
- zenml/zen_server/dashboard/assets/trash-arLUMWMS.js +1 -0
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-D9qYhfaN.js +1 -0
- zenml/zen_server/dashboard/assets/upgrade-form-CwRHBuXB.webp +0 -0
- zenml/zen_server/dashboard/assets/url-Dh93fvh0.js +1 -0
- zenml/zen_server/dashboard/assets/zod-BwEbpOxH.js +1 -0
- zenml/zen_server/dashboard/index.html +19 -1
- zenml/zen_server/deploy/__init__.py +7 -16
- zenml/zen_server/deploy/base_provider.py +49 -78
- zenml/zen_server/deploy/{local → daemon}/__init__.py +3 -3
- zenml/zen_server/deploy/{local/local_provider.py → daemon/daemon_provider.py} +48 -66
- zenml/zen_server/deploy/{local/local_zen_server.py → daemon/daemon_zen_server.py} +78 -62
- zenml/zen_server/deploy/deployer.py +94 -175
- zenml/zen_server/deploy/deployment.py +23 -17
- zenml/zen_server/deploy/docker/docker_provider.py +15 -31
- zenml/zen_server/deploy/docker/docker_zen_server.py +30 -35
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +3 -13
- zenml/zen_server/deploy/helm/templates/NOTES.txt +2 -8
- zenml/zen_server/deploy/helm/templates/_environment.tpl +129 -3
- zenml/zen_server/deploy/helm/templates/server-db-job.yaml +45 -18
- zenml/zen_server/deploy/helm/templates/server-db-pvc.yaml +25 -0
- zenml/zen_server/deploy/helm/templates/server-deployment.yaml +22 -6
- zenml/zen_server/deploy/helm/templates/server-secret.yaml +2 -12
- zenml/zen_server/deploy/helm/values.yaml +134 -21
- zenml/zen_server/exceptions.py +20 -1
- zenml/zen_server/feature_gate/__init__.py +13 -0
- zenml/zen_server/feature_gate/endpoint_utils.py +61 -0
- zenml/zen_server/feature_gate/feature_gate_interface.py +49 -0
- zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +125 -0
- zenml/zen_server/jwt.py +48 -31
- zenml/zen_server/rate_limit.py +200 -0
- zenml/zen_server/rbac/endpoint_utils.py +92 -9
- zenml/zen_server/rbac/models.py +21 -17
- zenml/zen_server/rbac/rbac_sql_zen_store.py +175 -0
- zenml/zen_server/rbac/utils.py +71 -30
- zenml/zen_server/rbac/zenml_cloud_rbac.py +13 -188
- zenml/zen_server/routers/actions_endpoints.py +324 -0
- zenml/zen_server/routers/artifact_version_endpoints.py +28 -2
- zenml/zen_server/routers/auth_endpoints.py +205 -110
- zenml/zen_server/routers/code_repositories_endpoints.py +1 -0
- zenml/zen_server/routers/devices_endpoints.py +56 -49
- zenml/zen_server/routers/event_source_endpoints.py +327 -0
- zenml/zen_server/routers/logs_endpoints.py +66 -0
- zenml/zen_server/routers/model_versions_endpoints.py +59 -0
- zenml/zen_server/routers/models_endpoints.py +8 -1
- zenml/zen_server/routers/pipeline_builds_endpoints.py +6 -1
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +35 -0
- zenml/zen_server/routers/pipelines_endpoints.py +19 -32
- zenml/zen_server/routers/plugin_endpoints.py +107 -0
- zenml/zen_server/routers/run_templates_endpoints.py +212 -0
- zenml/zen_server/routers/runs_endpoints.py +91 -32
- zenml/zen_server/routers/schedule_endpoints.py +1 -0
- zenml/zen_server/routers/secrets_endpoints.py +4 -2
- zenml/zen_server/routers/server_endpoints.py +186 -4
- zenml/zen_server/routers/service_connectors_endpoints.py +56 -0
- zenml/zen_server/routers/service_endpoints.py +180 -0
- zenml/zen_server/routers/stack_components_endpoints.py +2 -1
- zenml/zen_server/routers/stack_deployment_endpoints.py +164 -0
- zenml/zen_server/routers/steps_endpoints.py +21 -12
- zenml/zen_server/routers/triggers_endpoints.py +336 -0
- zenml/zen_server/routers/users_endpoints.py +280 -45
- zenml/zen_server/routers/webhook_endpoints.py +127 -0
- zenml/zen_server/routers/workspaces_endpoints.py +220 -185
- zenml/zen_server/secure_headers.py +120 -0
- zenml/{new → zen_server/template_execution}/__init__.py +1 -1
- zenml/zen_server/template_execution/runner_entrypoint_configuration.py +42 -0
- zenml/zen_server/template_execution/utils.py +474 -0
- zenml/zen_server/template_execution/workload_manager_interface.py +92 -0
- zenml/zen_server/utils.py +310 -74
- zenml/zen_server/zen_server_api.py +294 -52
- zenml/zen_stores/base_zen_store.py +71 -57
- zenml/zen_stores/migrations/alembic.py +22 -9
- zenml/zen_stores/migrations/env.py +2 -2
- zenml/zen_stores/migrations/utils.py +731 -0
- zenml/zen_stores/migrations/versions/0.21.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.21.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.22.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.23.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.30.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.31.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.31.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.32.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.32.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.33.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.34.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.35.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.35.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.36.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.36.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.37.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.38.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.39.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.39.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.41.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.42.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.42.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.43.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.1_release_0_45_1.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.4_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.5_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.6_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.46.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.46.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.47.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.50.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.51.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.52.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.53.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.53.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.54.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.54.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.55.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.55.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.3_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.4_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.5_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.3_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.4_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0.rc1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0.rc2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.2_release.py +23 -0
- 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/0.62.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.63.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.64.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.65.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.66.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.67.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.68.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.68.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.70.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.72.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/026d4577b6a0_add_code_path.py +39 -0
- zenml/zen_stores/migrations/versions/03742aa7fdd7_add_secrets.py +1 -0
- zenml/zen_stores/migrations/versions/0701da9951a0_added_service_table.py +94 -0
- zenml/zen_stores/migrations/versions/0b06faa59c93_add_service_connectors.py +1 -0
- zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
- zenml/zen_stores/migrations/versions/0e4735b23577_increase_pipeline_spec_field_length.py +1 -0
- zenml/zen_stores/migrations/versions/1041bc644e0d_remove_secrets_manager.py +6 -3
- zenml/zen_stores/migrations/versions/10a907dad202_delete_mlmd_tables.py +2 -1
- zenml/zen_stores/migrations/versions/14d687c8fa1c_rename_model_config_to_model_version.py +1 -0
- zenml/zen_stores/migrations/versions/19f27d5b234e_add_build_and_deployment_tables.py +1 -0
- zenml/zen_stores/migrations/versions/1a9a9d2a836d_admin_users.py +56 -0
- zenml/zen_stores/migrations/versions/1ac1b9c04da1_make_secrets_values_optional.py +1 -0
- zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +99 -0
- zenml/zen_stores/migrations/versions/1d74e596abb8_add_run_once_start_time_to_schedule.py +36 -0
- zenml/zen_stores/migrations/versions/1d8f30c54477_migrate_to_new_.py +124 -0
- zenml/zen_stores/migrations/versions/248dfd320b68_update_size_of_flavor_config_schema.py +1 -0
- zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
- zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
- zenml/zen_stores/migrations/versions/26b776ad583e_redesign_artifacts.py +9 -10
- zenml/zen_stores/migrations/versions/2d201872e23c_remove_db_dependency_loop.py +29 -0
- zenml/zen_stores/migrations/versions/37835ce041d2_optimizing_database.py +4 -3
- zenml/zen_stores/migrations/versions/389046140cad_data_versioning.py +1 -0
- zenml/zen_stores/migrations/versions/3944116bbd56_rename_project_to_workspace.py +1 -0
- zenml/zen_stores/migrations/versions/3b68abe58f44_add_model_watchtower_entities.py +1 -0
- zenml/zen_stores/migrations/versions/3c5a367730c2_add_environment_info_to_runs.py +1 -0
- zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +51 -0
- zenml/zen_stores/migrations/versions/43a86093b60e_add_labels_for_stack_components.py +1 -0
- zenml/zen_stores/migrations/versions/46506f72f0ed_add_server_settings.py +123 -0
- zenml/zen_stores/migrations/versions/479103df60b6_add_triggers.py +162 -0
- zenml/zen_stores/migrations/versions/4a3087070f4e_add_step_source_code.py +1 -0
- zenml/zen_stores/migrations/versions/4c41c0ca42db_add_code_repository_table.py +1 -0
- zenml/zen_stores/migrations/versions/4d688d8f7aff_rename_model_version_to_model.py +1 -0
- zenml/zen_stores/migrations/versions/4e1972485075_endpoint_artifact_deployment_artifact.py +1 -0
- zenml/zen_stores/migrations/versions/4f66af55fbb9_rename_model_config_model_to_model_.py +1 -0
- zenml/zen_stores/migrations/versions/5330ba58bf20_rename_tables_and_foreign_keys.py +8 -9
- zenml/zen_stores/migrations/versions/5994f9ad0489_introduce_role_permissions.py +4 -2
- zenml/zen_stores/migrations/versions/5cc3f41cf048_add_save_models_to_registry.py +1 -0
- zenml/zen_stores/migrations/versions/6119cd9b93c2_tags_table.py +1 -0
- zenml/zen_stores/migrations/versions/623a234c11f5_add_sdk_docs_url_to_flavors.py +1 -0
- zenml/zen_stores/migrations/versions/6917bce75069_add_pipeline_run_unique_constraint.py +5 -4
- zenml/zen_stores/migrations/versions/6a28c4fd0ef2_add_caching_info.py +1 -0
- zenml/zen_stores/migrations/versions/6f707b385dc1_fix_model_artifacts.py +1 -0
- zenml/zen_stores/migrations/versions/722392c91006_make_is_service_account_mandatory.py +1 -0
- zenml/zen_stores/migrations/versions/72675226b2de_unique_users.py +31 -0
- zenml/zen_stores/migrations/versions/72722dee4686_track_server_version.py +1 -0
- zenml/zen_stores/migrations/versions/7280c14811d6_use_text_type.py +1 -0
- zenml/zen_stores/migrations/versions/728c6369cfaa_add_name_column_to_input_artifact_pk.py +4 -2
- zenml/zen_stores/migrations/versions/729263e47b55_fix_external_input_artifacts.py +1 -0
- zenml/zen_stores/migrations/versions/743ec82b1b3c_update_size_of_build_images.py +3 -2
- zenml/zen_stores/migrations/versions/7500f434b71c_remove_shared_columns.py +4 -2
- zenml/zen_stores/migrations/versions/76a7b9451ccd_add_build_template_deployment_id.py +52 -0
- zenml/zen_stores/migrations/versions/7834208cc3f6_artifact_project_scoping.py +9 -7
- zenml/zen_stores/migrations/versions/7b651bf6822e_track_secrets_in_db.py +7 -7
- zenml/zen_stores/migrations/versions/7d1919bb1ef0_add_run_templates.py +100 -0
- zenml/zen_stores/migrations/versions/7e4a481d17f7_add_identity_table.py +3 -2
- zenml/zen_stores/migrations/versions/7f603e583dd7_fixed_migration.py +2 -1
- zenml/zen_stores/migrations/versions/86fa52918b54_remove_teams_and_roles.py +1 -0
- zenml/zen_stores/migrations/versions/8a64fbfecda0_add_num_outputs_to_run_step.py +1 -0
- zenml/zen_stores/migrations/versions/8ed03137cacc_polymorthic_run_metadata.py +1 -0
- zenml/zen_stores/migrations/versions/904464ea4041_add_pipeline_model_run_unique_constraints.py +192 -0
- zenml/zen_stores/migrations/versions/909550c7c4da_remove_user_hub_token.py +36 -0
- zenml/zen_stores/migrations/versions/93cbda80a732_add_service_accounts.py +1 -0
- zenml/zen_stores/migrations/versions/979eff8fc4b1_add_code_repo_description_and_logo_url.py +1 -0
- zenml/zen_stores/migrations/versions/9971237fa937_artifact_visualizations.py +1 -0
- zenml/zen_stores/migrations/versions/9d8020441014_increase_step_configuration_length.py +1 -0
- zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
- zenml/zen_stores/migrations/versions/a39c4184c8ce_remove_secrets_manager_flavors.py +3 -2
- zenml/zen_stores/migrations/versions/a91762e6be36_artifact_version_table.py +5 -4
- zenml/zen_stores/migrations/versions/ade72effebaf_added_logs_table.py +1 -0
- zenml/zen_stores/migrations/versions/alembic_start.py +2 -1
- zenml/zen_stores/migrations/versions/b4eccf34dfa3_add_hub_token_to_user_model.py +1 -0
- zenml/zen_stores/migrations/versions/b4fca5241eea_migrate_onboarding_state.py +167 -0
- zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +33 -0
- zenml/zen_stores/migrations/versions/b59aa68fdb1f_simplify_pipelines.py +139 -0
- zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
- zenml/zen_stores/migrations/versions/bf2120261b5a_add_configured_model_version_id.py +74 -0
- zenml/zen_stores/migrations/versions/c1b18cec3a48_increase_length_on_flavor_config_schema.py +1 -0
- zenml/zen_stores/migrations/versions/c22561cbb3a9_add_artifact_unique_constraints.py +86 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
- zenml/zen_stores/migrations/versions/cc9894cb58aa_add_user_metadata.py +41 -0
- zenml/zen_stores/migrations/versions/ccd68b7825ae_add_status_to_pipeline_and_step_run.py +1 -0
- zenml/zen_stores/migrations/versions/d02b3d3464cf_add_orchestrator_run_id_column.py +1 -0
- zenml/zen_stores/migrations/versions/d26471b6fe8f_update_build_filtering.py +1 -0
- zenml/zen_stores/migrations/versions/d7b3acf9aa46_create_schedule_table.py +1 -0
- zenml/zen_stores/migrations/versions/e1d66d91a099_add_stack_and_component_spec_paths_to_.py +1 -0
- zenml/zen_stores/migrations/versions/e5225281b4d3_add_connector_skew_tolerance.py +1 -0
- zenml/zen_stores/migrations/versions/e65aa6708ff7_pipeline_versioning.py +1 -0
- zenml/zen_stores/migrations/versions/ec0d785ca296_create_run_metadata_table.py +1 -0
- zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +119 -0
- zenml/zen_stores/migrations/versions/f3b3964e3a0f_add_oauth_devices.py +1 -0
- zenml/zen_stores/migrations/versions/f49904a80aa7_increase_length_of_artifact_table_sources.py +1 -0
- zenml/zen_stores/migrations/versions/fbd7f18ced1e_increase_step_run_field_lengths.py +5 -4
- zenml/zen_stores/rest_zen_store.py +1315 -304
- zenml/zen_stores/schemas/__init__.py +22 -3
- zenml/zen_stores/schemas/action_schemas.py +192 -0
- zenml/zen_stores/schemas/api_key_schemas.py +23 -10
- zenml/zen_stores/schemas/artifact_schemas.py +112 -49
- zenml/zen_stores/schemas/artifact_visualization_schemas.py +17 -8
- zenml/zen_stores/schemas/base_schemas.py +27 -0
- zenml/zen_stores/schemas/code_repository_schemas.py +25 -10
- zenml/zen_stores/schemas/component_schemas.py +74 -11
- zenml/zen_stores/schemas/constants.py +16 -0
- zenml/zen_stores/schemas/device_schemas.py +29 -15
- zenml/zen_stores/schemas/event_source_schemas.py +188 -0
- zenml/zen_stores/schemas/flavor_schemas.py +19 -9
- zenml/zen_stores/schemas/logs_schemas.py +12 -6
- zenml/zen_stores/schemas/model_schemas.py +192 -139
- zenml/zen_stores/schemas/pipeline_build_schemas.py +16 -16
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +58 -17
- zenml/zen_stores/schemas/pipeline_run_schemas.py +170 -35
- zenml/zen_stores/schemas/pipeline_schemas.py +51 -33
- zenml/zen_stores/schemas/run_metadata_schemas.py +28 -78
- zenml/zen_stores/schemas/run_template_schemas.py +267 -0
- zenml/zen_stores/schemas/schedule_schema.py +15 -5
- zenml/zen_stores/schemas/secret_schemas.py +18 -10
- zenml/zen_stores/schemas/server_settings_schemas.py +129 -0
- zenml/zen_stores/schemas/service_connector_schemas.py +13 -6
- zenml/zen_stores/schemas/service_schemas.py +258 -0
- zenml/zen_stores/schemas/stack_schemas.py +23 -6
- zenml/zen_stores/schemas/step_run_schemas.py +132 -41
- zenml/zen_stores/schemas/tag_schemas.py +31 -50
- zenml/zen_stores/schemas/trigger_schemas.py +316 -0
- zenml/zen_stores/schemas/user_schemas.py +66 -23
- zenml/zen_stores/schemas/utils.py +112 -0
- zenml/zen_stores/schemas/workspace_schemas.py +36 -19
- zenml/zen_stores/secrets_stores/aws_secrets_store.py +41 -32
- zenml/zen_stores/secrets_stores/azure_secrets_store.py +20 -23
- zenml/zen_stores/secrets_stores/base_secrets_store.py +80 -12
- zenml/zen_stores/secrets_stores/gcp_secrets_store.py +42 -33
- zenml/zen_stores/secrets_stores/hashicorp_secrets_store.py +7 -11
- zenml/zen_stores/secrets_stores/secrets_store_interface.py +1 -0
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +15 -8
- zenml/zen_stores/secrets_stores/sql_secrets_store.py +8 -9
- zenml/zen_stores/sql_zen_store.py +4062 -799
- zenml/zen_stores/template_utils.py +263 -0
- zenml/zen_stores/zen_store_interface.py +614 -44
- zenml_nightly-0.72.0.dev20250115.dist-info/METADATA +484 -0
- zenml_nightly-0.72.0.dev20250115.dist-info/RECORD +1292 -0
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250115.dist-info}/WHEEL +1 -1
- CLA.md +0 -110
- CODE-OF-CONDUCT.md +0 -132
- CONTRIBUTING.md +0 -260
- README.md +0 -304
- RELEASE_NOTES.md +0 -3919
- ROADMAP.md +0 -5
- SECURITY.md +0 -15
- zenml/_hub/client.py +0 -285
- zenml/_hub/constants.py +0 -21
- zenml/_hub/utils.py +0 -80
- zenml/api.py +0 -61
- zenml/cli/hub.py +0 -1115
- zenml/cli/stack_recipes.py +0 -469
- zenml/integrations/gcp/google_cloud_function.py +0 -187
- zenml/integrations/gcp/google_cloud_scheduler.py +0 -83
- zenml/integrations/gcp/orchestrators/vertex_scheduler/main.py +0 -91
- zenml/integrations/gcp/orchestrators/vertex_scheduler/requirements.txt +0 -2
- zenml/integrations/kserve/__init__.py +0 -57
- zenml/integrations/kserve/custom_deployer/zenml_custom_model.py +0 -175
- zenml/integrations/kserve/flavors/kserve_model_deployer_flavor.py +0 -137
- zenml/integrations/kserve/model_deployers/kserve_model_deployer.py +0 -1003
- zenml/integrations/kserve/secret_schemas/secret_schemas.py +0 -65
- zenml/integrations/kserve/services/kserve_deployment.py +0 -596
- zenml/integrations/kserve/steps/__init__.py +0 -22
- zenml/integrations/kserve/steps/kserve_deployer.py +0 -472
- zenml/integrations/kserve/steps/kserve_step_utils.py +0 -293
- zenml/integrations/kubeflow/utils.py +0 -96
- zenml/lineage_graph/lineage_graph.py +0 -244
- zenml/lineage_graph/node/artifact_node.py +0 -52
- zenml/lineage_graph/node/step_node.py +0 -41
- zenml/models/v2/base/internal.py +0 -37
- zenml/models/v2/base/update.py +0 -40
- zenml/models/v2/misc/hub_plugin_models.py +0 -79
- zenml/new/pipelines/deserialization_utils.py +0 -291
- zenml/new/pipelines/model_utils.py +0 -72
- zenml/new/pipelines/pipeline_decorator.py +0 -109
- zenml/new/steps/step_decorator.py +0 -160
- zenml/pipelines/base_pipeline.py +0 -274
- zenml/post_execution/pipeline.py +0 -58
- zenml/post_execution/pipeline_run.py +0 -55
- zenml/services/service_registry.py +0 -214
- zenml/services/terraform/__init__.py +0 -14
- zenml/services/terraform/terraform_service.py +0 -441
- zenml/steps/step_environment.py +0 -108
- zenml/steps/step_output.py +0 -36
- zenml/utils/mlstacks_utils.py +0 -635
- zenml/utils/terraform_utils.py +0 -42
- zenml/zen_server/dashboard/_redirects +0 -1
- zenml/zen_server/dashboard/asset-manifest.json +0 -131
- zenml/zen_server/dashboard/manifest.json +0 -25
- zenml/zen_server/dashboard/precache-manifest.c139638dcc4d9d3425353266447a2fad.js +0 -462
- zenml/zen_server/dashboard/robots.txt +0 -2
- zenml/zen_server/dashboard/service-worker.js +0 -39
- zenml/zen_server/dashboard/static/css/2.5b37d44a.chunk.css +0 -16
- zenml/zen_server/dashboard/static/css/2.5b37d44a.chunk.css.map +0 -1
- zenml/zen_server/dashboard/static/css/main.77e46c35.chunk.css +0 -2
- zenml/zen_server/dashboard/static/css/main.77e46c35.chunk.css.map +0 -1
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js +0 -3
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js.LICENSE.txt +0 -95
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js.map +0 -1
- zenml/zen_server/dashboard/static/js/main.270838b4.chunk.js +0 -2
- zenml/zen_server/dashboard/static/js/main.270838b4.chunk.js.map +0 -1
- zenml/zen_server/dashboard/static/js/runtime-main.bfca2edd.js +0 -2
- zenml/zen_server/dashboard/static/js/runtime-main.bfca2edd.js.map +0 -1
- zenml/zen_server/dashboard/static/media/AlertTriangle.28aee535.svg +0 -5
- zenml/zen_server/dashboard/static/media/ArrowSquareOut.abfb9bc7.svg +0 -5
- zenml/zen_server/dashboard/static/media/Back.86c23a22.svg +0 -4
- zenml/zen_server/dashboard/static/media/BookOpen.5cb101ff.svg +0 -4
- zenml/zen_server/dashboard/static/media/BoundingBox.1eb98717.svg +0 -10
- zenml/zen_server/dashboard/static/media/Burger.9b1c67d7.svg +0 -3
- zenml/zen_server/dashboard/static/media/Cached.2381fb8d.svg +0 -1
- zenml/zen_server/dashboard/static/media/Calendar.356e11c7.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChartBarHorizontal.0247447b.svg +0 -6
- zenml/zen_server/dashboard/static/media/ChartLine.0d79e18d.svg +0 -4
- zenml/zen_server/dashboard/static/media/ChatDots.2e1c9211.svg +0 -6
- zenml/zen_server/dashboard/static/media/Check.dad6beb2.svg +0 -3
- zenml/zen_server/dashboard/static/media/CheckCircleFilled.c19566d0.svg +0 -3
- zenml/zen_server/dashboard/static/media/Checkbox.af50e31e.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronDown.f860ce32.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronDownLight.6642d756.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronLeft.f6edfcdb.svg +0 -3
- zenml/zen_server/dashboard/static/media/CircleCheck.f98fd6ca.svg +0 -1
- zenml/zen_server/dashboard/static/media/Clock.ffc9de95.svg +0 -3
- zenml/zen_server/dashboard/static/media/Close.74e9efbc.svg +0 -5
- zenml/zen_server/dashboard/static/media/CloseWithBorder.6960930a.svg +0 -3
- zenml/zen_server/dashboard/static/media/CloseWithoutBorder.cd6f71df.svg +0 -3
- zenml/zen_server/dashboard/static/media/CloudArrowUp.0aecb235.svg +0 -6
- zenml/zen_server/dashboard/static/media/Code.ef0f33b5.svg +0 -3
- zenml/zen_server/dashboard/static/media/Config.0be63f8a.svg +0 -1
- zenml/zen_server/dashboard/static/media/Connector.9fd46ef1.svg +0 -10
- zenml/zen_server/dashboard/static/media/Copy.36e2112a.svg +0 -1
- zenml/zen_server/dashboard/static/media/Dashboard.d05787e0.svg +0 -3
- zenml/zen_server/dashboard/static/media/Data.b1c3b5f8.svg +0 -3
- zenml/zen_server/dashboard/static/media/Delete.3c361b28.svg +0 -8
- zenml/zen_server/dashboard/static/media/Docs.7541d478.svg +0 -7
- zenml/zen_server/dashboard/static/media/Download.fba04d87.svg +0 -5
- zenml/zen_server/dashboard/static/media/Edit.490eb294.svg +0 -6
- zenml/zen_server/dashboard/static/media/EmptyRightArrow.23749d01.svg +0 -3
- zenml/zen_server/dashboard/static/media/Example.6396cd37.svg +0 -5
- zenml/zen_server/dashboard/static/media/Extension.1394cd4a.svg +0 -3
- zenml/zen_server/dashboard/static/media/Eye.d9e4ee62.svg +0 -4
- zenml/zen_server/dashboard/static/media/Failed.0213c1a0.svg +0 -1
- zenml/zen_server/dashboard/static/media/FileText.1f15bacd.svg +0 -7
- zenml/zen_server/dashboard/static/media/Filter.ab6b9c0d.svg +0 -3
- zenml/zen_server/dashboard/static/media/Folders.12b29887.svg +0 -5
- zenml/zen_server/dashboard/static/media/FunnelFill.6df4c143.svg +0 -3
- zenml/zen_server/dashboard/static/media/GitCommit.7dd9c2aa.svg +0 -5
- zenml/zen_server/dashboard/static/media/GitHub_Logo.cefc2023.png +0 -0
- zenml/zen_server/dashboard/static/media/Graph.2c63a892.svg +0 -11
- zenml/zen_server/dashboard/static/media/History.08329240.svg +0 -3
- zenml/zen_server/dashboard/static/media/Home.0843b0d5.svg +0 -3
- zenml/zen_server/dashboard/static/media/ImageBuilder.ea762d9c.svg +0 -6
- zenml/zen_server/dashboard/static/media/InProgress.304a0edc.svg +0 -1
- zenml/zen_server/dashboard/static/media/Info.9fe10c5c.svg +0 -3
- zenml/zen_server/dashboard/static/media/KeyboardReturn.491afbe3.svg +0 -3
- zenml/zen_server/dashboard/static/media/Link.72bbb55d.svg +0 -4
- zenml/zen_server/dashboard/static/media/Lock.30f5e1fe.svg +0 -5
- zenml/zen_server/dashboard/static/media/Lock2.a769ea52.svg +0 -3
- zenml/zen_server/dashboard/static/media/LockKey.92f21621.svg +0 -6
- zenml/zen_server/dashboard/static/media/Logs.8bf4d005.svg +0 -5
- zenml/zen_server/dashboard/static/media/MinusCircle.4188f418.svg +0 -4
- zenml/zen_server/dashboard/static/media/ModelRegistry.f0de050a.svg +0 -6
- zenml/zen_server/dashboard/static/media/MultiUser.a2ba7c67.svg +0 -10
- zenml/zen_server/dashboard/static/media/PaginationFirst.92628634.svg +0 -4
- zenml/zen_server/dashboard/static/media/PaginationLast.00d3c732.svg +0 -4
- zenml/zen_server/dashboard/static/media/PaginationNext.86158845.svg +0 -3
- zenml/zen_server/dashboard/static/media/PaginationPrev.60c18a88.svg +0 -3
- zenml/zen_server/dashboard/static/media/Pen.f2d831d4.svg +0 -6
- zenml/zen_server/dashboard/static/media/PhotoCamera.179d6d4c.svg +0 -3
- zenml/zen_server/dashboard/static/media/Pipeline.30d298b0.svg +0 -7
- zenml/zen_server/dashboard/static/media/Plus.5aa1c16b.svg +0 -3
- zenml/zen_server/dashboard/static/media/PlusCircle.92d860dd.svg +0 -5
- zenml/zen_server/dashboard/static/media/Repositories.71a36b8c.svg +0 -3
- zenml/zen_server/dashboard/static/media/RightArrow.f30d3871.svg +0 -29
- zenml/zen_server/dashboard/static/media/Rocket.63bf7b9d.svg +0 -3
- zenml/zen_server/dashboard/static/media/RocketLaunch.1bff2b59.svg +0 -6
- zenml/zen_server/dashboard/static/media/Rubik-Medium.c87313aa.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Rubik-Regular.b3d0902b.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Run.daec4fb2.svg +0 -6
- zenml/zen_server/dashboard/static/media/Search.d1afcce5.svg +0 -4
- zenml/zen_server/dashboard/static/media/Settings.59ca73ae.svg +0 -4
- zenml/zen_server/dashboard/static/media/Share2.46c3ff66.svg +0 -3
- zenml/zen_server/dashboard/static/media/SignOut.6aa718c5.svg +0 -3
- zenml/zen_server/dashboard/static/media/SimplePlus.5cf7ec20.svg +0 -3
- zenml/zen_server/dashboard/static/media/SingleUser.bef3a095.svg +0 -4
- zenml/zen_server/dashboard/static/media/SourceCodePro-Regular.b484b32f.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Stack.19b604ac.svg +0 -5
- zenml/zen_server/dashboard/static/media/StackComponent.b1ba90b5.svg +0 -4
- zenml/zen_server/dashboard/static/media/Star.f0c25022.svg +0 -9
- zenml/zen_server/dashboard/static/media/StarOutline.94ca8cd9.svg +0 -3
- zenml/zen_server/dashboard/static/media/Storefront.4b4796fe.svg +0 -3
- zenml/zen_server/dashboard/static/media/Stream.543e3039.svg +0 -3
- zenml/zen_server/dashboard/static/media/SupportAgent.510ddf1f.svg +0 -8
- zenml/zen_server/dashboard/static/media/Table.77033750.svg +0 -6
- zenml/zen_server/dashboard/static/media/Tool.d5785486.svg +0 -3
- zenml/zen_server/dashboard/static/media/UserPlus.741a99d7.svg +0 -6
- zenml/zen_server/dashboard/static/media/Verified.0625b2a0.svg +0 -3
- zenml/zen_server/dashboard/static/media/addNew.4fb6c939.svg +0 -8
- zenml/zen_server/dashboard/static/media/arrowClose.cbd53f3f.svg +0 -3
- zenml/zen_server/dashboard/static/media/arrowOpen.6ceef0af.svg +0 -3
- zenml/zen_server/dashboard/static/media/check_small.30bc0138.svg +0 -3
- zenml/zen_server/dashboard/static/media/circleArrowSideClose.98d6013e.svg +0 -18
- zenml/zen_server/dashboard/static/media/circleArrowSideOpen.63653df6.svg +0 -18
- zenml/zen_server/dashboard/static/media/image.104fd14b.png +0 -0
- zenml/zen_server/dashboard/static/media/imageAddIcon.e83004a9.svg +0 -7
- zenml/zen_server/dashboard/static/media/logo.93333e5c.svg +0 -1
- zenml/zen_server/dashboard/static/media/logo_small.4204397d.svg +0 -3
- zenml/zen_server/dashboard/static/media/logo_white.d4b4414e.svg +0 -20
- zenml/zen_server/dashboard/static/media/notConnected.5e2c8ea7.svg +0 -8
- zenml/zen_server/dashboard/static/media/plugin-fallback.72c294e6.svg +0 -6
- zenml/zen_server/dashboard/static/media/share.bcd998b0.svg +0 -5
- zenml/zen_server/dashboard/static/media/stars.08a9b19a.svg +0 -8
- zenml/zen_server/deploy/terraform/__init__.py +0 -41
- zenml/zen_server/deploy/terraform/providers/__init__.py +0 -14
- zenml/zen_server/deploy/terraform/providers/aws_provider.py +0 -61
- zenml/zen_server/deploy/terraform/providers/azure_provider.py +0 -59
- zenml/zen_server/deploy/terraform/providers/gcp_provider.py +0 -59
- zenml/zen_server/deploy/terraform/providers/terraform_provider.py +0 -332
- zenml/zen_server/deploy/terraform/recipes/aws/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/aws/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/aws/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/aws/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/aws/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/aws/sql.tf +0 -62
- zenml/zen_server/deploy/terraform/recipes/aws/terraform.tf +0 -44
- zenml/zen_server/deploy/terraform/recipes/aws/variables.tf +0 -179
- zenml/zen_server/deploy/terraform/recipes/aws/vpc.tf +0 -47
- zenml/zen_server/deploy/terraform/recipes/aws/zen_server.tf +0 -111
- zenml/zen_server/deploy/terraform/recipes/azure/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/azure/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/azure/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/azure/key_vault.tf +0 -73
- zenml/zen_server/deploy/terraform/recipes/azure/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/azure/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/azure/rg.tf +0 -36
- zenml/zen_server/deploy/terraform/recipes/azure/sql.tf +0 -65
- zenml/zen_server/deploy/terraform/recipes/azure/terraform.tf +0 -52
- zenml/zen_server/deploy/terraform/recipes/azure/variables.tf +0 -188
- zenml/zen_server/deploy/terraform/recipes/azure/zen_server.tf +0 -111
- zenml/zen_server/deploy/terraform/recipes/gcp/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/gcp/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/gcp/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/gcp/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/gcp/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/gcp/sql.tf +0 -64
- zenml/zen_server/deploy/terraform/recipes/gcp/terraform.tf +0 -44
- zenml/zen_server/deploy/terraform/recipes/gcp/variables.tf +0 -183
- zenml/zen_server/deploy/terraform/recipes/gcp/zen_server.tf +0 -122
- zenml/zen_server/deploy/terraform/terraform_zen_server.py +0 -255
- zenml/zen_server/routers/run_metadata_endpoints.py +0 -97
- zenml_nightly-0.55.0.dev20240124.dist-info/METADATA +0 -438
- zenml_nightly-0.55.0.dev20240124.dist-info/RECORD +0 -1072
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250115.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250115.dist-info}/entry_points.txt +0 -0
@@ -12,9 +12,11 @@
|
|
12
12
|
# or implied. See the License for the specific language governing
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""REST Zen Store implementation."""
|
15
|
+
|
15
16
|
import os
|
16
17
|
import re
|
17
|
-
from
|
18
|
+
from datetime import datetime
|
19
|
+
from pathlib import Path
|
18
20
|
from typing import (
|
19
21
|
Any,
|
20
22
|
ClassVar,
|
@@ -31,14 +33,23 @@ from uuid import UUID
|
|
31
33
|
|
32
34
|
import requests
|
33
35
|
import urllib3
|
34
|
-
from pydantic import
|
36
|
+
from pydantic import (
|
37
|
+
BaseModel,
|
38
|
+
ConfigDict,
|
39
|
+
Field,
|
40
|
+
ValidationError,
|
41
|
+
field_validator,
|
42
|
+
model_validator,
|
43
|
+
)
|
35
44
|
from requests.adapters import HTTPAdapter, Retry
|
36
45
|
|
37
46
|
import zenml
|
38
47
|
from zenml.analytics import source_context
|
39
48
|
from zenml.config.global_config import GlobalConfiguration
|
49
|
+
from zenml.config.pipeline_run_configuration import PipelineRunConfiguration
|
40
50
|
from zenml.config.store_config import StoreConfiguration
|
41
51
|
from zenml.constants import (
|
52
|
+
ACTIONS,
|
42
53
|
API,
|
43
54
|
API_KEY_ROTATE,
|
44
55
|
API_KEYS,
|
@@ -46,13 +57,17 @@ from zenml.constants import (
|
|
46
57
|
ARTIFACT_VERSIONS,
|
47
58
|
ARTIFACT_VISUALIZATIONS,
|
48
59
|
ARTIFACTS,
|
60
|
+
BATCH,
|
49
61
|
CODE_REFERENCES,
|
50
62
|
CODE_REPOSITORIES,
|
63
|
+
CONFIG,
|
51
64
|
CURRENT_USER,
|
65
|
+
DEACTIVATE,
|
52
66
|
DEFAULT_HTTP_TIMEOUT,
|
53
67
|
DEVICES,
|
54
68
|
DISABLE_CLIENT_SERVER_MISMATCH_WARNING,
|
55
69
|
ENV_ZENML_DISABLE_CLIENT_SERVER_MISMATCH_WARNING,
|
70
|
+
EVENT_SOURCES,
|
56
71
|
FLAVORS,
|
57
72
|
GET_OR_CREATE,
|
58
73
|
INFO,
|
@@ -66,36 +81,58 @@ from zenml.constants import (
|
|
66
81
|
PIPELINE_DEPLOYMENTS,
|
67
82
|
PIPELINES,
|
68
83
|
RUN_METADATA,
|
84
|
+
RUN_TEMPLATES,
|
69
85
|
RUNS,
|
70
86
|
SCHEDULES,
|
71
87
|
SECRETS,
|
72
88
|
SECRETS_BACKUP,
|
73
89
|
SECRETS_OPERATIONS,
|
74
90
|
SECRETS_RESTORE,
|
91
|
+
SERVER_SETTINGS,
|
75
92
|
SERVICE_ACCOUNTS,
|
76
93
|
SERVICE_CONNECTOR_CLIENT,
|
77
94
|
SERVICE_CONNECTOR_RESOURCES,
|
78
95
|
SERVICE_CONNECTOR_TYPES,
|
79
96
|
SERVICE_CONNECTOR_VERIFY,
|
97
|
+
SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
|
80
98
|
SERVICE_CONNECTORS,
|
99
|
+
SERVICES,
|
100
|
+
STACK,
|
81
101
|
STACK_COMPONENTS,
|
102
|
+
STACK_DEPLOYMENT,
|
82
103
|
STACKS,
|
83
104
|
STEPS,
|
84
105
|
TAGS,
|
106
|
+
TRIGGER_EXECUTIONS,
|
107
|
+
TRIGGERS,
|
85
108
|
USERS,
|
86
109
|
VERSION_1,
|
87
110
|
WORKSPACES,
|
88
111
|
)
|
89
112
|
from zenml.enums import (
|
113
|
+
APITokenType,
|
90
114
|
OAuthGrantTypes,
|
115
|
+
StackDeploymentProvider,
|
91
116
|
StoreType,
|
92
117
|
)
|
93
118
|
from zenml.exceptions import (
|
94
119
|
AuthorizationException,
|
120
|
+
CredentialsNotValid,
|
121
|
+
MethodNotAllowedError,
|
95
122
|
)
|
96
123
|
from zenml.io import fileio
|
97
124
|
from zenml.logger import get_logger
|
125
|
+
from zenml.login.credentials import APIToken
|
126
|
+
from zenml.login.credentials_store import get_credentials_store
|
127
|
+
from zenml.login.pro.utils import (
|
128
|
+
get_troubleshooting_instructions,
|
129
|
+
is_zenml_pro_server_url,
|
130
|
+
)
|
98
131
|
from zenml.models import (
|
132
|
+
ActionFilter,
|
133
|
+
ActionRequest,
|
134
|
+
ActionResponse,
|
135
|
+
ActionUpdate,
|
99
136
|
APIKeyFilter,
|
100
137
|
APIKeyRequest,
|
101
138
|
APIKeyResponse,
|
@@ -111,8 +148,8 @@ from zenml.models import (
|
|
111
148
|
ArtifactVersionUpdate,
|
112
149
|
ArtifactVisualizationResponse,
|
113
150
|
BaseFilter,
|
151
|
+
BaseIdentifiedResponse,
|
114
152
|
BaseRequest,
|
115
|
-
BaseResponse,
|
116
153
|
CodeReferenceResponse,
|
117
154
|
CodeRepositoryFilter,
|
118
155
|
CodeRepositoryRequest,
|
@@ -122,6 +159,11 @@ from zenml.models import (
|
|
122
159
|
ComponentRequest,
|
123
160
|
ComponentResponse,
|
124
161
|
ComponentUpdate,
|
162
|
+
DeployedStack,
|
163
|
+
EventSourceFilter,
|
164
|
+
EventSourceRequest,
|
165
|
+
EventSourceResponse,
|
166
|
+
EventSourceUpdate,
|
125
167
|
FlavorFilter,
|
126
168
|
FlavorRequest,
|
127
169
|
FlavorResponse,
|
@@ -144,6 +186,7 @@ from zenml.models import (
|
|
144
186
|
OAuthDeviceFilter,
|
145
187
|
OAuthDeviceResponse,
|
146
188
|
OAuthDeviceUpdate,
|
189
|
+
OAuthTokenResponse,
|
147
190
|
Page,
|
148
191
|
PipelineBuildFilter,
|
149
192
|
PipelineBuildRequest,
|
@@ -159,9 +202,11 @@ from zenml.models import (
|
|
159
202
|
PipelineRunResponse,
|
160
203
|
PipelineRunUpdate,
|
161
204
|
PipelineUpdate,
|
162
|
-
RunMetadataFilter,
|
163
205
|
RunMetadataRequest,
|
164
|
-
|
206
|
+
RunTemplateFilter,
|
207
|
+
RunTemplateRequest,
|
208
|
+
RunTemplateResponse,
|
209
|
+
RunTemplateUpdate,
|
165
210
|
ScheduleFilter,
|
166
211
|
ScheduleRequest,
|
167
212
|
ScheduleResponse,
|
@@ -171,6 +216,8 @@ from zenml.models import (
|
|
171
216
|
SecretResponse,
|
172
217
|
SecretUpdate,
|
173
218
|
ServerModel,
|
219
|
+
ServerSettingsResponse,
|
220
|
+
ServerSettingsUpdate,
|
174
221
|
ServiceAccountFilter,
|
175
222
|
ServiceAccountRequest,
|
176
223
|
ServiceAccountResponse,
|
@@ -181,6 +228,12 @@ from zenml.models import (
|
|
181
228
|
ServiceConnectorResponse,
|
182
229
|
ServiceConnectorTypeModel,
|
183
230
|
ServiceConnectorUpdate,
|
231
|
+
ServiceFilter,
|
232
|
+
ServiceRequest,
|
233
|
+
ServiceResponse,
|
234
|
+
ServiceUpdate,
|
235
|
+
StackDeploymentConfig,
|
236
|
+
StackDeploymentInfo,
|
184
237
|
StackFilter,
|
185
238
|
StackRequest,
|
186
239
|
StackResponse,
|
@@ -193,6 +246,12 @@ from zenml.models import (
|
|
193
246
|
TagRequest,
|
194
247
|
TagResponse,
|
195
248
|
TagUpdate,
|
249
|
+
TriggerExecutionFilter,
|
250
|
+
TriggerExecutionResponse,
|
251
|
+
TriggerFilter,
|
252
|
+
TriggerRequest,
|
253
|
+
TriggerResponse,
|
254
|
+
TriggerUpdate,
|
196
255
|
UserFilter,
|
197
256
|
UserRequest,
|
198
257
|
UserResponse,
|
@@ -209,6 +268,7 @@ from zenml.service_connectors.service_connector_registry import (
|
|
209
268
|
from zenml.utils.networking_utils import (
|
210
269
|
replace_localhost_with_internal_hostname,
|
211
270
|
)
|
271
|
+
from zenml.utils.pydantic_utils import before_validator_handler
|
212
272
|
from zenml.zen_server.exceptions import exception_from_response
|
213
273
|
from zenml.zen_stores.base_zen_store import BaseZenStore
|
214
274
|
|
@@ -219,7 +279,7 @@ Json = Union[Dict[str, Any], List[Any], str, int, float, bool, None]
|
|
219
279
|
|
220
280
|
|
221
281
|
AnyRequest = TypeVar("AnyRequest", bound=BaseRequest)
|
222
|
-
AnyResponse = TypeVar("AnyResponse", bound=
|
282
|
+
AnyResponse = TypeVar("AnyResponse", bound=BaseIdentifiedResponse) # type: ignore[type-arg]
|
223
283
|
AnyWorkspaceScopedRequest = TypeVar(
|
224
284
|
"AnyWorkspaceScopedRequest",
|
225
285
|
bound=WorkspaceScopedRequest,
|
@@ -234,10 +294,10 @@ class RestZenStoreConfiguration(StoreConfiguration):
|
|
234
294
|
username: The username to use to connect to the Zen server.
|
235
295
|
password: The password to use to connect to the Zen server.
|
236
296
|
api_key: The service account API key to use to connect to the Zen
|
237
|
-
server.
|
238
|
-
|
239
|
-
|
240
|
-
|
297
|
+
server. This is only set if the API key is configured explicitly via
|
298
|
+
environment variables or the ZenML global configuration file. API
|
299
|
+
keys configured via the CLI are stored in the credentials store
|
300
|
+
instead.
|
241
301
|
verify_ssl: Either a boolean, in which case it controls whether we
|
242
302
|
verify the server's TLS certificate, or a string, in which case it
|
243
303
|
must be a path to a CA bundle to use or the CA bundle value itself.
|
@@ -247,40 +307,13 @@ class RestZenStoreConfiguration(StoreConfiguration):
|
|
247
307
|
|
248
308
|
type: StoreType = StoreType.REST
|
249
309
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
api_token: Optional[str] = None
|
254
|
-
verify_ssl: Union[bool, str] = True
|
310
|
+
verify_ssl: Union[bool, str] = Field(
|
311
|
+
default=True, union_mode="left_to_right"
|
312
|
+
)
|
255
313
|
http_timeout: int = DEFAULT_HTTP_TIMEOUT
|
256
314
|
|
257
|
-
@
|
258
|
-
|
259
|
-
"""Validates the credentials provided in the values dictionary.
|
260
|
-
|
261
|
-
Args:
|
262
|
-
values: A dictionary containing the values to be validated.
|
263
|
-
|
264
|
-
Raises:
|
265
|
-
ValueError: If neither api_token nor username nor api_key is set.
|
266
|
-
|
267
|
-
Returns:
|
268
|
-
The values dictionary.
|
269
|
-
"""
|
270
|
-
# Check if the values dictionary contains either an API token, an API
|
271
|
-
# key or a username as non-empty strings.
|
272
|
-
if (
|
273
|
-
values.get("api_token")
|
274
|
-
or values.get("username")
|
275
|
-
or values.get("api_key")
|
276
|
-
):
|
277
|
-
return values
|
278
|
-
raise ValueError(
|
279
|
-
"Neither api_token nor username nor api_key is set in the "
|
280
|
-
"store config."
|
281
|
-
)
|
282
|
-
|
283
|
-
@validator("url")
|
315
|
+
@field_validator("url")
|
316
|
+
@classmethod
|
284
317
|
def validate_url(cls, url: str) -> str:
|
285
318
|
"""Validates that the URL is a well-formed REST store URL.
|
286
319
|
|
@@ -308,7 +341,8 @@ class RestZenStoreConfiguration(StoreConfiguration):
|
|
308
341
|
|
309
342
|
return url
|
310
343
|
|
311
|
-
@
|
344
|
+
@field_validator("verify_ssl")
|
345
|
+
@classmethod
|
312
346
|
def validate_verify_ssl(
|
313
347
|
cls, verify_ssl: Union[bool, str]
|
314
348
|
) -> Union[bool, str]:
|
@@ -335,9 +369,10 @@ class RestZenStoreConfiguration(StoreConfiguration):
|
|
335
369
|
|
336
370
|
fileio.makedirs(str(secret_folder))
|
337
371
|
file_path = Path(secret_folder, "ca_bundle.pem")
|
338
|
-
with
|
372
|
+
with os.fdopen(
|
373
|
+
os.open(file_path, flags=os.O_RDWR | os.O_CREAT, mode=0o600), "w"
|
374
|
+
) as f:
|
339
375
|
f.write(verify_ssl)
|
340
|
-
file_path.chmod(0o600)
|
341
376
|
verify_ssl = str(file_path)
|
342
377
|
|
343
378
|
return verify_ssl
|
@@ -363,54 +398,48 @@ class RestZenStoreConfiguration(StoreConfiguration):
|
|
363
398
|
with open(self.verify_ssl, "r") as f:
|
364
399
|
self.verify_ssl = f.read()
|
365
400
|
|
401
|
+
@model_validator(mode="before")
|
366
402
|
@classmethod
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
"""Create a copy of the store config using a different path.
|
374
|
-
|
375
|
-
This method is used to create a copy of the store configuration that can
|
376
|
-
be loaded using a different configuration path or in the context of a
|
377
|
-
new environment, such as a container image.
|
378
|
-
|
379
|
-
The configuration files accompanying the store configuration are also
|
380
|
-
copied to the new configuration path (e.g. certificates etc.).
|
381
|
-
|
382
|
-
Args:
|
383
|
-
config: The store configuration to copy.
|
384
|
-
config_path: new path where the configuration copy will be loaded
|
385
|
-
from.
|
386
|
-
load_config_path: absolute path that will be used to load the copied
|
387
|
-
configuration. This can be set to a value different from
|
388
|
-
`config_path` if the configuration copy will be loaded from
|
389
|
-
a different environment, e.g. when the configuration is copied
|
390
|
-
to a container image and loaded using a different absolute path.
|
391
|
-
This will be reflected in the paths and URLs encoded in the
|
392
|
-
copied configuration.
|
393
|
-
|
394
|
-
Returns:
|
395
|
-
A new store configuration object that reflects the new configuration
|
396
|
-
path.
|
397
|
-
"""
|
398
|
-
assert isinstance(config, RestZenStoreConfiguration)
|
399
|
-
assert config.api_token is not None or config.api_key is not None
|
400
|
-
config = config.copy(exclude={"username", "password"}, deep=True)
|
401
|
-
# Load the certificate values back into the configuration
|
402
|
-
config.expand_certificates()
|
403
|
-
return config
|
403
|
+
@before_validator_handler
|
404
|
+
def _move_credentials(cls, data: Dict[str, Any]) -> Dict[str, Any]:
|
405
|
+
"""Moves credentials (API keys, API tokens, passwords) from the config to the credentials store.
|
406
|
+
|
407
|
+
Args:
|
408
|
+
data: The values dict used to instantiate the model.
|
404
409
|
|
405
|
-
|
406
|
-
|
410
|
+
Returns:
|
411
|
+
The values dict without credentials.
|
412
|
+
"""
|
413
|
+
url = data.get("url")
|
414
|
+
if not url:
|
415
|
+
return data
|
416
|
+
|
417
|
+
url = replace_localhost_with_internal_hostname(url)
|
418
|
+
|
419
|
+
if api_token := data.pop("api_token", None):
|
420
|
+
credentials_store = get_credentials_store()
|
421
|
+
credentials_store.set_bare_token(url, api_token)
|
407
422
|
|
423
|
+
username = data.pop("username", None)
|
424
|
+
password = data.pop("password", None)
|
425
|
+
if username is not None and password is not None:
|
426
|
+
credentials_store = get_credentials_store()
|
427
|
+
credentials_store.set_password(url, username, password)
|
428
|
+
|
429
|
+
if api_key := data.pop("api_key", None):
|
430
|
+
credentials_store = get_credentials_store()
|
431
|
+
credentials_store.set_api_key(url, api_key)
|
432
|
+
|
433
|
+
return data
|
434
|
+
|
435
|
+
model_config = ConfigDict(
|
408
436
|
# Don't validate attributes when assigning them. This is necessary
|
409
437
|
# because the `verify_ssl` attribute can be expanded to the contents
|
410
438
|
# of the certificate file.
|
411
|
-
validate_assignment
|
412
|
-
#
|
413
|
-
extra
|
439
|
+
validate_assignment=False,
|
440
|
+
# Ignore extra attributes set in the class.
|
441
|
+
extra="ignore",
|
442
|
+
)
|
414
443
|
|
415
444
|
|
416
445
|
class RestZenStore(BaseZenStore):
|
@@ -419,7 +448,7 @@ class RestZenStore(BaseZenStore):
|
|
419
448
|
config: RestZenStoreConfiguration
|
420
449
|
TYPE: ClassVar[StoreType] = StoreType.REST
|
421
450
|
CONFIG_TYPE: ClassVar[Type[StoreConfiguration]] = RestZenStoreConfiguration
|
422
|
-
_api_token: Optional[
|
451
|
+
_api_token: Optional[APIToken] = None
|
423
452
|
_session: Optional[requests.Session] = None
|
424
453
|
|
425
454
|
# ====================================
|
@@ -431,9 +460,54 @@ class RestZenStore(BaseZenStore):
|
|
431
460
|
# --------------------------------
|
432
461
|
|
433
462
|
def _initialize(self) -> None:
|
434
|
-
"""Initialize the REST store.
|
435
|
-
|
436
|
-
|
463
|
+
"""Initialize the REST store.
|
464
|
+
|
465
|
+
Raises:
|
466
|
+
RuntimeError: If the store cannot be initialized.
|
467
|
+
AuthorizationException: If the store cannot be initialized due to
|
468
|
+
authentication errors.
|
469
|
+
"""
|
470
|
+
try:
|
471
|
+
client_version = zenml.__version__
|
472
|
+
server_version = self.get_store_info().version
|
473
|
+
|
474
|
+
# Handle cases where the ZenML server is not available
|
475
|
+
except ConnectionError as e:
|
476
|
+
error_message = (
|
477
|
+
f"Cannot connect to the ZenML server at {self.url}."
|
478
|
+
)
|
479
|
+
if urlparse(self.url).hostname in [
|
480
|
+
"localhost",
|
481
|
+
"127.0.0.1",
|
482
|
+
"host.docker.internal",
|
483
|
+
]:
|
484
|
+
recommendation = (
|
485
|
+
"Please run `zenml login --local --restart` to restart the "
|
486
|
+
"server."
|
487
|
+
)
|
488
|
+
else:
|
489
|
+
recommendation = (
|
490
|
+
f"Please run `zenml login {self.url}` to reconnect to the "
|
491
|
+
"server."
|
492
|
+
)
|
493
|
+
raise RuntimeError(f"{error_message}\n{recommendation}") from e
|
494
|
+
|
495
|
+
except AuthorizationException as e:
|
496
|
+
raise AuthorizationException(
|
497
|
+
f"Authorization failed for store at '{self.url}'. Please check "
|
498
|
+
f"your credentials: {str(e)}"
|
499
|
+
)
|
500
|
+
|
501
|
+
except Exception as e:
|
502
|
+
zenml_pro_extra = ""
|
503
|
+
if is_zenml_pro_server_url(self.url):
|
504
|
+
zenml_pro_extra = (
|
505
|
+
"\nHINT: " + get_troubleshooting_instructions(self.url)
|
506
|
+
)
|
507
|
+
raise RuntimeError(
|
508
|
+
f"Error connecting to URL "
|
509
|
+
f"'{self.url}': {str(e)}" + zenml_pro_extra
|
510
|
+
) from e
|
437
511
|
|
438
512
|
if not DISABLE_CLIENT_SERVER_MISMATCH_WARNING and (
|
439
513
|
server_version != client_version
|
@@ -455,7 +529,7 @@ class RestZenStore(BaseZenStore):
|
|
455
529
|
Information about the server.
|
456
530
|
"""
|
457
531
|
body = self.get(INFO)
|
458
|
-
return ServerModel.
|
532
|
+
return ServerModel.model_validate(body)
|
459
533
|
|
460
534
|
def get_deployment_id(self) -> UUID:
|
461
535
|
"""Get the ID of the deployment.
|
@@ -465,6 +539,131 @@ class RestZenStore(BaseZenStore):
|
|
465
539
|
"""
|
466
540
|
return self.get_store_info().id
|
467
541
|
|
542
|
+
# -------------------- Server Settings --------------------
|
543
|
+
|
544
|
+
def get_server_settings(
|
545
|
+
self, hydrate: bool = True
|
546
|
+
) -> ServerSettingsResponse:
|
547
|
+
"""Get the server settings.
|
548
|
+
|
549
|
+
Args:
|
550
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
551
|
+
by including metadata fields in the response.
|
552
|
+
|
553
|
+
Returns:
|
554
|
+
The server settings.
|
555
|
+
"""
|
556
|
+
response_body = self.get(SERVER_SETTINGS, params={"hydrate": hydrate})
|
557
|
+
return ServerSettingsResponse.model_validate(response_body)
|
558
|
+
|
559
|
+
def update_server_settings(
|
560
|
+
self, settings_update: ServerSettingsUpdate
|
561
|
+
) -> ServerSettingsResponse:
|
562
|
+
"""Update the server settings.
|
563
|
+
|
564
|
+
Args:
|
565
|
+
settings_update: The server settings update.
|
566
|
+
|
567
|
+
Returns:
|
568
|
+
The updated server settings.
|
569
|
+
"""
|
570
|
+
response_body = self.put(SERVER_SETTINGS, body=settings_update)
|
571
|
+
return ServerSettingsResponse.model_validate(response_body)
|
572
|
+
|
573
|
+
# -------------------- Actions --------------------
|
574
|
+
|
575
|
+
def create_action(self, action: ActionRequest) -> ActionResponse:
|
576
|
+
"""Create an action.
|
577
|
+
|
578
|
+
Args:
|
579
|
+
action: The action to create.
|
580
|
+
|
581
|
+
Returns:
|
582
|
+
The created action.
|
583
|
+
"""
|
584
|
+
return self._create_resource(
|
585
|
+
resource=action,
|
586
|
+
route=ACTIONS,
|
587
|
+
response_model=ActionResponse,
|
588
|
+
)
|
589
|
+
|
590
|
+
def get_action(
|
591
|
+
self,
|
592
|
+
action_id: UUID,
|
593
|
+
hydrate: bool = True,
|
594
|
+
) -> ActionResponse:
|
595
|
+
"""Get an action by ID.
|
596
|
+
|
597
|
+
Args:
|
598
|
+
action_id: The ID of the action to get.
|
599
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
600
|
+
by including metadata fields in the response.
|
601
|
+
|
602
|
+
Returns:
|
603
|
+
The action.
|
604
|
+
"""
|
605
|
+
return self._get_resource(
|
606
|
+
resource_id=action_id,
|
607
|
+
route=ACTIONS,
|
608
|
+
response_model=ActionResponse,
|
609
|
+
params={"hydrate": hydrate},
|
610
|
+
)
|
611
|
+
|
612
|
+
def list_actions(
|
613
|
+
self,
|
614
|
+
action_filter_model: ActionFilter,
|
615
|
+
hydrate: bool = False,
|
616
|
+
) -> Page[ActionResponse]:
|
617
|
+
"""List all actions matching the given filter criteria.
|
618
|
+
|
619
|
+
Args:
|
620
|
+
action_filter_model: All filter parameters including pagination
|
621
|
+
params.
|
622
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
623
|
+
by including metadata fields in the response.
|
624
|
+
|
625
|
+
Returns:
|
626
|
+
A list of all actions matching the filter criteria.
|
627
|
+
"""
|
628
|
+
return self._list_paginated_resources(
|
629
|
+
route=ACTIONS,
|
630
|
+
response_model=ActionResponse,
|
631
|
+
filter_model=action_filter_model,
|
632
|
+
params={"hydrate": hydrate},
|
633
|
+
)
|
634
|
+
|
635
|
+
def update_action(
|
636
|
+
self,
|
637
|
+
action_id: UUID,
|
638
|
+
action_update: ActionUpdate,
|
639
|
+
) -> ActionResponse:
|
640
|
+
"""Update an existing action.
|
641
|
+
|
642
|
+
Args:
|
643
|
+
action_id: The ID of the action to update.
|
644
|
+
action_update: The update to be applied to the action.
|
645
|
+
|
646
|
+
Returns:
|
647
|
+
The updated action.
|
648
|
+
"""
|
649
|
+
return self._update_resource(
|
650
|
+
resource_id=action_id,
|
651
|
+
resource_update=action_update,
|
652
|
+
route=ACTIONS,
|
653
|
+
response_model=ActionResponse,
|
654
|
+
)
|
655
|
+
|
656
|
+
def delete_action(self, action_id: UUID) -> None:
|
657
|
+
"""Delete an action.
|
658
|
+
|
659
|
+
Args:
|
660
|
+
action_id: The ID of the action to delete.
|
661
|
+
"""
|
662
|
+
self._delete_resource(
|
663
|
+
resource_id=action_id,
|
664
|
+
route=ACTIONS,
|
665
|
+
)
|
666
|
+
|
468
667
|
# ----------------------------- API Keys -----------------------------
|
469
668
|
|
470
669
|
def create_api_key(
|
@@ -511,16 +710,6 @@ class RestZenStore(BaseZenStore):
|
|
511
710
|
params={"hydrate": hydrate},
|
512
711
|
)
|
513
712
|
|
514
|
-
def set_api_key(self, api_key: str) -> None:
|
515
|
-
"""Set the API key to use for authentication.
|
516
|
-
|
517
|
-
Args:
|
518
|
-
api_key: The API key to use for authentication.
|
519
|
-
"""
|
520
|
-
self.config.api_key = api_key
|
521
|
-
self.clear_session()
|
522
|
-
GlobalConfiguration()._write_config()
|
523
|
-
|
524
713
|
def list_api_keys(
|
525
714
|
self,
|
526
715
|
service_account_id: UUID,
|
@@ -592,7 +781,7 @@ class RestZenStore(BaseZenStore):
|
|
592
781
|
f"{SERVICE_ACCOUNTS}/{str(service_account_id)}{API_KEYS}/{str(api_key_name_or_id)}{API_KEY_ROTATE}",
|
593
782
|
body=rotate_request,
|
594
783
|
)
|
595
|
-
return APIKeyResponse.
|
784
|
+
return APIKeyResponse.model_validate(response_body)
|
596
785
|
|
597
786
|
def delete_api_key(
|
598
787
|
self,
|
@@ -611,6 +800,93 @@ class RestZenStore(BaseZenStore):
|
|
611
800
|
route=f"{SERVICE_ACCOUNTS}/{str(service_account_id)}{API_KEYS}",
|
612
801
|
)
|
613
802
|
|
803
|
+
# ----------------------------- Services -----------------------------
|
804
|
+
|
805
|
+
def create_service(
|
806
|
+
self, service_request: ServiceRequest
|
807
|
+
) -> ServiceResponse:
|
808
|
+
"""Create a new service.
|
809
|
+
|
810
|
+
Args:
|
811
|
+
service_request: The service to create.
|
812
|
+
|
813
|
+
Returns:
|
814
|
+
The created service.
|
815
|
+
"""
|
816
|
+
return self._create_resource(
|
817
|
+
resource=service_request,
|
818
|
+
response_model=ServiceResponse,
|
819
|
+
route=SERVICES,
|
820
|
+
)
|
821
|
+
|
822
|
+
def get_service(
|
823
|
+
self, service_id: UUID, hydrate: bool = True
|
824
|
+
) -> ServiceResponse:
|
825
|
+
"""Get a service.
|
826
|
+
|
827
|
+
Args:
|
828
|
+
service_id: The ID of the service to get.
|
829
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
830
|
+
by including metadata fields in the response.
|
831
|
+
|
832
|
+
Returns:
|
833
|
+
The service.
|
834
|
+
"""
|
835
|
+
return self._get_resource(
|
836
|
+
resource_id=service_id,
|
837
|
+
route=SERVICES,
|
838
|
+
response_model=ServiceResponse,
|
839
|
+
params={"hydrate": hydrate},
|
840
|
+
)
|
841
|
+
|
842
|
+
def list_services(
|
843
|
+
self, filter_model: ServiceFilter, hydrate: bool = False
|
844
|
+
) -> Page[ServiceResponse]:
|
845
|
+
"""List all services matching the given filter criteria.
|
846
|
+
|
847
|
+
Args:
|
848
|
+
filter_model: All filter parameters including pagination
|
849
|
+
params.
|
850
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
851
|
+
by including metadata fields in the response.
|
852
|
+
|
853
|
+
Returns:
|
854
|
+
A list of all services matching the filter criteria.
|
855
|
+
"""
|
856
|
+
return self._list_paginated_resources(
|
857
|
+
route=SERVICES,
|
858
|
+
response_model=ServiceResponse,
|
859
|
+
filter_model=filter_model,
|
860
|
+
params={"hydrate": hydrate},
|
861
|
+
)
|
862
|
+
|
863
|
+
def update_service(
|
864
|
+
self, service_id: UUID, update: ServiceUpdate
|
865
|
+
) -> ServiceResponse:
|
866
|
+
"""Update a service.
|
867
|
+
|
868
|
+
Args:
|
869
|
+
service_id: The ID of the service to update.
|
870
|
+
update: The update to be applied to the service.
|
871
|
+
|
872
|
+
Returns:
|
873
|
+
The updated service.
|
874
|
+
"""
|
875
|
+
return self._update_resource(
|
876
|
+
resource_id=service_id,
|
877
|
+
resource_update=update,
|
878
|
+
response_model=ServiceResponse,
|
879
|
+
route=SERVICES,
|
880
|
+
)
|
881
|
+
|
882
|
+
def delete_service(self, service_id: UUID) -> None:
|
883
|
+
"""Delete a service.
|
884
|
+
|
885
|
+
Args:
|
886
|
+
service_id: The ID of the service to delete.
|
887
|
+
"""
|
888
|
+
self._delete_resource(resource_id=service_id, route=SERVICES)
|
889
|
+
|
614
890
|
# ----------------------------- Artifacts -----------------------------
|
615
891
|
|
616
892
|
def create_artifact(self, artifact: ArtifactRequest) -> ArtifactResponse:
|
@@ -715,6 +991,23 @@ class RestZenStore(BaseZenStore):
|
|
715
991
|
route=ARTIFACT_VERSIONS,
|
716
992
|
)
|
717
993
|
|
994
|
+
def batch_create_artifact_versions(
|
995
|
+
self, artifact_versions: List[ArtifactVersionRequest]
|
996
|
+
) -> List[ArtifactVersionResponse]:
|
997
|
+
"""Creates a batch of artifact versions.
|
998
|
+
|
999
|
+
Args:
|
1000
|
+
artifact_versions: The artifact versions to create.
|
1001
|
+
|
1002
|
+
Returns:
|
1003
|
+
The created artifact versions.
|
1004
|
+
"""
|
1005
|
+
return self._batch_create_resources(
|
1006
|
+
resources=artifact_versions,
|
1007
|
+
response_model=ArtifactVersionResponse,
|
1008
|
+
route=ARTIFACT_VERSIONS,
|
1009
|
+
)
|
1010
|
+
|
718
1011
|
def get_artifact_version(
|
719
1012
|
self, artifact_version_id: UUID, hydrate: bool = True
|
720
1013
|
) -> ArtifactVersionResponse:
|
@@ -1308,10 +1601,6 @@ class RestZenStore(BaseZenStore):
|
|
1308
1601
|
route=PIPELINE_BUILDS,
|
1309
1602
|
)
|
1310
1603
|
|
1311
|
-
# ----------------------
|
1312
|
-
# Pipeline Deployments
|
1313
|
-
# ----------------------
|
1314
|
-
|
1315
1604
|
# -------------------------- Pipeline Deployments --------------------------
|
1316
1605
|
|
1317
1606
|
def create_deployment(
|
@@ -1386,6 +1675,228 @@ class RestZenStore(BaseZenStore):
|
|
1386
1675
|
route=PIPELINE_DEPLOYMENTS,
|
1387
1676
|
)
|
1388
1677
|
|
1678
|
+
# -------------------- Run templates --------------------
|
1679
|
+
|
1680
|
+
def create_run_template(
|
1681
|
+
self,
|
1682
|
+
template: RunTemplateRequest,
|
1683
|
+
) -> RunTemplateResponse:
|
1684
|
+
"""Create a new run template.
|
1685
|
+
|
1686
|
+
Args:
|
1687
|
+
template: The template to create.
|
1688
|
+
|
1689
|
+
Returns:
|
1690
|
+
The newly created template.
|
1691
|
+
"""
|
1692
|
+
return self._create_workspace_scoped_resource(
|
1693
|
+
resource=template,
|
1694
|
+
route=RUN_TEMPLATES,
|
1695
|
+
response_model=RunTemplateResponse,
|
1696
|
+
)
|
1697
|
+
|
1698
|
+
def get_run_template(
|
1699
|
+
self, template_id: UUID, hydrate: bool = True
|
1700
|
+
) -> RunTemplateResponse:
|
1701
|
+
"""Get a run template with a given ID.
|
1702
|
+
|
1703
|
+
Args:
|
1704
|
+
template_id: ID of the template.
|
1705
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1706
|
+
by including metadata fields in the response.
|
1707
|
+
|
1708
|
+
Returns:
|
1709
|
+
The template.
|
1710
|
+
"""
|
1711
|
+
return self._get_resource(
|
1712
|
+
resource_id=template_id,
|
1713
|
+
route=RUN_TEMPLATES,
|
1714
|
+
response_model=RunTemplateResponse,
|
1715
|
+
params={"hydrate": hydrate},
|
1716
|
+
)
|
1717
|
+
|
1718
|
+
def list_run_templates(
|
1719
|
+
self,
|
1720
|
+
template_filter_model: RunTemplateFilter,
|
1721
|
+
hydrate: bool = False,
|
1722
|
+
) -> Page[RunTemplateResponse]:
|
1723
|
+
"""List all run templates matching the given filter criteria.
|
1724
|
+
|
1725
|
+
Args:
|
1726
|
+
template_filter_model: All filter parameters including pagination
|
1727
|
+
params.
|
1728
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1729
|
+
by including metadata fields in the response.
|
1730
|
+
|
1731
|
+
Returns:
|
1732
|
+
A list of all templates matching the filter criteria.
|
1733
|
+
"""
|
1734
|
+
return self._list_paginated_resources(
|
1735
|
+
route=RUN_TEMPLATES,
|
1736
|
+
response_model=RunTemplateResponse,
|
1737
|
+
filter_model=template_filter_model,
|
1738
|
+
params={"hydrate": hydrate},
|
1739
|
+
)
|
1740
|
+
|
1741
|
+
def update_run_template(
|
1742
|
+
self,
|
1743
|
+
template_id: UUID,
|
1744
|
+
template_update: RunTemplateUpdate,
|
1745
|
+
) -> RunTemplateResponse:
|
1746
|
+
"""Updates a run template.
|
1747
|
+
|
1748
|
+
Args:
|
1749
|
+
template_id: The ID of the template to update.
|
1750
|
+
template_update: The update to apply.
|
1751
|
+
|
1752
|
+
Returns:
|
1753
|
+
The updated template.
|
1754
|
+
"""
|
1755
|
+
return self._update_resource(
|
1756
|
+
resource_id=template_id,
|
1757
|
+
resource_update=template_update,
|
1758
|
+
route=RUN_TEMPLATES,
|
1759
|
+
response_model=RunTemplateResponse,
|
1760
|
+
)
|
1761
|
+
|
1762
|
+
def delete_run_template(self, template_id: UUID) -> None:
|
1763
|
+
"""Delete a run template.
|
1764
|
+
|
1765
|
+
Args:
|
1766
|
+
template_id: The ID of the template to delete.
|
1767
|
+
"""
|
1768
|
+
self._delete_resource(
|
1769
|
+
resource_id=template_id,
|
1770
|
+
route=RUN_TEMPLATES,
|
1771
|
+
)
|
1772
|
+
|
1773
|
+
def run_template(
|
1774
|
+
self,
|
1775
|
+
template_id: UUID,
|
1776
|
+
run_configuration: Optional[PipelineRunConfiguration] = None,
|
1777
|
+
) -> PipelineRunResponse:
|
1778
|
+
"""Run a template.
|
1779
|
+
|
1780
|
+
Args:
|
1781
|
+
template_id: The ID of the template to run.
|
1782
|
+
run_configuration: Configuration for the run.
|
1783
|
+
|
1784
|
+
Raises:
|
1785
|
+
RuntimeError: If the server does not support running a template.
|
1786
|
+
|
1787
|
+
Returns:
|
1788
|
+
Model of the pipeline run.
|
1789
|
+
"""
|
1790
|
+
run_configuration = run_configuration or PipelineRunConfiguration()
|
1791
|
+
|
1792
|
+
try:
|
1793
|
+
response_body = self.post(
|
1794
|
+
f"{RUN_TEMPLATES}/{template_id}/runs",
|
1795
|
+
body=run_configuration,
|
1796
|
+
)
|
1797
|
+
except MethodNotAllowedError as e:
|
1798
|
+
raise RuntimeError(
|
1799
|
+
"Running a template is not supported for this server."
|
1800
|
+
) from e
|
1801
|
+
|
1802
|
+
return PipelineRunResponse.model_validate(response_body)
|
1803
|
+
|
1804
|
+
# -------------------- Event Sources --------------------
|
1805
|
+
|
1806
|
+
def create_event_source(
|
1807
|
+
self, event_source: EventSourceRequest
|
1808
|
+
) -> EventSourceResponse:
|
1809
|
+
"""Create an event_source.
|
1810
|
+
|
1811
|
+
Args:
|
1812
|
+
event_source: The event_source to create.
|
1813
|
+
|
1814
|
+
Returns:
|
1815
|
+
The created event_source.
|
1816
|
+
"""
|
1817
|
+
return self._create_resource(
|
1818
|
+
resource=event_source,
|
1819
|
+
route=EVENT_SOURCES,
|
1820
|
+
response_model=EventSourceResponse,
|
1821
|
+
)
|
1822
|
+
|
1823
|
+
def get_event_source(
|
1824
|
+
self,
|
1825
|
+
event_source_id: UUID,
|
1826
|
+
hydrate: bool = True,
|
1827
|
+
) -> EventSourceResponse:
|
1828
|
+
"""Get an event_source by ID.
|
1829
|
+
|
1830
|
+
Args:
|
1831
|
+
event_source_id: The ID of the event_source to get.
|
1832
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1833
|
+
by including metadata fields in the response.
|
1834
|
+
|
1835
|
+
Returns:
|
1836
|
+
The event_source.
|
1837
|
+
"""
|
1838
|
+
return self._get_resource(
|
1839
|
+
resource_id=event_source_id,
|
1840
|
+
route=EVENT_SOURCES,
|
1841
|
+
response_model=EventSourceResponse,
|
1842
|
+
params={"hydrate": hydrate},
|
1843
|
+
)
|
1844
|
+
|
1845
|
+
def list_event_sources(
|
1846
|
+
self,
|
1847
|
+
event_source_filter_model: EventSourceFilter,
|
1848
|
+
hydrate: bool = False,
|
1849
|
+
) -> Page[EventSourceResponse]:
|
1850
|
+
"""List all event_sources matching the given filter criteria.
|
1851
|
+
|
1852
|
+
Args:
|
1853
|
+
event_source_filter_model: All filter parameters including pagination
|
1854
|
+
params.
|
1855
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1856
|
+
by including metadata fields in the response.
|
1857
|
+
|
1858
|
+
Returns:
|
1859
|
+
A list of all event_sources matching the filter criteria.
|
1860
|
+
"""
|
1861
|
+
return self._list_paginated_resources(
|
1862
|
+
route=EVENT_SOURCES,
|
1863
|
+
response_model=EventSourceResponse,
|
1864
|
+
filter_model=event_source_filter_model,
|
1865
|
+
params={"hydrate": hydrate},
|
1866
|
+
)
|
1867
|
+
|
1868
|
+
def update_event_source(
|
1869
|
+
self,
|
1870
|
+
event_source_id: UUID,
|
1871
|
+
event_source_update: EventSourceUpdate,
|
1872
|
+
) -> EventSourceResponse:
|
1873
|
+
"""Update an existing event_source.
|
1874
|
+
|
1875
|
+
Args:
|
1876
|
+
event_source_id: The ID of the event_source to update.
|
1877
|
+
event_source_update: The update to be applied to the event_source.
|
1878
|
+
|
1879
|
+
Returns:
|
1880
|
+
The updated event_source.
|
1881
|
+
"""
|
1882
|
+
return self._update_resource(
|
1883
|
+
resource_id=event_source_id,
|
1884
|
+
resource_update=event_source_update,
|
1885
|
+
route=EVENT_SOURCES,
|
1886
|
+
response_model=EventSourceResponse,
|
1887
|
+
)
|
1888
|
+
|
1889
|
+
def delete_event_source(self, event_source_id: UUID) -> None:
|
1890
|
+
"""Delete an event_source.
|
1891
|
+
|
1892
|
+
Args:
|
1893
|
+
event_source_id: The ID of the event_source to delete.
|
1894
|
+
"""
|
1895
|
+
self._delete_resource(
|
1896
|
+
resource_id=event_source_id,
|
1897
|
+
route=EVENT_SOURCES,
|
1898
|
+
)
|
1899
|
+
|
1389
1900
|
# ----------------------------- Pipeline runs -----------------------------
|
1390
1901
|
|
1391
1902
|
def create_run(
|
@@ -1502,9 +2013,7 @@ class RestZenStore(BaseZenStore):
|
|
1502
2013
|
|
1503
2014
|
# ----------------------------- Run Metadata -----------------------------
|
1504
2015
|
|
1505
|
-
def create_run_metadata(
|
1506
|
-
self, run_metadata: RunMetadataRequest
|
1507
|
-
) -> List[RunMetadataResponse]:
|
2016
|
+
def create_run_metadata(self, run_metadata: RunMetadataRequest) -> None:
|
1508
2017
|
"""Creates run metadata.
|
1509
2018
|
|
1510
2019
|
Args:
|
@@ -1514,55 +2023,8 @@ class RestZenStore(BaseZenStore):
|
|
1514
2023
|
The created run metadata.
|
1515
2024
|
"""
|
1516
2025
|
route = f"{WORKSPACES}/{str(run_metadata.workspace)}{RUN_METADATA}"
|
1517
|
-
|
1518
|
-
|
1519
|
-
if isinstance(response_body, list):
|
1520
|
-
for metadata in response_body or []:
|
1521
|
-
result.append(RunMetadataResponse.parse_obj(metadata))
|
1522
|
-
return result
|
1523
|
-
|
1524
|
-
def get_run_metadata(
|
1525
|
-
self, run_metadata_id: UUID, hydrate: bool = True
|
1526
|
-
) -> RunMetadataResponse:
|
1527
|
-
"""Gets run metadata with the given ID.
|
1528
|
-
|
1529
|
-
Args:
|
1530
|
-
run_metadata_id: The ID of the run metadata to get.
|
1531
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
1532
|
-
by including metadata fields in the response.
|
1533
|
-
|
1534
|
-
Returns:
|
1535
|
-
The run metadata.
|
1536
|
-
"""
|
1537
|
-
return self._get_resource(
|
1538
|
-
resource_id=run_metadata_id,
|
1539
|
-
route=RUN_METADATA,
|
1540
|
-
response_model=RunMetadataResponse,
|
1541
|
-
params={"hydrate": hydrate},
|
1542
|
-
)
|
1543
|
-
|
1544
|
-
def list_run_metadata(
|
1545
|
-
self,
|
1546
|
-
run_metadata_filter_model: RunMetadataFilter,
|
1547
|
-
hydrate: bool = False,
|
1548
|
-
) -> Page[RunMetadataResponse]:
|
1549
|
-
"""List run metadata.
|
1550
|
-
|
1551
|
-
Args:
|
1552
|
-
run_metadata_filter_model: All filter parameters including
|
1553
|
-
pagination params.
|
1554
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
1555
|
-
by including metadata fields in the response.
|
1556
|
-
|
1557
|
-
Returns:
|
1558
|
-
The run metadata.
|
1559
|
-
"""
|
1560
|
-
return self._list_paginated_resources(
|
1561
|
-
route=RUN_METADATA,
|
1562
|
-
response_model=RunMetadataResponse,
|
1563
|
-
filter_model=run_metadata_filter_model,
|
1564
|
-
params={"hydrate": hydrate},
|
1565
|
-
)
|
2026
|
+
self.post(f"{route}", body=run_metadata)
|
2027
|
+
return None
|
1566
2028
|
|
1567
2029
|
# ----------------------------- Schedules -----------------------------
|
1568
2030
|
|
@@ -2110,9 +2572,15 @@ class RestZenStore(BaseZenStore):
|
|
2110
2572
|
f"{SERVICE_CONNECTORS}{SERVICE_CONNECTOR_VERIFY}",
|
2111
2573
|
body=service_connector,
|
2112
2574
|
params={"list_resources": list_resources},
|
2575
|
+
timeout=max(
|
2576
|
+
self.config.http_timeout,
|
2577
|
+
SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
|
2578
|
+
),
|
2113
2579
|
)
|
2114
2580
|
|
2115
|
-
resources = ServiceConnectorResourcesModel.
|
2581
|
+
resources = ServiceConnectorResourcesModel.model_validate(
|
2582
|
+
response_body
|
2583
|
+
)
|
2116
2584
|
self._populate_connector_type(resources)
|
2117
2585
|
return resources
|
2118
2586
|
|
@@ -2145,9 +2613,15 @@ class RestZenStore(BaseZenStore):
|
|
2145
2613
|
response_body = self.put(
|
2146
2614
|
f"{SERVICE_CONNECTORS}/{str(service_connector_id)}{SERVICE_CONNECTOR_VERIFY}",
|
2147
2615
|
params=params,
|
2616
|
+
timeout=max(
|
2617
|
+
self.config.http_timeout,
|
2618
|
+
SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
|
2619
|
+
),
|
2148
2620
|
)
|
2149
2621
|
|
2150
|
-
resources = ServiceConnectorResourcesModel.
|
2622
|
+
resources = ServiceConnectorResourcesModel.model_validate(
|
2623
|
+
response_body
|
2624
|
+
)
|
2151
2625
|
self._populate_connector_type(resources)
|
2152
2626
|
return resources
|
2153
2627
|
|
@@ -2178,7 +2652,7 @@ class RestZenStore(BaseZenStore):
|
|
2178
2652
|
params=params,
|
2179
2653
|
)
|
2180
2654
|
|
2181
|
-
connector = ServiceConnectorResponse.
|
2655
|
+
connector = ServiceConnectorResponse.model_validate(response_body)
|
2182
2656
|
self._populate_connector_type(connector)
|
2183
2657
|
return connector
|
2184
2658
|
|
@@ -2211,11 +2685,15 @@ class RestZenStore(BaseZenStore):
|
|
2211
2685
|
response_body = self.get(
|
2212
2686
|
f"{WORKSPACES}/{workspace_name_or_id}{SERVICE_CONNECTORS}{SERVICE_CONNECTOR_RESOURCES}",
|
2213
2687
|
params=params,
|
2688
|
+
timeout=max(
|
2689
|
+
self.config.http_timeout,
|
2690
|
+
SERVICE_CONNECTOR_VERIFY_REQUEST_TIMEOUT,
|
2691
|
+
),
|
2214
2692
|
)
|
2215
2693
|
|
2216
2694
|
assert isinstance(response_body, list)
|
2217
2695
|
resource_list = [
|
2218
|
-
ServiceConnectorResourcesModel.
|
2696
|
+
ServiceConnectorResourcesModel.model_validate(item)
|
2219
2697
|
for item in response_body
|
2220
2698
|
]
|
2221
2699
|
|
@@ -2248,7 +2726,7 @@ class RestZenStore(BaseZenStore):
|
|
2248
2726
|
)
|
2249
2727
|
except (ValueError, AuthorizationException) as e:
|
2250
2728
|
logger.error(
|
2251
|
-
f
|
2729
|
+
f"Failed to fetch {resource_type or 'available'} "
|
2252
2730
|
f"resources from service connector {connector.name}/"
|
2253
2731
|
f"{connector.id}: {e}"
|
2254
2732
|
)
|
@@ -2288,7 +2766,8 @@ class RestZenStore(BaseZenStore):
|
|
2288
2766
|
|
2289
2767
|
assert isinstance(response_body, list)
|
2290
2768
|
remote_connector_types = [
|
2291
|
-
ServiceConnectorTypeModel.
|
2769
|
+
ServiceConnectorTypeModel.model_validate(item)
|
2770
|
+
for item in response_body
|
2292
2771
|
]
|
2293
2772
|
|
2294
2773
|
# Mark the remote connector types as being only remotely available
|
@@ -2344,7 +2823,7 @@ class RestZenStore(BaseZenStore):
|
|
2344
2823
|
response_body = self.get(
|
2345
2824
|
f"{SERVICE_CONNECTOR_TYPES}/{connector_type}",
|
2346
2825
|
)
|
2347
|
-
remote_connector_type = ServiceConnectorTypeModel.
|
2826
|
+
remote_connector_type = ServiceConnectorTypeModel.model_validate(
|
2348
2827
|
response_body
|
2349
2828
|
)
|
2350
2829
|
if local_connector_type:
|
@@ -2376,10 +2855,12 @@ class RestZenStore(BaseZenStore):
|
|
2376
2855
|
Returns:
|
2377
2856
|
The registered stack.
|
2378
2857
|
"""
|
2379
|
-
|
2858
|
+
assert stack.workspace is not None
|
2859
|
+
|
2860
|
+
return self._create_resource(
|
2380
2861
|
resource=stack,
|
2381
|
-
route=STACKS,
|
2382
2862
|
response_model=StackResponse,
|
2863
|
+
route=f"{WORKSPACES}/{str(stack.workspace)}{STACKS}",
|
2383
2864
|
)
|
2384
2865
|
|
2385
2866
|
def get_stack(self, stack_id: UUID, hydrate: bool = True) -> StackResponse:
|
@@ -2451,6 +2932,88 @@ class RestZenStore(BaseZenStore):
|
|
2451
2932
|
route=STACKS,
|
2452
2933
|
)
|
2453
2934
|
|
2935
|
+
# ---------------- Stack deployments-----------------
|
2936
|
+
|
2937
|
+
def get_stack_deployment_info(
|
2938
|
+
self,
|
2939
|
+
provider: StackDeploymentProvider,
|
2940
|
+
) -> StackDeploymentInfo:
|
2941
|
+
"""Get information about a stack deployment provider.
|
2942
|
+
|
2943
|
+
Args:
|
2944
|
+
provider: The stack deployment provider.
|
2945
|
+
|
2946
|
+
Returns:
|
2947
|
+
Information about the stack deployment provider.
|
2948
|
+
"""
|
2949
|
+
body = self.get(
|
2950
|
+
f"{STACK_DEPLOYMENT}{INFO}",
|
2951
|
+
params={"provider": provider.value},
|
2952
|
+
)
|
2953
|
+
return StackDeploymentInfo.model_validate(body)
|
2954
|
+
|
2955
|
+
def get_stack_deployment_config(
|
2956
|
+
self,
|
2957
|
+
provider: StackDeploymentProvider,
|
2958
|
+
stack_name: str,
|
2959
|
+
location: Optional[str] = None,
|
2960
|
+
) -> StackDeploymentConfig:
|
2961
|
+
"""Return the cloud provider console URL and configuration needed to deploy the ZenML stack.
|
2962
|
+
|
2963
|
+
Args:
|
2964
|
+
provider: The stack deployment provider.
|
2965
|
+
stack_name: The name of the stack.
|
2966
|
+
location: The location where the stack should be deployed.
|
2967
|
+
|
2968
|
+
Returns:
|
2969
|
+
The cloud provider console URL and configuration needed to deploy
|
2970
|
+
the ZenML stack to the specified cloud provider.
|
2971
|
+
"""
|
2972
|
+
params = {
|
2973
|
+
"provider": provider.value,
|
2974
|
+
"stack_name": stack_name,
|
2975
|
+
}
|
2976
|
+
if location:
|
2977
|
+
params["location"] = location
|
2978
|
+
body = self.get(f"{STACK_DEPLOYMENT}{CONFIG}", params=params)
|
2979
|
+
return StackDeploymentConfig.model_validate(body)
|
2980
|
+
|
2981
|
+
def get_stack_deployment_stack(
|
2982
|
+
self,
|
2983
|
+
provider: StackDeploymentProvider,
|
2984
|
+
stack_name: str,
|
2985
|
+
location: Optional[str] = None,
|
2986
|
+
date_start: Optional[datetime] = None,
|
2987
|
+
) -> Optional[DeployedStack]:
|
2988
|
+
"""Return a matching ZenML stack that was deployed and registered.
|
2989
|
+
|
2990
|
+
Args:
|
2991
|
+
provider: The stack deployment provider.
|
2992
|
+
stack_name: The name of the stack.
|
2993
|
+
location: The location where the stack should be deployed.
|
2994
|
+
date_start: The date when the deployment started.
|
2995
|
+
|
2996
|
+
Returns:
|
2997
|
+
The ZenML stack that was deployed and registered or None if the
|
2998
|
+
stack was not found.
|
2999
|
+
"""
|
3000
|
+
params = {
|
3001
|
+
"provider": provider.value,
|
3002
|
+
"stack_name": stack_name,
|
3003
|
+
}
|
3004
|
+
if location:
|
3005
|
+
params["location"] = location
|
3006
|
+
if date_start:
|
3007
|
+
params["date_start"] = str(date_start)
|
3008
|
+
body = self.get(
|
3009
|
+
f"{STACK_DEPLOYMENT}{STACK}",
|
3010
|
+
params=params,
|
3011
|
+
)
|
3012
|
+
if body:
|
3013
|
+
return DeployedStack.model_validate(body)
|
3014
|
+
|
3015
|
+
return None
|
3016
|
+
|
2454
3017
|
# ----------------------------- Step runs -----------------------------
|
2455
3018
|
|
2456
3019
|
def create_run_step(self, step_run: StepRunRequest) -> StepRunResponse:
|
@@ -2532,6 +3095,158 @@ class RestZenStore(BaseZenStore):
|
|
2532
3095
|
route=STEPS,
|
2533
3096
|
)
|
2534
3097
|
|
3098
|
+
# -------------------- Triggers --------------------
|
3099
|
+
|
3100
|
+
def create_trigger(self, trigger: TriggerRequest) -> TriggerResponse:
|
3101
|
+
"""Create an trigger.
|
3102
|
+
|
3103
|
+
Args:
|
3104
|
+
trigger: The trigger to create.
|
3105
|
+
|
3106
|
+
Returns:
|
3107
|
+
The created trigger.
|
3108
|
+
"""
|
3109
|
+
return self._create_resource(
|
3110
|
+
resource=trigger,
|
3111
|
+
route=TRIGGERS,
|
3112
|
+
response_model=TriggerResponse,
|
3113
|
+
)
|
3114
|
+
|
3115
|
+
def get_trigger(
|
3116
|
+
self,
|
3117
|
+
trigger_id: UUID,
|
3118
|
+
hydrate: bool = True,
|
3119
|
+
) -> TriggerResponse:
|
3120
|
+
"""Get a trigger by ID.
|
3121
|
+
|
3122
|
+
Args:
|
3123
|
+
trigger_id: The ID of the trigger to get.
|
3124
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
3125
|
+
by including metadata fields in the response.
|
3126
|
+
|
3127
|
+
Returns:
|
3128
|
+
The trigger.
|
3129
|
+
"""
|
3130
|
+
return self._get_resource(
|
3131
|
+
resource_id=trigger_id,
|
3132
|
+
route=TRIGGERS,
|
3133
|
+
response_model=TriggerResponse,
|
3134
|
+
params={"hydrate": hydrate},
|
3135
|
+
)
|
3136
|
+
|
3137
|
+
def list_triggers(
|
3138
|
+
self,
|
3139
|
+
trigger_filter_model: TriggerFilter,
|
3140
|
+
hydrate: bool = False,
|
3141
|
+
) -> Page[TriggerResponse]:
|
3142
|
+
"""List all triggers matching the given filter criteria.
|
3143
|
+
|
3144
|
+
Args:
|
3145
|
+
trigger_filter_model: All filter parameters including pagination
|
3146
|
+
params.
|
3147
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
3148
|
+
by including metadata fields in the response.
|
3149
|
+
|
3150
|
+
Returns:
|
3151
|
+
A list of all triggers matching the filter criteria.
|
3152
|
+
"""
|
3153
|
+
return self._list_paginated_resources(
|
3154
|
+
route=TRIGGERS,
|
3155
|
+
response_model=TriggerResponse,
|
3156
|
+
filter_model=trigger_filter_model,
|
3157
|
+
params={"hydrate": hydrate},
|
3158
|
+
)
|
3159
|
+
|
3160
|
+
def update_trigger(
|
3161
|
+
self,
|
3162
|
+
trigger_id: UUID,
|
3163
|
+
trigger_update: TriggerUpdate,
|
3164
|
+
) -> TriggerResponse:
|
3165
|
+
"""Update an existing trigger.
|
3166
|
+
|
3167
|
+
Args:
|
3168
|
+
trigger_id: The ID of the trigger to update.
|
3169
|
+
trigger_update: The update to be applied to the trigger.
|
3170
|
+
|
3171
|
+
Returns:
|
3172
|
+
The updated trigger.
|
3173
|
+
"""
|
3174
|
+
return self._update_resource(
|
3175
|
+
resource_id=trigger_id,
|
3176
|
+
resource_update=trigger_update,
|
3177
|
+
route=TRIGGERS,
|
3178
|
+
response_model=TriggerResponse,
|
3179
|
+
)
|
3180
|
+
|
3181
|
+
def delete_trigger(self, trigger_id: UUID) -> None:
|
3182
|
+
"""Delete an trigger.
|
3183
|
+
|
3184
|
+
Args:
|
3185
|
+
trigger_id: The ID of the trigger to delete.
|
3186
|
+
"""
|
3187
|
+
self._delete_resource(
|
3188
|
+
resource_id=trigger_id,
|
3189
|
+
route=TRIGGERS,
|
3190
|
+
)
|
3191
|
+
|
3192
|
+
# -------------------- Trigger Executions --------------------
|
3193
|
+
|
3194
|
+
def get_trigger_execution(
|
3195
|
+
self,
|
3196
|
+
trigger_execution_id: UUID,
|
3197
|
+
hydrate: bool = True,
|
3198
|
+
) -> TriggerExecutionResponse:
|
3199
|
+
"""Get an trigger execution by ID.
|
3200
|
+
|
3201
|
+
Args:
|
3202
|
+
trigger_execution_id: The ID of the trigger execution to get.
|
3203
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
3204
|
+
by including metadata fields in the response.
|
3205
|
+
|
3206
|
+
Returns:
|
3207
|
+
The trigger execution.
|
3208
|
+
"""
|
3209
|
+
return self._get_resource(
|
3210
|
+
resource_id=trigger_execution_id,
|
3211
|
+
route=TRIGGER_EXECUTIONS,
|
3212
|
+
response_model=TriggerExecutionResponse,
|
3213
|
+
params={"hydrate": hydrate},
|
3214
|
+
)
|
3215
|
+
|
3216
|
+
def list_trigger_executions(
|
3217
|
+
self,
|
3218
|
+
trigger_execution_filter_model: TriggerExecutionFilter,
|
3219
|
+
hydrate: bool = False,
|
3220
|
+
) -> Page[TriggerExecutionResponse]:
|
3221
|
+
"""List all trigger executions matching the given filter criteria.
|
3222
|
+
|
3223
|
+
Args:
|
3224
|
+
trigger_execution_filter_model: All filter parameters including
|
3225
|
+
pagination params.
|
3226
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
3227
|
+
by including metadata fields in the response.
|
3228
|
+
|
3229
|
+
Returns:
|
3230
|
+
A list of all trigger executions matching the filter criteria.
|
3231
|
+
"""
|
3232
|
+
return self._list_paginated_resources(
|
3233
|
+
route=TRIGGER_EXECUTIONS,
|
3234
|
+
response_model=TriggerExecutionResponse,
|
3235
|
+
filter_model=trigger_execution_filter_model,
|
3236
|
+
params={"hydrate": hydrate},
|
3237
|
+
)
|
3238
|
+
|
3239
|
+
def delete_trigger_execution(self, trigger_execution_id: UUID) -> None:
|
3240
|
+
"""Delete a trigger execution.
|
3241
|
+
|
3242
|
+
Args:
|
3243
|
+
trigger_execution_id: The ID of the trigger execution to delete.
|
3244
|
+
"""
|
3245
|
+
self._delete_resource(
|
3246
|
+
resource_id=trigger_execution_id,
|
3247
|
+
route=TRIGGER_EXECUTIONS,
|
3248
|
+
)
|
3249
|
+
|
2535
3250
|
# ----------------------------- Users -----------------------------
|
2536
3251
|
|
2537
3252
|
def create_user(self, user: UserRequest) -> UserResponse:
|
@@ -2580,7 +3295,7 @@ class RestZenStore(BaseZenStore):
|
|
2580
3295
|
)
|
2581
3296
|
else:
|
2582
3297
|
body = self.get(CURRENT_USER, params={"hydrate": hydrate})
|
2583
|
-
return UserResponse.
|
3298
|
+
return UserResponse.model_validate(body)
|
2584
3299
|
|
2585
3300
|
def list_users(
|
2586
3301
|
self,
|
@@ -2624,6 +3339,23 @@ class RestZenStore(BaseZenStore):
|
|
2624
3339
|
response_model=UserResponse,
|
2625
3340
|
)
|
2626
3341
|
|
3342
|
+
def deactivate_user(
|
3343
|
+
self, user_name_or_id: Union[str, UUID]
|
3344
|
+
) -> UserResponse:
|
3345
|
+
"""Deactivates a user.
|
3346
|
+
|
3347
|
+
Args:
|
3348
|
+
user_name_or_id: The name or ID of the user to delete.
|
3349
|
+
|
3350
|
+
Returns:
|
3351
|
+
The deactivated user containing the activation token.
|
3352
|
+
"""
|
3353
|
+
response_body = self.put(
|
3354
|
+
f"{USERS}/{str(user_name_or_id)}{DEACTIVATE}",
|
3355
|
+
)
|
3356
|
+
|
3357
|
+
return UserResponse.model_validate(response_body)
|
3358
|
+
|
2627
3359
|
def delete_user(self, user_name_or_id: Union[str, UUID]) -> None:
|
2628
3360
|
"""Deletes a user.
|
2629
3361
|
|
@@ -2940,10 +3672,10 @@ class RestZenStore(BaseZenStore):
|
|
2940
3672
|
Returns:
|
2941
3673
|
The newly created model version to artifact link.
|
2942
3674
|
"""
|
2943
|
-
return self.
|
3675
|
+
return self._create_resource(
|
2944
3676
|
resource=model_version_artifact_link,
|
2945
3677
|
response_model=ModelVersionArtifactResponse,
|
2946
|
-
route=
|
3678
|
+
route=MODEL_VERSION_ARTIFACTS,
|
2947
3679
|
)
|
2948
3680
|
|
2949
3681
|
def list_model_version_artifact_links(
|
@@ -3020,10 +3752,10 @@ class RestZenStore(BaseZenStore):
|
|
3020
3752
|
- Otherwise, returns the newly created model version to pipeline
|
3021
3753
|
run link.
|
3022
3754
|
"""
|
3023
|
-
return self.
|
3755
|
+
return self._create_resource(
|
3024
3756
|
resource=model_version_pipeline_run_link,
|
3025
3757
|
response_model=ModelVersionPipelineRunResponse,
|
3026
|
-
route=
|
3758
|
+
route=MODEL_VERSION_PIPELINE_RUNS,
|
3027
3759
|
)
|
3028
3760
|
|
3029
3761
|
def list_model_version_pipeline_run_links(
|
@@ -3141,17 +3873,20 @@ class RestZenStore(BaseZenStore):
|
|
3141
3873
|
|
3142
3874
|
def get_api_token(
|
3143
3875
|
self,
|
3144
|
-
|
3876
|
+
token_type: APITokenType = APITokenType.WORKLOAD,
|
3877
|
+
expires_in: Optional[int] = None,
|
3145
3878
|
schedule_id: Optional[UUID] = None,
|
3146
|
-
|
3879
|
+
pipeline_run_id: Optional[UUID] = None,
|
3880
|
+
step_run_id: Optional[UUID] = None,
|
3147
3881
|
) -> str:
|
3148
|
-
"""Get an API token
|
3882
|
+
"""Get an API token.
|
3149
3883
|
|
3150
3884
|
Args:
|
3151
|
-
|
3885
|
+
token_type: The type of the token to get.
|
3886
|
+
expires_in: The time in seconds until the token expires.
|
3152
3887
|
schedule_id: The ID of the schedule to get a token for.
|
3153
|
-
|
3154
|
-
|
3888
|
+
pipeline_run_id: The ID of the pipeline run to get a token for.
|
3889
|
+
step_run_id: The ID of the step run to get a token for.
|
3155
3890
|
|
3156
3891
|
Returns:
|
3157
3892
|
The API token.
|
@@ -3159,13 +3894,17 @@ class RestZenStore(BaseZenStore):
|
|
3159
3894
|
Raises:
|
3160
3895
|
ValueError: if the server response is not valid.
|
3161
3896
|
"""
|
3162
|
-
params: Dict[str, Any] = {
|
3163
|
-
|
3164
|
-
|
3897
|
+
params: Dict[str, Any] = {
|
3898
|
+
"token_type": token_type.value,
|
3899
|
+
}
|
3900
|
+
if expires_in:
|
3901
|
+
params["expires_in"] = expires_in
|
3165
3902
|
if schedule_id:
|
3166
3903
|
params["schedule_id"] = schedule_id
|
3167
|
-
if
|
3168
|
-
params["
|
3904
|
+
if pipeline_run_id:
|
3905
|
+
params["pipeline_run_id"] = pipeline_run_id
|
3906
|
+
if step_run_id:
|
3907
|
+
params["step_run_id"] = step_run_id
|
3169
3908
|
response_body = self.get(API_TOKEN, params=params)
|
3170
3909
|
if not isinstance(response_body, str):
|
3171
3910
|
raise ValueError(
|
@@ -3272,104 +4011,282 @@ class RestZenStore(BaseZenStore):
|
|
3272
4011
|
# Internal helper methods
|
3273
4012
|
# =======================
|
3274
4013
|
|
3275
|
-
def
|
3276
|
-
"""Get
|
4014
|
+
def get_or_generate_api_token(self) -> str:
|
4015
|
+
"""Get or generate an API token.
|
3277
4016
|
|
3278
4017
|
Returns:
|
3279
|
-
The
|
4018
|
+
The API token.
|
3280
4019
|
|
3281
4020
|
Raises:
|
3282
|
-
|
3283
|
-
|
3284
|
-
"""
|
3285
|
-
if self._api_token is None:
|
3286
|
-
# Check if
|
3287
|
-
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3291
|
-
self.
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
|
3296
|
-
|
3297
|
-
|
3298
|
-
|
3299
|
-
"
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
|
3304
|
-
|
3305
|
-
|
3306
|
-
|
3307
|
-
|
3308
|
-
|
3309
|
-
|
3310
|
-
|
3311
|
-
|
3312
|
-
|
3313
|
-
|
3314
|
-
data=data,
|
3315
|
-
verify=self.config.verify_ssl,
|
3316
|
-
timeout=self.config.http_timeout,
|
3317
|
-
)
|
4021
|
+
CredentialsNotValid: if an API token cannot be fetched or
|
4022
|
+
generated because the client credentials are not valid.
|
4023
|
+
"""
|
4024
|
+
if self._api_token is None or self._api_token.expired:
|
4025
|
+
# Check if a valid API token is already in the cache
|
4026
|
+
credentials_store = get_credentials_store()
|
4027
|
+
credentials = credentials_store.get_credentials(self.url)
|
4028
|
+
token = credentials.api_token if credentials else None
|
4029
|
+
if credentials and token and not token.expired:
|
4030
|
+
self._api_token = token
|
4031
|
+
|
4032
|
+
# Populate the server info in the credentials store if it is
|
4033
|
+
# not already present
|
4034
|
+
if not credentials.server_id:
|
4035
|
+
try:
|
4036
|
+
server_info = self.get_store_info()
|
4037
|
+
except Exception as e:
|
4038
|
+
logger.warning(f"Failed to get server info: {e}.")
|
4039
|
+
else:
|
4040
|
+
credentials_store.update_server_info(
|
4041
|
+
self.url, server_info
|
4042
|
+
)
|
4043
|
+
|
4044
|
+
return self._api_token.access_token
|
4045
|
+
|
4046
|
+
# Token is expired or not found in the cache. Time to get a new one.
|
4047
|
+
|
4048
|
+
if not token:
|
4049
|
+
logger.debug(f"Authenticating to {self.url}")
|
4050
|
+
else:
|
4051
|
+
logger.debug(
|
4052
|
+
f"Authentication token for {self.url} expired; refreshing..."
|
3318
4053
|
)
|
3319
|
-
|
3320
|
-
|
3321
|
-
|
3322
|
-
|
3323
|
-
|
3324
|
-
|
3325
|
-
|
4054
|
+
|
4055
|
+
data: Optional[Dict[str, str]] = None
|
4056
|
+
|
4057
|
+
# Use a custom user agent to identify the ZenML client in the server
|
4058
|
+
# logs.
|
4059
|
+
headers: Dict[str, str] = {
|
4060
|
+
"User-Agent": "zenml/" + zenml.__version__,
|
4061
|
+
}
|
4062
|
+
|
4063
|
+
# Check if an API key is configured
|
4064
|
+
api_key = credentials_store.get_api_key(self.url)
|
4065
|
+
|
4066
|
+
# Check if username and password are configured
|
4067
|
+
username, password = credentials_store.get_password(self.url)
|
4068
|
+
|
4069
|
+
api_key_hint = (
|
4070
|
+
"\nHint: If you're getting this error in an automated, "
|
4071
|
+
"non-interactive workload like a pipeline run or a CI/CD job, "
|
4072
|
+
"you should use a service account API key to authenticate to "
|
4073
|
+
"the server instead of temporary CLI login credentials. For "
|
4074
|
+
"more information, see "
|
4075
|
+
"https://docs.zenml.io/how-to/project-setup-and-management/connecting-to-zenml/connect-with-a-service-account"
|
4076
|
+
)
|
4077
|
+
|
4078
|
+
if api_key is not None:
|
4079
|
+
# An API key is configured. Use it as a password to
|
4080
|
+
# authenticate.
|
4081
|
+
data = {
|
4082
|
+
"grant_type": OAuthGrantTypes.ZENML_API_KEY.value,
|
4083
|
+
"password": api_key,
|
4084
|
+
}
|
4085
|
+
elif username is not None and password is not None:
|
4086
|
+
# Username and password are configured. Use them to authenticate.
|
4087
|
+
data = {
|
4088
|
+
"grant_type": OAuthGrantTypes.OAUTH_PASSWORD.value,
|
4089
|
+
"username": username,
|
4090
|
+
"password": password,
|
4091
|
+
}
|
4092
|
+
elif is_zenml_pro_server_url(self.url):
|
4093
|
+
# ZenML Pro tenants use a proprietary authorization grant
|
4094
|
+
# where the ZenML Pro API session token is exchanged for a
|
4095
|
+
# regular ZenML server access token.
|
4096
|
+
|
4097
|
+
# Get the ZenML Pro API session token, if cached and valid
|
4098
|
+
pro_token = credentials_store.get_pro_token(allow_expired=True)
|
4099
|
+
if not pro_token:
|
4100
|
+
raise CredentialsNotValid(
|
4101
|
+
"You need to be logged in to ZenML Pro in order to "
|
4102
|
+
f"access the ZenML Pro server '{self.url}'. Please run "
|
4103
|
+
"'zenml login' to log in or choose a different server."
|
4104
|
+
+ api_key_hint
|
4105
|
+
)
|
4106
|
+
|
4107
|
+
elif pro_token.expired:
|
4108
|
+
raise CredentialsNotValid(
|
4109
|
+
"Your ZenML Pro login session has expired. "
|
4110
|
+
"Please log in again using 'zenml login'."
|
4111
|
+
+ api_key_hint
|
3326
4112
|
)
|
3327
|
-
|
3328
|
-
|
4113
|
+
|
4114
|
+
data = {
|
4115
|
+
"grant_type": OAuthGrantTypes.ZENML_EXTERNAL.value,
|
4116
|
+
}
|
4117
|
+
headers.update(
|
4118
|
+
{"Authorization": "Bearer " + pro_token.access_token}
|
4119
|
+
)
|
3329
4120
|
else:
|
3330
|
-
|
3331
|
-
|
3332
|
-
|
3333
|
-
|
4121
|
+
if not token:
|
4122
|
+
raise CredentialsNotValid(
|
4123
|
+
"No valid credentials found. Please run 'zenml login "
|
4124
|
+
f"--url {self.url}' to connect to the current server."
|
4125
|
+
+ api_key_hint
|
4126
|
+
)
|
4127
|
+
elif token.expired:
|
4128
|
+
raise CredentialsNotValid(
|
4129
|
+
"Your authentication to the current server has expired. "
|
4130
|
+
"Please log in again using 'zenml login --url "
|
4131
|
+
f"{self.url}'." + api_key_hint
|
4132
|
+
)
|
4133
|
+
|
4134
|
+
response = self._handle_response(
|
4135
|
+
requests.post(
|
4136
|
+
self.url + API + VERSION_1 + LOGIN,
|
4137
|
+
data=data,
|
4138
|
+
verify=self.config.verify_ssl,
|
4139
|
+
timeout=self.config.http_timeout,
|
4140
|
+
headers=headers,
|
3334
4141
|
)
|
3335
|
-
|
4142
|
+
)
|
4143
|
+
try:
|
4144
|
+
token_response = OAuthTokenResponse.model_validate(response)
|
4145
|
+
except ValidationError as e:
|
4146
|
+
raise CredentialsNotValid(
|
4147
|
+
"Unexpected response received while authenticating to "
|
4148
|
+
f"the server {e}"
|
4149
|
+
) from e
|
4150
|
+
|
4151
|
+
# Cache the token
|
4152
|
+
self._api_token = credentials_store.set_token(
|
4153
|
+
self.url, token_response
|
4154
|
+
)
|
4155
|
+
|
4156
|
+
# Update the server info in the credentials store with the latest
|
4157
|
+
# information from the server.
|
4158
|
+
# NOTE: this is the best place to do this because we know that
|
4159
|
+
# the token is valid and the server is reachable.
|
4160
|
+
try:
|
4161
|
+
server_info = self.get_store_info()
|
4162
|
+
except Exception as e:
|
4163
|
+
logger.warning(f"Failed to get server info: {e}.")
|
4164
|
+
else:
|
4165
|
+
credentials_store.update_server_info(self.url, server_info)
|
4166
|
+
|
4167
|
+
return self._api_token.access_token
|
3336
4168
|
|
3337
4169
|
@property
|
3338
4170
|
def session(self) -> requests.Session:
|
3339
|
-
"""
|
4171
|
+
"""Initialize and return a requests session.
|
3340
4172
|
|
3341
4173
|
Returns:
|
3342
|
-
A requests session
|
4174
|
+
A requests session.
|
3343
4175
|
"""
|
3344
4176
|
if self._session is None:
|
4177
|
+
# We only need to initialize the session once over the lifetime
|
4178
|
+
# of the client. We can swap the token out when it expires.
|
3345
4179
|
if self.config.verify_ssl is False:
|
3346
4180
|
urllib3.disable_warnings(
|
3347
4181
|
urllib3.exceptions.InsecureRequestWarning
|
3348
4182
|
)
|
3349
4183
|
|
3350
4184
|
self._session = requests.Session()
|
3351
|
-
|
4185
|
+
# Retries are triggered for idempotent HTTP methods (GET, HEAD, PUT,
|
4186
|
+
# OPTIONS and DELETE) on specific HTTP status codes:
|
4187
|
+
#
|
4188
|
+
# 500: Internal Server Error.
|
4189
|
+
# 502: Bad Gateway.
|
4190
|
+
# 503: Service Unavailable.
|
4191
|
+
# 504: Gateway Timeout.
|
4192
|
+
#
|
4193
|
+
# This also handles connection level errors, if a connection attempt
|
4194
|
+
# fails due to transient issues like:
|
4195
|
+
#
|
4196
|
+
# DNS resolution errors.
|
4197
|
+
# Connection timeouts.
|
4198
|
+
# Network disruptions.
|
4199
|
+
#
|
4200
|
+
# Additional errors retried:
|
4201
|
+
#
|
4202
|
+
# Read Timeouts: If the server does not send a response within
|
4203
|
+
# the timeout period.
|
4204
|
+
# Connection Refused: If the server refuses the connection.
|
4205
|
+
#
|
4206
|
+
retries = Retry(
|
4207
|
+
connect=5,
|
4208
|
+
read=8,
|
4209
|
+
redirect=3,
|
4210
|
+
status=10,
|
4211
|
+
allowed_methods=["HEAD", "GET", "PUT", "DELETE", "OPTIONS"],
|
4212
|
+
status_forcelist=[
|
4213
|
+
408, # Request Timeout
|
4214
|
+
429, # Too Many Requests
|
4215
|
+
500, # Internal Server Error
|
4216
|
+
502, # Bad Gateway
|
4217
|
+
503, # Service Unavailable
|
4218
|
+
504, # Gateway Timeout
|
4219
|
+
],
|
4220
|
+
other=3,
|
4221
|
+
backoff_factor=0.5,
|
4222
|
+
)
|
3352
4223
|
self._session.mount("https://", HTTPAdapter(max_retries=retries))
|
3353
4224
|
self._session.mount("http://", HTTPAdapter(max_retries=retries))
|
3354
4225
|
self._session.verify = self.config.verify_ssl
|
3355
|
-
|
3356
|
-
|
3357
|
-
|
4226
|
+
# Use a custom user agent to identify the ZenML client in the server
|
4227
|
+
# logs.
|
4228
|
+
self._session.headers.update(
|
4229
|
+
{"User-Agent": "zenml/" + zenml.__version__}
|
4230
|
+
)
|
4231
|
+
|
4232
|
+
# Note that we return an unauthenticated session here. An API token
|
4233
|
+
# is only fetched and set in the authorization header when and if it is
|
4234
|
+
# needed.
|
3358
4235
|
return self._session
|
3359
4236
|
|
3360
|
-
def
|
3361
|
-
"""
|
3362
|
-
|
4237
|
+
def authenticate(self, force: bool = False) -> None:
|
4238
|
+
"""Authenticate or re-authenticate to the ZenML server.
|
4239
|
+
|
4240
|
+
Args:
|
4241
|
+
force: If True, force a re-authentication even if a valid API token
|
4242
|
+
is currently cached. This is useful when the current API token
|
4243
|
+
is known to be invalid or expired.
|
4244
|
+
"""
|
4245
|
+
# This is called to trigger an authentication flow, either because
|
4246
|
+
# the current API token is expired or no longer valid, or because
|
4247
|
+
# a configuration change has happened or merely because an
|
4248
|
+
# authentication was never attempted before.
|
4249
|
+
#
|
4250
|
+
# 1. Drop the API token currently being used, if any.
|
4251
|
+
# 2. If force=True, clear the current API token from the credentials
|
4252
|
+
# store, if any, otherwise it will just be re-used on the next call.
|
4253
|
+
# 3. Get a new API token
|
4254
|
+
|
4255
|
+
# The authentication token could have expired or invalidated through
|
4256
|
+
# other means; refresh it and try again. This will clear any cached
|
4257
|
+
# token and trigger a new authentication flow.
|
4258
|
+
if self._api_token and not force:
|
4259
|
+
if self._api_token.expired:
|
4260
|
+
logger.info(
|
4261
|
+
"Authentication session expired; attempting to "
|
4262
|
+
"re-authenticate."
|
4263
|
+
)
|
4264
|
+
else:
|
4265
|
+
logger.info(
|
4266
|
+
"Authentication session was invalidated by the server; "
|
4267
|
+
"This can happen for example if the user's permissions "
|
4268
|
+
"have been revoked or if the server has been restarted "
|
4269
|
+
"and lost its session state. Attempting to "
|
4270
|
+
"re-authenticate."
|
4271
|
+
)
|
4272
|
+
else:
|
4273
|
+
if force:
|
4274
|
+
# Clear the current API token from the credentials store, if
|
4275
|
+
# any, to force a new authentication flow.
|
4276
|
+
get_credentials_store().clear_token(self.url)
|
4277
|
+
# Never authenticated since the client was created or the API token
|
4278
|
+
# was explicitly cleared.
|
4279
|
+
logger.debug(f"Authenticating to {self.url}...")
|
4280
|
+
|
3363
4281
|
self._api_token = None
|
3364
|
-
|
3365
|
-
|
3366
|
-
|
3367
|
-
|
3368
|
-
|
3369
|
-
|
3370
|
-
|
3371
|
-
)
|
3372
|
-
self.config.api_token = None
|
4282
|
+
|
4283
|
+
new_api_token = self.get_or_generate_api_token()
|
4284
|
+
|
4285
|
+
# Set or refresh the authentication token
|
4286
|
+
self.session.headers.update(
|
4287
|
+
{"Authorization": "Bearer " + new_api_token}
|
4288
|
+
)
|
4289
|
+
logger.debug(f"Authenticated to {self.url}")
|
3373
4290
|
|
3374
4291
|
@staticmethod
|
3375
4292
|
def _handle_response(response: requests.Response) -> Json:
|
@@ -3417,6 +4334,7 @@ class RestZenStore(BaseZenStore):
|
|
3417
4334
|
method: str,
|
3418
4335
|
url: str,
|
3419
4336
|
params: Optional[Dict[str, Any]] = None,
|
4337
|
+
timeout: Optional[int] = None,
|
3420
4338
|
**kwargs: Any,
|
3421
4339
|
) -> Json:
|
3422
4340
|
"""Make a request to the REST API.
|
@@ -3425,14 +4343,15 @@ class RestZenStore(BaseZenStore):
|
|
3425
4343
|
method: The HTTP method to use.
|
3426
4344
|
url: The URL to request.
|
3427
4345
|
params: The query parameters to pass to the endpoint.
|
4346
|
+
timeout: The request timeout in seconds.
|
3428
4347
|
kwargs: Additional keyword arguments to pass to the request.
|
3429
4348
|
|
3430
4349
|
Returns:
|
3431
4350
|
The parsed response.
|
3432
4351
|
|
3433
4352
|
Raises:
|
3434
|
-
|
3435
|
-
|
4353
|
+
CredentialsNotValid: if the request fails due to invalid
|
4354
|
+
client credentials.
|
3436
4355
|
"""
|
3437
4356
|
params = {k: str(v) for k, v in params.items()} if params else {}
|
3438
4357
|
|
@@ -3440,49 +4359,88 @@ class RestZenStore(BaseZenStore):
|
|
3440
4359
|
{source_context.name: source_context.get().value}
|
3441
4360
|
)
|
3442
4361
|
|
3443
|
-
|
3444
|
-
|
3445
|
-
|
3446
|
-
|
3447
|
-
|
3448
|
-
|
3449
|
-
|
3450
|
-
|
3451
|
-
|
3452
|
-
|
3453
|
-
|
3454
|
-
|
3455
|
-
|
3456
|
-
|
3457
|
-
|
3458
|
-
|
3459
|
-
|
3460
|
-
|
3461
|
-
|
3462
|
-
|
3463
|
-
|
3464
|
-
|
3465
|
-
|
3466
|
-
|
3467
|
-
|
3468
|
-
|
3469
|
-
**kwargs,
|
4362
|
+
# If the server replies with a credentials validation (401 Unauthorized)
|
4363
|
+
# error, we (re-)authenticate and retry the request here in the
|
4364
|
+
# following cases:
|
4365
|
+
#
|
4366
|
+
# 1. initial authentication: the last request was not authenticated
|
4367
|
+
# with an API token.
|
4368
|
+
# 2. re-authentication: the last request was authenticated with an API
|
4369
|
+
# token that was rejected by the server. This is to cover the case
|
4370
|
+
# of expired tokens that can be refreshed by the client automatically
|
4371
|
+
# without user intervention from other sources (e.g. API keys).
|
4372
|
+
#
|
4373
|
+
# NOTE: it can happen that the same request is retried here for up to
|
4374
|
+
# two times: once after initial authentication and once after
|
4375
|
+
# re-authentication.
|
4376
|
+
re_authenticated = False
|
4377
|
+
while True:
|
4378
|
+
try:
|
4379
|
+
return self._handle_response(
|
4380
|
+
self.session.request(
|
4381
|
+
method,
|
4382
|
+
url,
|
4383
|
+
params=params,
|
4384
|
+
verify=self.config.verify_ssl,
|
4385
|
+
timeout=timeout or self.config.http_timeout,
|
4386
|
+
**kwargs,
|
4387
|
+
)
|
3470
4388
|
)
|
3471
|
-
|
3472
|
-
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3476
|
-
|
4389
|
+
except CredentialsNotValid as e:
|
4390
|
+
# NOTE: CredentialsNotValid is raised only when the server
|
4391
|
+
# explicitly indicates that the credentials are not valid and
|
4392
|
+
# they can be thrown away or when the request is not
|
4393
|
+
# authenticated at all.
|
4394
|
+
|
4395
|
+
if self._api_token is None:
|
4396
|
+
# The last request was not authenticated with an API
|
4397
|
+
# token at all. We authenticate here and then try the
|
4398
|
+
# request again, this time with a valid API token in the
|
4399
|
+
# header.
|
4400
|
+
logger.debug(
|
4401
|
+
f"The last request was not authenticated: {e}\n"
|
4402
|
+
"Re-authenticating and retrying..."
|
4403
|
+
)
|
4404
|
+
self.authenticate()
|
4405
|
+
elif not re_authenticated:
|
4406
|
+
# The last request was authenticated with an API token
|
4407
|
+
# that was rejected by the server. We attempt a
|
4408
|
+
# re-authentication here and then retry the request.
|
4409
|
+
logger.debug(
|
4410
|
+
"The last request was authenticated with an API token "
|
4411
|
+
f"that was rejected by the server: {e}\n"
|
4412
|
+
"Re-authenticating and retrying..."
|
4413
|
+
)
|
4414
|
+
re_authenticated = True
|
4415
|
+
self.authenticate(
|
4416
|
+
# Ignore the current token and force a re-authentication
|
4417
|
+
force=True
|
4418
|
+
)
|
4419
|
+
else:
|
4420
|
+
# The last request was made after re-authenticating but
|
4421
|
+
# still failed. Bailing out.
|
4422
|
+
logger.debug(
|
4423
|
+
f"The last request failed after re-authenticating: {e}\n"
|
4424
|
+
"Bailing out..."
|
4425
|
+
)
|
4426
|
+
raise CredentialsNotValid(
|
4427
|
+
"The current credentials are no longer valid. Please "
|
4428
|
+
"log in again using 'zenml login'."
|
4429
|
+
) from e
|
3477
4430
|
|
3478
4431
|
def get(
|
3479
|
-
self,
|
4432
|
+
self,
|
4433
|
+
path: str,
|
4434
|
+
params: Optional[Dict[str, Any]] = None,
|
4435
|
+
timeout: Optional[int] = None,
|
4436
|
+
**kwargs: Any,
|
3480
4437
|
) -> Json:
|
3481
4438
|
"""Make a GET request to the given endpoint path.
|
3482
4439
|
|
3483
4440
|
Args:
|
3484
4441
|
path: The path to the endpoint.
|
3485
4442
|
params: The query parameters to pass to the endpoint.
|
4443
|
+
timeout: The request timeout in seconds.
|
3486
4444
|
kwargs: Additional keyword arguments to pass to the request.
|
3487
4445
|
|
3488
4446
|
Returns:
|
@@ -3490,17 +4448,26 @@ class RestZenStore(BaseZenStore):
|
|
3490
4448
|
"""
|
3491
4449
|
logger.debug(f"Sending GET request to {path}...")
|
3492
4450
|
return self._request(
|
3493
|
-
"GET",
|
4451
|
+
"GET",
|
4452
|
+
self.url + API + VERSION_1 + path,
|
4453
|
+
params=params,
|
4454
|
+
timeout=timeout,
|
4455
|
+
**kwargs,
|
3494
4456
|
)
|
3495
4457
|
|
3496
4458
|
def delete(
|
3497
|
-
self,
|
4459
|
+
self,
|
4460
|
+
path: str,
|
4461
|
+
params: Optional[Dict[str, Any]] = None,
|
4462
|
+
timeout: Optional[int] = None,
|
4463
|
+
**kwargs: Any,
|
3498
4464
|
) -> Json:
|
3499
4465
|
"""Make a DELETE request to the given endpoint path.
|
3500
4466
|
|
3501
4467
|
Args:
|
3502
4468
|
path: The path to the endpoint.
|
3503
4469
|
params: The query parameters to pass to the endpoint.
|
4470
|
+
timeout: The request timeout in seconds.
|
3504
4471
|
kwargs: Additional keyword arguments to pass to the request.
|
3505
4472
|
|
3506
4473
|
Returns:
|
@@ -3511,6 +4478,7 @@ class RestZenStore(BaseZenStore):
|
|
3511
4478
|
"DELETE",
|
3512
4479
|
self.url + API + VERSION_1 + path,
|
3513
4480
|
params=params,
|
4481
|
+
timeout=timeout,
|
3514
4482
|
**kwargs,
|
3515
4483
|
)
|
3516
4484
|
|
@@ -3519,6 +4487,7 @@ class RestZenStore(BaseZenStore):
|
|
3519
4487
|
path: str,
|
3520
4488
|
body: BaseModel,
|
3521
4489
|
params: Optional[Dict[str, Any]] = None,
|
4490
|
+
timeout: Optional[int] = None,
|
3522
4491
|
**kwargs: Any,
|
3523
4492
|
) -> Json:
|
3524
4493
|
"""Make a POST request to the given endpoint path.
|
@@ -3527,6 +4496,7 @@ class RestZenStore(BaseZenStore):
|
|
3527
4496
|
path: The path to the endpoint.
|
3528
4497
|
body: The body to send.
|
3529
4498
|
params: The query parameters to pass to the endpoint.
|
4499
|
+
timeout: The request timeout in seconds.
|
3530
4500
|
kwargs: Additional keyword arguments to pass to the request.
|
3531
4501
|
|
3532
4502
|
Returns:
|
@@ -3536,8 +4506,9 @@ class RestZenStore(BaseZenStore):
|
|
3536
4506
|
return self._request(
|
3537
4507
|
"POST",
|
3538
4508
|
self.url + API + VERSION_1 + path,
|
3539
|
-
|
4509
|
+
json=body.model_dump(mode="json"),
|
3540
4510
|
params=params,
|
4511
|
+
timeout=timeout,
|
3541
4512
|
**kwargs,
|
3542
4513
|
)
|
3543
4514
|
|
@@ -3546,6 +4517,7 @@ class RestZenStore(BaseZenStore):
|
|
3546
4517
|
path: str,
|
3547
4518
|
body: Optional[BaseModel] = None,
|
3548
4519
|
params: Optional[Dict[str, Any]] = None,
|
4520
|
+
timeout: Optional[int] = None,
|
3549
4521
|
**kwargs: Any,
|
3550
4522
|
) -> Json:
|
3551
4523
|
"""Make a PUT request to the given endpoint path.
|
@@ -3554,18 +4526,22 @@ class RestZenStore(BaseZenStore):
|
|
3554
4526
|
path: The path to the endpoint.
|
3555
4527
|
body: The body to send.
|
3556
4528
|
params: The query parameters to pass to the endpoint.
|
4529
|
+
timeout: The request timeout in seconds.
|
3557
4530
|
kwargs: Additional keyword arguments to pass to the request.
|
3558
4531
|
|
3559
4532
|
Returns:
|
3560
4533
|
The response body.
|
3561
4534
|
"""
|
3562
4535
|
logger.debug(f"Sending PUT request to {path}...")
|
3563
|
-
|
4536
|
+
json = (
|
4537
|
+
body.model_dump(mode="json", exclude_unset=True) if body else None
|
4538
|
+
)
|
3564
4539
|
return self._request(
|
3565
4540
|
"PUT",
|
3566
4541
|
self.url + API + VERSION_1 + path,
|
3567
|
-
|
4542
|
+
json=json,
|
3568
4543
|
params=params,
|
4544
|
+
timeout=timeout,
|
3569
4545
|
**kwargs,
|
3570
4546
|
)
|
3571
4547
|
|
@@ -3589,7 +4565,42 @@ class RestZenStore(BaseZenStore):
|
|
3589
4565
|
The created resource.
|
3590
4566
|
"""
|
3591
4567
|
response_body = self.post(f"{route}", body=resource, params=params)
|
3592
|
-
|
4568
|
+
|
4569
|
+
return response_model.model_validate(response_body)
|
4570
|
+
|
4571
|
+
def _batch_create_resources(
|
4572
|
+
self,
|
4573
|
+
resources: List[AnyRequest],
|
4574
|
+
response_model: Type[AnyResponse],
|
4575
|
+
route: str,
|
4576
|
+
params: Optional[Dict[str, Any]] = None,
|
4577
|
+
) -> List[AnyResponse]:
|
4578
|
+
"""Create a new batch of resources.
|
4579
|
+
|
4580
|
+
Args:
|
4581
|
+
resources: The resources to create.
|
4582
|
+
response_model: The response model of an individual resource.
|
4583
|
+
route: The resource REST route to use.
|
4584
|
+
params: Optional query parameters to pass to the endpoint.
|
4585
|
+
|
4586
|
+
Returns:
|
4587
|
+
List of response models.
|
4588
|
+
"""
|
4589
|
+
json_data = [
|
4590
|
+
resource.model_dump(mode="json") for resource in resources
|
4591
|
+
]
|
4592
|
+
response = self._request(
|
4593
|
+
"POST",
|
4594
|
+
self.url + API + VERSION_1 + route + BATCH,
|
4595
|
+
json=json_data,
|
4596
|
+
params=params,
|
4597
|
+
)
|
4598
|
+
assert isinstance(response, list)
|
4599
|
+
|
4600
|
+
return [
|
4601
|
+
response_model.model_validate(model_data)
|
4602
|
+
for model_data in response
|
4603
|
+
]
|
3593
4604
|
|
3594
4605
|
def _create_workspace_scoped_resource(
|
3595
4606
|
self,
|
@@ -3665,7 +4676,7 @@ class RestZenStore(BaseZenStore):
|
|
3665
4676
|
f"response from the {route}{GET_OR_CREATE} endpoint but got "
|
3666
4677
|
f"{type(was_created)} instead."
|
3667
4678
|
)
|
3668
|
-
return response_model.
|
4679
|
+
return response_model.model_validate(model_json), was_created
|
3669
4680
|
|
3670
4681
|
def _get_or_create_workspace_scoped_resource(
|
3671
4682
|
self,
|
@@ -3713,7 +4724,7 @@ class RestZenStore(BaseZenStore):
|
|
3713
4724
|
The retrieved resource.
|
3714
4725
|
"""
|
3715
4726
|
body = self.get(f"{route}/{str(resource_id)}", params=params)
|
3716
|
-
return response_model.
|
4727
|
+
return response_model.model_validate(body)
|
3717
4728
|
|
3718
4729
|
def _list_paginated_resources(
|
3719
4730
|
self,
|
@@ -3738,17 +4749,17 @@ class RestZenStore(BaseZenStore):
|
|
3738
4749
|
"""
|
3739
4750
|
# leave out filter params that are not supplied
|
3740
4751
|
params = params or {}
|
3741
|
-
params.update(filter_model.
|
4752
|
+
params.update(filter_model.model_dump(exclude_none=True))
|
3742
4753
|
body = self.get(f"{route}", params=params)
|
3743
4754
|
if not isinstance(body, dict):
|
3744
4755
|
raise ValueError(
|
3745
4756
|
f"Bad API Response. Expected list, got {type(body)}"
|
3746
4757
|
)
|
3747
4758
|
# The initial page of items will be of type BaseResponseModel
|
3748
|
-
page_of_items: Page[AnyResponse] = Page.
|
4759
|
+
page_of_items: Page[AnyResponse] = Page.model_validate(body)
|
3749
4760
|
# So these items will be parsed into their correct types like here
|
3750
4761
|
page_of_items.items = [
|
3751
|
-
response_model.
|
4762
|
+
response_model.model_validate(generic_item)
|
3752
4763
|
for generic_item in body["items"]
|
3753
4764
|
]
|
3754
4765
|
return page_of_items
|
@@ -3779,7 +4790,7 @@ class RestZenStore(BaseZenStore):
|
|
3779
4790
|
raise ValueError(
|
3780
4791
|
f"Bad API Response. Expected list, got {type(body)}"
|
3781
4792
|
)
|
3782
|
-
return [response_model.
|
4793
|
+
return [response_model.model_validate(entry) for entry in body]
|
3783
4794
|
|
3784
4795
|
def _update_resource(
|
3785
4796
|
self,
|
@@ -3806,7 +4817,7 @@ class RestZenStore(BaseZenStore):
|
|
3806
4817
|
f"{route}/{str(resource_id)}", body=resource_update, params=params
|
3807
4818
|
)
|
3808
4819
|
|
3809
|
-
return response_model.
|
4820
|
+
return response_model.model_validate(response_body)
|
3810
4821
|
|
3811
4822
|
def _delete_resource(
|
3812
4823
|
self, resource_id: Union[str, UUID], route: str
|