zenml-nightly 0.58.2.dev20240618__py3-none-any.whl → 0.58.2.dev20240619__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/_hub/client.py +8 -5
- zenml/actions/base_action.py +8 -10
- zenml/artifact_stores/base_artifact_store.py +20 -15
- zenml/artifact_stores/local_artifact_store.py +3 -2
- zenml/artifacts/artifact_config.py +34 -19
- zenml/artifacts/external_artifact.py +18 -8
- zenml/artifacts/external_artifact_config.py +14 -6
- zenml/artifacts/unmaterialized_artifact.py +2 -11
- zenml/cli/__init__.py +6 -0
- zenml/cli/artifact.py +20 -2
- zenml/cli/served_model.py +0 -1
- zenml/cli/server.py +3 -3
- zenml/cli/utils.py +36 -40
- zenml/cli/web_login.py +2 -2
- zenml/client.py +198 -24
- zenml/client_lazy_loader.py +20 -14
- zenml/config/base_settings.py +5 -6
- zenml/config/build_configuration.py +1 -1
- zenml/config/compiler.py +3 -3
- zenml/config/docker_settings.py +27 -28
- zenml/config/global_config.py +33 -37
- zenml/config/pipeline_configurations.py +8 -11
- zenml/config/pipeline_run_configuration.py +6 -2
- zenml/config/pipeline_spec.py +3 -4
- zenml/config/resource_settings.py +8 -9
- zenml/config/schedule.py +16 -20
- zenml/config/secret_reference_mixin.py +6 -3
- zenml/config/secrets_store_config.py +16 -23
- zenml/config/server_config.py +50 -46
- zenml/config/settings_resolver.py +1 -1
- zenml/config/source.py +45 -35
- zenml/config/step_configurations.py +53 -31
- zenml/config/store_config.py +20 -19
- zenml/config/strict_base_model.py +2 -6
- zenml/constants.py +26 -2
- zenml/container_registries/base_container_registry.py +3 -2
- zenml/container_registries/default_container_registry.py +3 -3
- zenml/event_hub/base_event_hub.py +1 -1
- zenml/event_sources/base_event_source.py +11 -16
- zenml/exceptions.py +4 -0
- zenml/integrations/airflow/__init__.py +2 -10
- zenml/integrations/airflow/flavors/airflow_orchestrator_flavor.py +6 -7
- zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +13 -249
- zenml/integrations/airflow/orchestrators/dag_generator.py +5 -3
- zenml/integrations/argilla/flavors/argilla_annotator_flavor.py +5 -4
- zenml/integrations/aws/__init__.py +1 -1
- zenml/integrations/aws/flavors/aws_container_registry_flavor.py +3 -2
- zenml/integrations/aws/flavors/sagemaker_orchestrator_flavor.py +11 -5
- zenml/integrations/aws/flavors/sagemaker_step_operator_flavor.py +6 -2
- zenml/integrations/aws/service_connectors/aws_service_connector.py +5 -4
- zenml/integrations/azure/flavors/azureml_step_operator_flavor.py +4 -4
- zenml/integrations/azure/service_connectors/azure_service_connector.py +4 -3
- zenml/integrations/azure/step_operators/azureml_step_operator.py +1 -1
- zenml/integrations/bentoml/steps/bentoml_deployer.py +1 -1
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +8 -12
- zenml/integrations/comet/flavors/comet_experiment_tracker_flavor.py +1 -1
- zenml/integrations/evidently/__init__.py +3 -4
- zenml/integrations/evidently/column_mapping.py +11 -3
- zenml/integrations/evidently/data_validators/evidently_data_validator.py +21 -3
- zenml/integrations/evidently/metrics.py +5 -6
- zenml/integrations/evidently/tests.py +5 -6
- zenml/integrations/facets/models.py +2 -6
- zenml/integrations/feast/__init__.py +3 -1
- zenml/integrations/feast/feature_stores/feast_feature_store.py +0 -23
- zenml/integrations/gcp/__init__.py +1 -1
- zenml/integrations/gcp/flavors/vertex_orchestrator_flavor.py +1 -1
- zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py +1 -1
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +234 -103
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +57 -42
- zenml/integrations/github/code_repositories/github_code_repository.py +1 -1
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +9 -13
- zenml/integrations/great_expectations/__init__.py +1 -1
- zenml/integrations/great_expectations/data_validators/ge_data_validator.py +44 -44
- 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 +3 -3
- zenml/integrations/great_expectations/utils.py +5 -5
- zenml/integrations/huggingface/__init__.py +3 -0
- zenml/integrations/huggingface/flavors/huggingface_model_deployer_flavor.py +1 -1
- zenml/integrations/huggingface/steps/__init__.py +3 -0
- zenml/integrations/huggingface/steps/accelerate_runner.py +149 -0
- zenml/integrations/huggingface/steps/huggingface_deployer.py +2 -2
- zenml/integrations/hyperai/flavors/hyperai_orchestrator_flavor.py +1 -1
- zenml/integrations/hyperai/service_connectors/hyperai_service_connector.py +4 -3
- zenml/integrations/kubeflow/__init__.py +1 -1
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +48 -81
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +295 -245
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +1 -1
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +11 -2
- zenml/integrations/kubernetes/pod_settings.py +17 -31
- zenml/integrations/kubernetes/service_connectors/kubernetes_service_connector.py +8 -7
- zenml/integrations/label_studio/__init__.py +1 -3
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +3 -4
- zenml/integrations/label_studio/flavors/label_studio_annotator_flavor.py +2 -2
- zenml/integrations/langchain/materializers/document_materializer.py +44 -8
- zenml/integrations/mlflow/__init__.py +9 -3
- zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +1 -1
- zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +29 -37
- zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +4 -4
- zenml/integrations/mlflow/steps/mlflow_deployer.py +1 -1
- zenml/integrations/neptune/flavors/neptune_experiment_tracker_flavor.py +1 -1
- zenml/integrations/pigeon/flavors/pigeon_annotator_flavor.py +1 -1
- zenml/integrations/s3/flavors/s3_artifact_store_flavor.py +9 -8
- zenml/integrations/seldon/seldon_client.py +52 -67
- zenml/integrations/seldon/services/seldon_deployment.py +3 -3
- zenml/integrations/seldon/steps/seldon_deployer.py +4 -4
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +15 -5
- zenml/integrations/skypilot_aws/__init__.py +1 -1
- zenml/integrations/skypilot_aws/flavors/skypilot_orchestrator_aws_vm_flavor.py +1 -1
- zenml/integrations/skypilot_azure/__init__.py +1 -1
- zenml/integrations/skypilot_azure/flavors/skypilot_orchestrator_azure_vm_flavor.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +2 -1
- zenml/integrations/skypilot_gcp/flavors/skypilot_orchestrator_gcp_vm_flavor.py +1 -1
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +2 -2
- zenml/integrations/spark/flavors/spark_step_operator_flavor.py +1 -1
- zenml/integrations/tekton/__init__.py +1 -1
- zenml/integrations/tekton/flavors/tekton_orchestrator_flavor.py +66 -23
- zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +547 -233
- zenml/integrations/tensorboard/__init__.py +1 -12
- zenml/integrations/tensorboard/services/tensorboard_service.py +3 -5
- zenml/integrations/tensorboard/visualizers/tensorboard_visualizer.py +6 -6
- zenml/integrations/tensorflow/__init__.py +2 -10
- zenml/integrations/tensorflow/materializers/keras_materializer.py +17 -9
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +9 -14
- zenml/integrations/whylogs/flavors/whylogs_data_validator_flavor.py +1 -1
- zenml/lineage_graph/lineage_graph.py +1 -1
- zenml/materializers/built_in_materializer.py +3 -3
- zenml/materializers/pydantic_materializer.py +2 -2
- zenml/metadata/lazy_load.py +4 -4
- zenml/metadata/metadata_types.py +64 -4
- zenml/model/model.py +79 -54
- zenml/model_deployers/base_model_deployer.py +14 -12
- zenml/model_registries/base_model_registry.py +17 -15
- zenml/models/__init__.py +79 -206
- zenml/models/v2/base/base.py +54 -41
- zenml/models/v2/base/base_plugin_flavor.py +2 -6
- zenml/models/v2/base/filter.py +91 -76
- zenml/models/v2/base/page.py +2 -12
- zenml/models/v2/base/scoped.py +4 -7
- zenml/models/v2/core/api_key.py +22 -8
- zenml/models/v2/core/artifact.py +2 -2
- zenml/models/v2/core/artifact_version.py +74 -40
- zenml/models/v2/core/code_repository.py +37 -10
- zenml/models/v2/core/component.py +65 -16
- zenml/models/v2/core/device.py +14 -4
- zenml/models/v2/core/event_source.py +1 -2
- zenml/models/v2/core/flavor.py +74 -8
- zenml/models/v2/core/logs.py +68 -8
- zenml/models/v2/core/model.py +8 -4
- zenml/models/v2/core/model_version.py +25 -6
- zenml/models/v2/core/model_version_artifact.py +51 -21
- zenml/models/v2/core/model_version_pipeline_run.py +45 -13
- zenml/models/v2/core/pipeline.py +37 -72
- zenml/models/v2/core/pipeline_build.py +29 -17
- zenml/models/v2/core/pipeline_deployment.py +18 -6
- zenml/models/v2/core/pipeline_namespace.py +113 -0
- zenml/models/v2/core/pipeline_run.py +50 -22
- zenml/models/v2/core/run_metadata.py +59 -36
- zenml/models/v2/core/schedule.py +37 -24
- zenml/models/v2/core/secret.py +31 -12
- zenml/models/v2/core/service.py +64 -36
- zenml/models/v2/core/service_account.py +24 -11
- zenml/models/v2/core/service_connector.py +219 -44
- zenml/models/v2/core/stack.py +45 -17
- zenml/models/v2/core/step_run.py +28 -8
- zenml/models/v2/core/tag.py +8 -4
- zenml/models/v2/core/trigger.py +2 -2
- zenml/models/v2/core/trigger_execution.py +1 -0
- zenml/models/v2/core/user.py +18 -21
- zenml/models/v2/core/workspace.py +13 -3
- zenml/models/v2/misc/build_item.py +3 -3
- zenml/models/v2/misc/external_user.py +2 -6
- zenml/models/v2/misc/hub_plugin_models.py +9 -9
- zenml/models/v2/misc/loaded_visualization.py +2 -2
- zenml/models/v2/misc/service_connector_type.py +8 -17
- zenml/models/v2/misc/user_auth.py +7 -2
- zenml/new/pipelines/build_utils.py +3 -3
- zenml/new/pipelines/pipeline.py +17 -13
- zenml/new/pipelines/run_utils.py +103 -1
- zenml/orchestrators/base_orchestrator.py +10 -7
- zenml/orchestrators/local_docker/local_docker_orchestrator.py +1 -1
- zenml/orchestrators/step_runner.py +3 -6
- zenml/orchestrators/utils.py +1 -1
- zenml/plugins/base_plugin_flavor.py +6 -10
- zenml/plugins/plugin_flavor_registry.py +3 -7
- zenml/secret/base_secret.py +7 -8
- zenml/service_connectors/docker_service_connector.py +4 -3
- zenml/service_connectors/service_connector.py +5 -12
- zenml/service_connectors/service_connector_registry.py +2 -4
- zenml/services/container/container_service.py +1 -1
- zenml/services/container/container_service_endpoint.py +1 -1
- zenml/services/local/local_service.py +1 -1
- zenml/services/local/local_service_endpoint.py +1 -1
- zenml/services/service.py +16 -10
- zenml/services/service_type.py +4 -5
- zenml/services/terraform/terraform_service.py +1 -1
- zenml/stack/flavor.py +1 -5
- zenml/stack/flavor_registry.py +4 -4
- zenml/stack/stack.py +4 -1
- zenml/stack/stack_component.py +55 -31
- zenml/steps/base_step.py +34 -28
- zenml/steps/entrypoint_function_utils.py +3 -5
- zenml/steps/utils.py +12 -14
- zenml/utils/cuda_utils.py +50 -0
- zenml/utils/deprecation_utils.py +18 -20
- zenml/utils/dict_utils.py +1 -1
- zenml/utils/filesync_model.py +65 -28
- zenml/utils/function_utils.py +260 -0
- zenml/utils/json_utils.py +131 -0
- zenml/utils/mlstacks_utils.py +2 -2
- zenml/utils/pydantic_utils.py +270 -62
- zenml/utils/secret_utils.py +65 -12
- zenml/utils/source_utils.py +2 -2
- zenml/utils/typed_model.py +5 -3
- zenml/utils/typing_utils.py +243 -0
- zenml/utils/yaml_utils.py +1 -1
- zenml/zen_server/auth.py +2 -2
- zenml/zen_server/cloud_utils.py +6 -6
- zenml/zen_server/deploy/base_provider.py +1 -1
- zenml/zen_server/deploy/deployment.py +6 -8
- zenml/zen_server/deploy/docker/docker_zen_server.py +3 -4
- zenml/zen_server/deploy/local/local_provider.py +0 -1
- zenml/zen_server/deploy/local/local_zen_server.py +6 -6
- zenml/zen_server/deploy/terraform/terraform_zen_server.py +4 -6
- zenml/zen_server/exceptions.py +4 -1
- zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +1 -1
- zenml/zen_server/pipeline_deployment/utils.py +48 -68
- zenml/zen_server/rbac/models.py +2 -5
- zenml/zen_server/rbac/utils.py +11 -14
- zenml/zen_server/routers/auth_endpoints.py +2 -2
- zenml/zen_server/routers/pipeline_builds_endpoints.py +1 -1
- zenml/zen_server/routers/runs_endpoints.py +1 -1
- zenml/zen_server/routers/secrets_endpoints.py +3 -2
- zenml/zen_server/routers/server_endpoints.py +1 -1
- zenml/zen_server/routers/steps_endpoints.py +1 -1
- zenml/zen_server/routers/workspaces_endpoints.py +1 -1
- zenml/zen_stores/base_zen_store.py +46 -9
- zenml/zen_stores/migrations/utils.py +42 -46
- zenml/zen_stores/migrations/versions/0701da9951a0_added_service_table.py +1 -1
- zenml/zen_stores/migrations/versions/1041bc644e0d_remove_secrets_manager.py +5 -3
- zenml/zen_stores/migrations/versions/10a907dad202_delete_mlmd_tables.py +1 -1
- zenml/zen_stores/migrations/versions/26b776ad583e_redesign_artifacts.py +8 -10
- zenml/zen_stores/migrations/versions/37835ce041d2_optimizing_database.py +3 -3
- zenml/zen_stores/migrations/versions/46506f72f0ed_add_server_settings.py +10 -12
- zenml/zen_stores/migrations/versions/5994f9ad0489_introduce_role_permissions.py +3 -2
- zenml/zen_stores/migrations/versions/6917bce75069_add_pipeline_run_unique_constraint.py +4 -4
- zenml/zen_stores/migrations/versions/728c6369cfaa_add_name_column_to_input_artifact_pk.py +3 -2
- zenml/zen_stores/migrations/versions/743ec82b1b3c_update_size_of_build_images.py +2 -2
- zenml/zen_stores/migrations/versions/7500f434b71c_remove_shared_columns.py +3 -2
- zenml/zen_stores/migrations/versions/7834208cc3f6_artifact_project_scoping.py +8 -7
- zenml/zen_stores/migrations/versions/7b651bf6822e_track_secrets_in_db.py +6 -4
- zenml/zen_stores/migrations/versions/7e4a481d17f7_add_identity_table.py +2 -2
- zenml/zen_stores/migrations/versions/7f603e583dd7_fixed_migration.py +1 -1
- zenml/zen_stores/migrations/versions/a39c4184c8ce_remove_secrets_manager_flavors.py +2 -2
- zenml/zen_stores/migrations/versions/a91762e6be36_artifact_version_table.py +4 -4
- zenml/zen_stores/migrations/versions/alembic_start.py +1 -1
- zenml/zen_stores/migrations/versions/fbd7f18ced1e_increase_step_run_field_lengths.py +4 -4
- zenml/zen_stores/rest_zen_store.py +109 -49
- zenml/zen_stores/schemas/api_key_schemas.py +1 -1
- zenml/zen_stores/schemas/artifact_schemas.py +8 -8
- zenml/zen_stores/schemas/artifact_visualization_schemas.py +3 -3
- zenml/zen_stores/schemas/code_repository_schemas.py +1 -1
- zenml/zen_stores/schemas/component_schemas.py +8 -3
- zenml/zen_stores/schemas/device_schemas.py +8 -6
- zenml/zen_stores/schemas/event_source_schemas.py +3 -4
- zenml/zen_stores/schemas/flavor_schemas.py +5 -3
- zenml/zen_stores/schemas/model_schemas.py +26 -1
- zenml/zen_stores/schemas/pipeline_build_schemas.py +1 -1
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +4 -4
- zenml/zen_stores/schemas/pipeline_run_schemas.py +6 -6
- zenml/zen_stores/schemas/pipeline_schemas.py +5 -2
- zenml/zen_stores/schemas/run_metadata_schemas.py +2 -2
- zenml/zen_stores/schemas/secret_schemas.py +8 -5
- zenml/zen_stores/schemas/server_settings_schemas.py +3 -1
- zenml/zen_stores/schemas/service_connector_schemas.py +1 -1
- zenml/zen_stores/schemas/service_schemas.py +11 -2
- zenml/zen_stores/schemas/stack_schemas.py +1 -1
- zenml/zen_stores/schemas/step_run_schemas.py +11 -11
- zenml/zen_stores/schemas/tag_schemas.py +6 -2
- zenml/zen_stores/schemas/trigger_schemas.py +2 -2
- zenml/zen_stores/schemas/user_schemas.py +2 -2
- zenml/zen_stores/schemas/workspace_schemas.py +3 -1
- zenml/zen_stores/secrets_stores/aws_secrets_store.py +19 -20
- zenml/zen_stores/secrets_stores/azure_secrets_store.py +17 -20
- zenml/zen_stores/secrets_stores/base_secrets_store.py +79 -12
- zenml/zen_stores/secrets_stores/gcp_secrets_store.py +17 -20
- zenml/zen_stores/secrets_stores/hashicorp_secrets_store.py +4 -8
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +10 -7
- zenml/zen_stores/secrets_stores/sql_secrets_store.py +5 -6
- zenml/zen_stores/sql_zen_store.py +196 -120
- zenml/zen_stores/zen_store_interface.py +33 -0
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240619.dist-info}/METADATA +8 -7
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240619.dist-info}/RECORD +297 -294
- zenml/integrations/kubeflow/utils.py +0 -95
- zenml/models/v2/base/internal.py +0 -37
- zenml/models/v2/base/update.py +0 -44
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240619.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240619.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240619.dist-info}/entry_points.txt +0 -0
@@ -35,7 +35,7 @@ class DefaultContainerRegistryFlavor(BaseContainerRegistryFlavor):
|
|
35
35
|
|
36
36
|
@property
|
37
37
|
def docs_url(self) -> Optional[str]:
|
38
|
-
"""A
|
38
|
+
"""A URL to point at docs explaining this flavor.
|
39
39
|
|
40
40
|
Returns:
|
41
41
|
A flavor docs url.
|
@@ -44,7 +44,7 @@ class DefaultContainerRegistryFlavor(BaseContainerRegistryFlavor):
|
|
44
44
|
|
45
45
|
@property
|
46
46
|
def sdk_docs_url(self) -> Optional[str]:
|
47
|
-
"""A
|
47
|
+
"""A URL to point at docs explaining this flavor.
|
48
48
|
|
49
49
|
Returns:
|
50
50
|
A flavor docs url.
|
@@ -53,7 +53,7 @@ class DefaultContainerRegistryFlavor(BaseContainerRegistryFlavor):
|
|
53
53
|
|
54
54
|
@property
|
55
55
|
def logo_url(self) -> str:
|
56
|
-
"""A
|
56
|
+
"""A URL to represent the flavor in the dashboard.
|
57
57
|
|
58
58
|
Returns:
|
59
59
|
The flavor logo.
|
@@ -118,7 +118,7 @@ class BaseEventHub(ABC):
|
|
118
118
|
action_callback: The action to trigger.
|
119
119
|
"""
|
120
120
|
request = TriggerExecutionRequest(
|
121
|
-
trigger=trigger.id, event_metadata=event.
|
121
|
+
trigger=trigger.id, event_metadata=event.model_dump()
|
122
122
|
)
|
123
123
|
|
124
124
|
action_config = trigger.get_metadata().action
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Base implementation for event sources."""
|
15
15
|
|
16
|
-
import json
|
17
16
|
from abc import ABC, abstractmethod
|
18
17
|
from typing import (
|
19
18
|
Any,
|
@@ -210,7 +209,7 @@ class BaseEventSourceHandler(BasePlugin, ABC):
|
|
210
209
|
event_source=event_source, config=config
|
211
210
|
)
|
212
211
|
# Serialize the configuration back into the request
|
213
|
-
event_source.configuration = config.
|
212
|
+
event_source.configuration = config.model_dump(exclude_none=True)
|
214
213
|
# Create the event source in the database
|
215
214
|
event_source_response = self.zen_store.create_event_source(
|
216
215
|
event_source=event_source
|
@@ -238,7 +237,9 @@ class BaseEventSourceHandler(BasePlugin, ABC):
|
|
238
237
|
raise
|
239
238
|
|
240
239
|
# Serialize the configuration back into the response
|
241
|
-
event_source_response.set_configuration(
|
240
|
+
event_source_response.set_configuration(
|
241
|
+
config.model_dump(exclude_none=True)
|
242
|
+
)
|
242
243
|
|
243
244
|
# Return the response to the user
|
244
245
|
return event_source_response
|
@@ -281,7 +282,7 @@ class BaseEventSourceHandler(BasePlugin, ABC):
|
|
281
282
|
config_update=config_update,
|
282
283
|
)
|
283
284
|
# Serialize the configuration update back into the update request
|
284
|
-
event_source_update.configuration = config_update.
|
285
|
+
event_source_update.configuration = config_update.model_dump(
|
285
286
|
exclude_none=True
|
286
287
|
)
|
287
288
|
|
@@ -320,7 +321,7 @@ class BaseEventSourceHandler(BasePlugin, ABC):
|
|
320
321
|
|
321
322
|
# Serialize the configuration back into the response
|
322
323
|
event_source_response.set_configuration(
|
323
|
-
response_config.
|
324
|
+
response_config.model_dump(exclude_none=True)
|
324
325
|
)
|
325
326
|
# Return the response to the user
|
326
327
|
return event_source_response
|
@@ -387,7 +388,9 @@ class BaseEventSourceHandler(BasePlugin, ABC):
|
|
387
388
|
event_source=event_source, config=config
|
388
389
|
)
|
389
390
|
# Serialize the configuration back into the response
|
390
|
-
event_source.set_configuration(
|
391
|
+
event_source.set_configuration(
|
392
|
+
config.model_dump(exclude_none=True)
|
393
|
+
)
|
391
394
|
|
392
395
|
# Return the response to the user
|
393
396
|
return event_source
|
@@ -647,11 +650,7 @@ class BaseEventSourceFlavor(BasePluginFlavor, ABC):
|
|
647
650
|
Returns:
|
648
651
|
The config schema.
|
649
652
|
"""
|
650
|
-
|
651
|
-
cls.EVENT_SOURCE_CONFIG_CLASS.schema_json()
|
652
|
-
)
|
653
|
-
|
654
|
-
return config_schema
|
653
|
+
return cls.EVENT_SOURCE_CONFIG_CLASS.model_json_schema()
|
655
654
|
|
656
655
|
@classmethod
|
657
656
|
def get_event_source_config_schema(cls) -> Dict[str, Any]:
|
@@ -660,11 +659,7 @@ class BaseEventSourceFlavor(BasePluginFlavor, ABC):
|
|
660
659
|
Returns:
|
661
660
|
The config schema.
|
662
661
|
"""
|
663
|
-
|
664
|
-
cls.EVENT_FILTER_CONFIG_CLASS.schema_json()
|
665
|
-
)
|
666
|
-
|
667
|
-
return config_schema
|
662
|
+
return cls.EVENT_FILTER_CONFIG_CLASS.model_json_schema()
|
668
663
|
|
669
664
|
@classmethod
|
670
665
|
def get_flavor_response_model(
|
zenml/exceptions.py
CHANGED
@@ -245,6 +245,10 @@ class IllegalOperationError(ZenMLBaseException):
|
|
245
245
|
"""Raised when an illegal operation is attempted."""
|
246
246
|
|
247
247
|
|
248
|
+
class MethodNotAllowedError(ZenMLBaseException):
|
249
|
+
"""Raised when the server does not allow a request method."""
|
250
|
+
|
251
|
+
|
248
252
|
class SettingsResolvingError(ZenMLBaseException):
|
249
253
|
"""Raised when resolving settings failed."""
|
250
254
|
|
@@ -13,9 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Airflow integration for ZenML.
|
15
15
|
|
16
|
-
The Airflow integration
|
17
|
-
orchestrator. You can enable it by registering the Airflow orchestrator with
|
18
|
-
the CLI tool, then bootstrap using the ``zenml orchestrator up`` command.
|
16
|
+
The Airflow integration powers an alternative orchestrator.
|
19
17
|
"""
|
20
18
|
from typing import List, Type
|
21
19
|
|
@@ -30,13 +28,7 @@ class AirflowIntegration(Integration):
|
|
30
28
|
"""Definition of Airflow Integration for ZenML."""
|
31
29
|
|
32
30
|
NAME = AIRFLOW
|
33
|
-
|
34
|
-
# pendulum>-3.0.0
|
35
|
-
REQUIREMENTS = [
|
36
|
-
"apache-airflow~=2.4.0",
|
37
|
-
"pendulum<3.0.0",
|
38
|
-
"tenacity!=8.4.0", # https://github.com/jd/tenacity/issues/471
|
39
|
-
]
|
31
|
+
REQUIREMENTS = []
|
40
32
|
|
41
33
|
@classmethod
|
42
34
|
def flavors(cls) -> List[Type[Flavor]]:
|
@@ -13,9 +13,9 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Airflow orchestrator flavor."""
|
15
15
|
|
16
|
-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type
|
16
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type
|
17
17
|
|
18
|
-
from pydantic import
|
18
|
+
from pydantic import field_validator
|
19
19
|
|
20
20
|
from zenml.config.base_settings import BaseSettings
|
21
21
|
from zenml.integrations.airflow import AIRFLOW_ORCHESTRATOR_FLAVOR
|
@@ -87,10 +87,9 @@ class AirflowOrchestratorSettings(BaseSettings):
|
|
87
87
|
|
88
88
|
custom_dag_generator: Optional[str] = None
|
89
89
|
|
90
|
-
@
|
91
|
-
|
92
|
-
|
93
|
-
) -> Optional[str]:
|
90
|
+
@field_validator("operator", mode="before")
|
91
|
+
@classmethod
|
92
|
+
def _convert_operator(cls, value: Any) -> Any:
|
94
93
|
"""Converts operator types to source strings.
|
95
94
|
|
96
95
|
Args:
|
@@ -108,7 +107,7 @@ class AirflowOrchestratorSettings(BaseSettings):
|
|
108
107
|
return value
|
109
108
|
|
110
109
|
|
111
|
-
class AirflowOrchestratorConfig(
|
110
|
+
class AirflowOrchestratorConfig(
|
112
111
|
BaseOrchestratorConfig, AirflowOrchestratorSettings
|
113
112
|
):
|
114
113
|
"""Configuration for the Airflow orchestrator.
|
@@ -16,8 +16,6 @@
|
|
16
16
|
import datetime
|
17
17
|
import importlib
|
18
18
|
import os
|
19
|
-
import platform
|
20
|
-
import time
|
21
19
|
import zipfile
|
22
20
|
from typing import (
|
23
21
|
TYPE_CHECKING,
|
@@ -29,12 +27,8 @@ from typing import (
|
|
29
27
|
Type,
|
30
28
|
cast,
|
31
29
|
)
|
32
|
-
from uuid import UUID
|
33
30
|
|
34
31
|
from zenml.config.global_config import GlobalConfiguration
|
35
|
-
from zenml.constants import (
|
36
|
-
METADATA_ORCHESTRATOR_URL,
|
37
|
-
)
|
38
32
|
from zenml.entrypoints import StepEntrypointConfiguration
|
39
33
|
from zenml.enums import StackComponentType
|
40
34
|
from zenml.integrations.airflow.flavors.airflow_orchestrator_flavor import (
|
@@ -44,11 +38,10 @@ from zenml.integrations.airflow.flavors.airflow_orchestrator_flavor import (
|
|
44
38
|
)
|
45
39
|
from zenml.io import fileio
|
46
40
|
from zenml.logger import get_logger
|
47
|
-
from zenml.metadata.metadata_types import Uri
|
48
41
|
from zenml.orchestrators import ContainerizedOrchestrator
|
49
42
|
from zenml.orchestrators.utils import get_orchestrator_run_name
|
50
43
|
from zenml.stack import StackValidator
|
51
|
-
from zenml.utils import
|
44
|
+
from zenml.utils import io_utils
|
52
45
|
|
53
46
|
if TYPE_CHECKING:
|
54
47
|
from zenml.config import ResourceSettings
|
@@ -57,7 +50,6 @@ if TYPE_CHECKING:
|
|
57
50
|
DagConfiguration,
|
58
51
|
TaskConfiguration,
|
59
52
|
)
|
60
|
-
from zenml.metadata.metadata_types import MetadataType
|
61
53
|
from zenml.models import PipelineDeploymentResponse
|
62
54
|
from zenml.pipelines import Schedule
|
63
55
|
from zenml.stack import Stack
|
@@ -107,18 +99,18 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
107
99
|
"""Orchestrator responsible for running pipelines using Airflow."""
|
108
100
|
|
109
101
|
def __init__(self, **values: Any):
|
110
|
-
"""
|
102
|
+
"""Initialize the orchestrator.
|
111
103
|
|
112
104
|
Args:
|
113
105
|
**values: Values to set in the orchestrator.
|
114
106
|
"""
|
115
107
|
super().__init__(**values)
|
116
|
-
self.
|
108
|
+
self.dags_directory = os.path.join(
|
117
109
|
io_utils.get_global_config_directory(),
|
118
110
|
"airflow",
|
119
111
|
str(self.id),
|
112
|
+
"dags",
|
120
113
|
)
|
121
|
-
self._set_env()
|
122
114
|
|
123
115
|
@property
|
124
116
|
def config(self) -> AirflowOrchestratorConfig:
|
@@ -138,19 +130,6 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
138
130
|
"""
|
139
131
|
return AirflowOrchestratorSettings
|
140
132
|
|
141
|
-
@property
|
142
|
-
def dags_directory(self) -> str:
|
143
|
-
"""Returns path to the airflow dags directory.
|
144
|
-
|
145
|
-
Returns:
|
146
|
-
Path to the airflow dags directory.
|
147
|
-
"""
|
148
|
-
return os.path.join(self.airflow_home, "dags")
|
149
|
-
|
150
|
-
def _set_env(self) -> None:
|
151
|
-
"""Sets environment variables to configure airflow."""
|
152
|
-
os.environ["AIRFLOW_HOME"] = self.airflow_home
|
153
|
-
|
154
133
|
@property
|
155
134
|
def validator(self) -> Optional["StackValidator"]:
|
156
135
|
"""Validates the stack.
|
@@ -346,21 +325,22 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
346
325
|
"""
|
347
326
|
io_utils.create_dir_recursive_if_not_exists(output_dir)
|
348
327
|
|
349
|
-
if self.config.local and output_dir
|
328
|
+
if self.config.local and output_dir == self.dags_directory:
|
350
329
|
logger.warning(
|
351
|
-
"You're using a local Airflow orchestrator but
|
352
|
-
"custom DAG output directory
|
353
|
-
"
|
354
|
-
"directory
|
330
|
+
"You're using a local Airflow orchestrator but have not "
|
331
|
+
"specified a custom DAG output directory. Unless you've "
|
332
|
+
"configured your Airflow server to look for DAGs in this "
|
333
|
+
"directory (%s), this DAG will not be found automatically "
|
334
|
+
"by your local Airflow server.",
|
355
335
|
output_dir,
|
356
|
-
self.dags_directory,
|
357
336
|
)
|
358
337
|
|
359
338
|
def _write_zip(path: str) -> None:
|
360
339
|
with zipfile.ZipFile(path, mode="w") as z:
|
361
340
|
z.write(dag_generator_values.file, arcname="dag.py")
|
362
341
|
z.writestr(
|
363
|
-
dag_generator_values.config_file_name,
|
342
|
+
dag_generator_values.config_file_name,
|
343
|
+
dag_config.model_dump_json(),
|
364
344
|
)
|
365
345
|
|
366
346
|
logger.info("Writing DAG definition to `%s`.", path)
|
@@ -447,224 +427,8 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
447
427
|
|
448
428
|
return {
|
449
429
|
"schedule": "@once",
|
450
|
-
# set
|
430
|
+
# set a start time in the past and disable catchup so airflow
|
451
431
|
# runs the dag immediately
|
452
432
|
"start_date": datetime.datetime.utcnow() - datetime.timedelta(7),
|
453
433
|
"catchup": False,
|
454
434
|
}
|
455
|
-
|
456
|
-
#####################
|
457
|
-
# Local Airflow #
|
458
|
-
#####################
|
459
|
-
|
460
|
-
@property
|
461
|
-
def pid_file(self) -> str:
|
462
|
-
"""Returns path to the daemon PID file.
|
463
|
-
|
464
|
-
Returns:
|
465
|
-
Path to the daemon PID file.
|
466
|
-
"""
|
467
|
-
return os.path.join(self.airflow_home, "airflow_daemon.pid")
|
468
|
-
|
469
|
-
@property
|
470
|
-
def log_file(self) -> str:
|
471
|
-
"""Returns path to the airflow log file.
|
472
|
-
|
473
|
-
Returns:
|
474
|
-
str: Path to the airflow log file.
|
475
|
-
"""
|
476
|
-
return os.path.join(self.airflow_home, "airflow_orchestrator.log")
|
477
|
-
|
478
|
-
@property
|
479
|
-
def password_file(self) -> str:
|
480
|
-
"""Returns path to the webserver password file.
|
481
|
-
|
482
|
-
Returns:
|
483
|
-
Path to the webserver password file.
|
484
|
-
"""
|
485
|
-
return os.path.join(self.airflow_home, "standalone_admin_password.txt")
|
486
|
-
|
487
|
-
@property
|
488
|
-
def is_running(self) -> bool:
|
489
|
-
"""Returns whether the orchestrator is "running".
|
490
|
-
|
491
|
-
In the non-local case, this is always True. Otherwise checks if the
|
492
|
-
local Airflow server is running.
|
493
|
-
|
494
|
-
Returns:
|
495
|
-
If the orchestrator is running.
|
496
|
-
|
497
|
-
Raises:
|
498
|
-
RuntimeError: If port 8080 is occupied.
|
499
|
-
"""
|
500
|
-
if not self.config.local:
|
501
|
-
return True
|
502
|
-
|
503
|
-
from airflow.cli.commands.standalone_command import ( # type: ignore
|
504
|
-
StandaloneCommand,
|
505
|
-
)
|
506
|
-
from airflow.jobs.triggerer_job import TriggererJob
|
507
|
-
|
508
|
-
daemon_running = daemon.check_if_daemon_is_running(self.pid_file)
|
509
|
-
|
510
|
-
command = StandaloneCommand()
|
511
|
-
webserver_port_open = command.port_open(8080)
|
512
|
-
|
513
|
-
if not daemon_running:
|
514
|
-
if webserver_port_open:
|
515
|
-
raise RuntimeError(
|
516
|
-
"The airflow daemon does not seem to be running but "
|
517
|
-
"local port 8080 is occupied. Make sure the port is "
|
518
|
-
"available and try again."
|
519
|
-
)
|
520
|
-
|
521
|
-
# exit early so we don't check non-existing airflow databases
|
522
|
-
return False
|
523
|
-
|
524
|
-
# we can't use StandaloneCommand().is_ready() here as the
|
525
|
-
# Airflow SequentialExecutor apparently does not send a heartbeat
|
526
|
-
# while running a task which would result in this returning `False`
|
527
|
-
# even if Airflow is running.
|
528
|
-
airflow_running = webserver_port_open and command.job_running(
|
529
|
-
TriggererJob
|
530
|
-
)
|
531
|
-
return airflow_running
|
532
|
-
|
533
|
-
@property
|
534
|
-
def is_provisioned(self) -> bool:
|
535
|
-
"""Returns whether the airflow daemon is currently running.
|
536
|
-
|
537
|
-
Returns:
|
538
|
-
True if the airflow daemon is running, False otherwise.
|
539
|
-
"""
|
540
|
-
return self.is_running
|
541
|
-
|
542
|
-
def provision(self) -> None:
|
543
|
-
"""Ensures that Airflow is running."""
|
544
|
-
if not self.config.local:
|
545
|
-
return
|
546
|
-
|
547
|
-
if self.is_running:
|
548
|
-
logger.info("Airflow is already running.")
|
549
|
-
self._log_webserver_credentials()
|
550
|
-
return
|
551
|
-
|
552
|
-
self._check_local_server_requirements()
|
553
|
-
|
554
|
-
if not fileio.exists(self.dags_directory):
|
555
|
-
io_utils.create_dir_recursive_if_not_exists(self.dags_directory)
|
556
|
-
|
557
|
-
from airflow.cli.commands.standalone_command import StandaloneCommand
|
558
|
-
|
559
|
-
self._set_server_env()
|
560
|
-
try:
|
561
|
-
command = StandaloneCommand()
|
562
|
-
daemon.run_as_daemon(
|
563
|
-
command.run,
|
564
|
-
pid_file=self.pid_file,
|
565
|
-
log_file=self.log_file,
|
566
|
-
)
|
567
|
-
while not self.is_running:
|
568
|
-
# Wait until the daemon started all the relevant airflow
|
569
|
-
# processes
|
570
|
-
time.sleep(0.1)
|
571
|
-
self._log_webserver_credentials()
|
572
|
-
except Exception as e:
|
573
|
-
logger.error(e)
|
574
|
-
logger.error(
|
575
|
-
"An error occurred while starting the Airflow daemon. If you "
|
576
|
-
"want to start it manually, use the commands described in the "
|
577
|
-
"official Airflow quickstart guide for running Airflow locally."
|
578
|
-
)
|
579
|
-
self.deprovision()
|
580
|
-
finally:
|
581
|
-
logger.warning(
|
582
|
-
"Airflow provisioning using `zenml stack up` is "
|
583
|
-
"deprecated. Please follow the new Airflow quickstart guide "
|
584
|
-
"to run Airflow locally."
|
585
|
-
)
|
586
|
-
|
587
|
-
def deprovision(self) -> None:
|
588
|
-
"""Stops the airflow daemon if necessary and tears down resources."""
|
589
|
-
if not self.config.local:
|
590
|
-
return
|
591
|
-
|
592
|
-
if self.is_running:
|
593
|
-
daemon.stop_daemon(self.pid_file)
|
594
|
-
|
595
|
-
fileio.rmtree(self.airflow_home)
|
596
|
-
logger.info("Airflow spun down.")
|
597
|
-
|
598
|
-
def _set_server_env(self) -> None:
|
599
|
-
"""Sets environment variables for the local Airflow server process."""
|
600
|
-
os.environ["AIRFLOW__CORE__DAGS_FOLDER"] = self.dags_directory
|
601
|
-
os.environ["AIRFLOW__CORE__LOAD_EXAMPLES"] = "false"
|
602
|
-
# check the DAG folder every 10 seconds for new files
|
603
|
-
os.environ["AIRFLOW__SCHEDULER__DAG_DIR_LIST_INTERVAL"] = "10"
|
604
|
-
|
605
|
-
if platform.system() == "Darwin":
|
606
|
-
# Prevent crashes during forking on MacOS
|
607
|
-
# https://github.com/apache/airflow/issues/28487
|
608
|
-
os.environ["no_proxy"] = "*"
|
609
|
-
|
610
|
-
@staticmethod
|
611
|
-
def _check_local_server_requirements() -> None:
|
612
|
-
"""Checks that all packages for a local Airflow server are installed.
|
613
|
-
|
614
|
-
When running a local Airflow server, we require the
|
615
|
-
`apache-airflow-providers-docker` to run steps locally in Docker
|
616
|
-
containers in addition to the basic integration requirements.
|
617
|
-
|
618
|
-
Raises:
|
619
|
-
RuntimeError: If the `apache-airflow-providers-docker` is not
|
620
|
-
installed in the active Python environment.
|
621
|
-
"""
|
622
|
-
try:
|
623
|
-
from airflow.providers.docker.operators.docker import ( # noqa
|
624
|
-
DockerOperator,
|
625
|
-
)
|
626
|
-
except ImportError:
|
627
|
-
raise RuntimeError(
|
628
|
-
"Unable to import Airflow `DockerOperator` in the active "
|
629
|
-
"Python environment. Spinning up a local Airflow server to "
|
630
|
-
"run ZenML pipelines requires the `DockerOperator` to be "
|
631
|
-
"available. Please run "
|
632
|
-
"`pip install 'apache-airflow-providers-docker<3.8.0' "
|
633
|
-
"'apache-airflow~=2.4.0'` to install it and try again."
|
634
|
-
)
|
635
|
-
|
636
|
-
def _log_webserver_credentials(self) -> None:
|
637
|
-
"""Logs URL and credentials to log in to the airflow webserver.
|
638
|
-
|
639
|
-
Raises:
|
640
|
-
FileNotFoundError: If the password file does not exist.
|
641
|
-
"""
|
642
|
-
if fileio.exists(self.password_file):
|
643
|
-
with open(self.password_file) as file:
|
644
|
-
password = file.read().strip()
|
645
|
-
else:
|
646
|
-
raise FileNotFoundError(
|
647
|
-
f"Can't find password file '{self.password_file}'"
|
648
|
-
)
|
649
|
-
logger.info(
|
650
|
-
"To inspect your DAGs, login to `http://localhost:8080` "
|
651
|
-
"with username: `admin` password: `%s`",
|
652
|
-
password,
|
653
|
-
)
|
654
|
-
|
655
|
-
def get_pipeline_run_metadata(
|
656
|
-
self, run_id: UUID
|
657
|
-
) -> Dict[str, "MetadataType"]:
|
658
|
-
"""Get general component-specific metadata for a pipeline run.
|
659
|
-
|
660
|
-
Args:
|
661
|
-
run_id: The ID of the pipeline run.
|
662
|
-
|
663
|
-
Returns:
|
664
|
-
A dictionary of metadata.
|
665
|
-
"""
|
666
|
-
if self.config.local:
|
667
|
-
return {
|
668
|
-
METADATA_ORCHESTRATOR_URL: Uri("http://localhost:8080"),
|
669
|
-
}
|
670
|
-
return {}
|
@@ -19,7 +19,7 @@ import os
|
|
19
19
|
import zipfile
|
20
20
|
from typing import Any, Dict, List, Optional, Type, Union
|
21
21
|
|
22
|
-
from pydantic import BaseModel
|
22
|
+
from pydantic import BaseModel, Field
|
23
23
|
|
24
24
|
ENV_ZENML_AIRFLOW_RUN_ID = "ZENML_AIRFLOW_RUN_ID"
|
25
25
|
ENV_ZENML_LOCAL_STORES_PATH = "ZENML_LOCAL_STORES_PATH"
|
@@ -51,7 +51,9 @@ class DagConfiguration(BaseModel):
|
|
51
51
|
|
52
52
|
local_stores_path: Optional[str] = None
|
53
53
|
|
54
|
-
schedule: Union[datetime.timedelta, str]
|
54
|
+
schedule: Union[datetime.timedelta, str] = Field(
|
55
|
+
union_mode="left_to_right"
|
56
|
+
)
|
55
57
|
start_date: datetime.datetime
|
56
58
|
end_date: Optional[datetime.datetime] = None
|
57
59
|
catchup: bool = False
|
@@ -199,7 +201,7 @@ else:
|
|
199
201
|
import airflow
|
200
202
|
|
201
203
|
config_str = archive.read(CONFIG_FILENAME)
|
202
|
-
dag_config = DagConfiguration.
|
204
|
+
dag_config = DagConfiguration.model_validate_json(config_str)
|
203
205
|
|
204
206
|
step_name_to_airflow_operator = {}
|
205
207
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
from typing import TYPE_CHECKING, Optional, Type
|
17
17
|
|
18
|
-
from pydantic import
|
18
|
+
from pydantic import field_validator
|
19
19
|
|
20
20
|
from zenml.annotators.base_annotator import (
|
21
21
|
BaseAnnotatorConfig,
|
@@ -50,13 +50,14 @@ class ArgillaAnnotatorSettings(BaseSettings):
|
|
50
50
|
"""
|
51
51
|
|
52
52
|
instance_url: str = DEFAULT_LOCAL_INSTANCE_URL
|
53
|
-
api_key: Optional[str] = SecretField()
|
53
|
+
api_key: Optional[str] = SecretField(default=None)
|
54
54
|
workspace: Optional[str] = "admin"
|
55
55
|
port: Optional[int]
|
56
56
|
extra_headers: Optional[str] = None
|
57
57
|
httpx_extra_kwargs: Optional[str] = None
|
58
58
|
|
59
|
-
@
|
59
|
+
@field_validator("instance_url")
|
60
|
+
@classmethod
|
60
61
|
def ensure_instance_url_ends_without_slash(cls, instance_url: str) -> str:
|
61
62
|
"""Pydantic validator to ensure instance URL ends without a slash.
|
62
63
|
|
@@ -69,7 +70,7 @@ class ArgillaAnnotatorSettings(BaseSettings):
|
|
69
70
|
return instance_url.rstrip("/")
|
70
71
|
|
71
72
|
|
72
|
-
class ArgillaAnnotatorConfig(
|
73
|
+
class ArgillaAnnotatorConfig(
|
73
74
|
BaseAnnotatorConfig,
|
74
75
|
ArgillaAnnotatorSettings,
|
75
76
|
AuthenticationConfigMixin,
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
from typing import TYPE_CHECKING, Optional, Type
|
17
17
|
|
18
|
-
from pydantic import
|
18
|
+
from pydantic import field_validator
|
19
19
|
|
20
20
|
from zenml.constants import DOCKER_REGISTRY_RESOURCE_TYPE
|
21
21
|
from zenml.container_registries.base_container_registry import (
|
@@ -37,7 +37,8 @@ if TYPE_CHECKING:
|
|
37
37
|
class AWSContainerRegistryConfig(BaseContainerRegistryConfig):
|
38
38
|
"""Configuration for AWS Container Registry."""
|
39
39
|
|
40
|
-
@
|
40
|
+
@field_validator("uri")
|
41
|
+
@classmethod
|
41
42
|
def validate_aws_uri(cls, uri: str) -> str:
|
42
43
|
"""Validates that the URI is in the correct format.
|
43
44
|
|
@@ -15,6 +15,8 @@
|
|
15
15
|
|
16
16
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Type, Union
|
17
17
|
|
18
|
+
from pydantic import Field
|
19
|
+
|
18
20
|
from zenml.config.base_settings import BaseSettings
|
19
21
|
from zenml.integrations.aws import (
|
20
22
|
AWS_RESOURCE_TYPE,
|
@@ -80,13 +82,17 @@ class SagemakerOrchestratorSettings(BaseSettings):
|
|
80
82
|
|
81
83
|
processor_args: Dict[str, Any] = {}
|
82
84
|
input_data_s3_mode: str = "File"
|
83
|
-
input_data_s3_uri: Optional[Union[str, Dict[str, str]]] =
|
85
|
+
input_data_s3_uri: Optional[Union[str, Dict[str, str]]] = Field(
|
86
|
+
default=None, union_mode="left_to_right"
|
87
|
+
)
|
84
88
|
|
85
89
|
output_data_s3_mode: str = "EndOfJob"
|
86
|
-
output_data_s3_uri: Optional[Union[str, Dict[str, str]]] =
|
90
|
+
output_data_s3_uri: Optional[Union[str, Dict[str, str]]] = Field(
|
91
|
+
default=None, union_mode="left_to_right"
|
92
|
+
)
|
87
93
|
|
88
94
|
|
89
|
-
class SagemakerOrchestratorConfig(
|
95
|
+
class SagemakerOrchestratorConfig(
|
90
96
|
BaseOrchestratorConfig, SagemakerOrchestratorSettings
|
91
97
|
):
|
92
98
|
"""Config for the Sagemaker orchestrator.
|
@@ -124,8 +130,8 @@ class SagemakerOrchestratorConfig( # type: ignore[misc] # https://github.com/py
|
|
124
130
|
|
125
131
|
synchronous: bool = True
|
126
132
|
execution_role: str
|
127
|
-
aws_access_key_id: Optional[str] = SecretField()
|
128
|
-
aws_secret_access_key: Optional[str] = SecretField()
|
133
|
+
aws_access_key_id: Optional[str] = SecretField(default=None)
|
134
|
+
aws_secret_access_key: Optional[str] = SecretField(default=None)
|
129
135
|
aws_profile: Optional[str] = None
|
130
136
|
aws_auth_role_arn: Optional[str] = None
|
131
137
|
region: Optional[str] = None
|