zenml-nightly 0.58.2.dev20240618__py3-none-any.whl → 0.58.2.dev20240620__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.dev20240620.dist-info}/METADATA +8 -7
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240620.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.dev20240620.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240620.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.58.2.dev20240618.dist-info → zenml_nightly-0.58.2.dev20240620.dist-info}/entry_points.txt +0 -0
@@ -31,16 +31,16 @@
|
|
31
31
|
|
32
32
|
import os
|
33
33
|
import re
|
34
|
-
|
34
|
+
import types
|
35
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, cast
|
35
36
|
from uuid import UUID
|
36
37
|
|
37
|
-
import kfp
|
38
38
|
from google.api_core import exceptions as google_exceptions
|
39
39
|
from google.cloud import aiplatform
|
40
40
|
from kfp import dsl
|
41
|
-
from kfp.
|
42
|
-
from kfp.v2.compiler import Compiler as KFPV2Compiler
|
41
|
+
from kfp.compiler import Compiler
|
43
42
|
|
43
|
+
from zenml.config.resource_settings import ResourceSettings
|
44
44
|
from zenml.constants import (
|
45
45
|
METADATA_ORCHESTRATOR_URL,
|
46
46
|
)
|
@@ -57,20 +57,19 @@ from zenml.integrations.gcp.flavors.vertex_orchestrator_flavor import (
|
|
57
57
|
from zenml.integrations.gcp.google_credentials_mixin import (
|
58
58
|
GoogleCredentialsMixin,
|
59
59
|
)
|
60
|
-
from zenml.integrations.kubeflow.utils import apply_pod_settings
|
61
60
|
from zenml.io import fileio
|
62
61
|
from zenml.logger import get_logger
|
63
62
|
from zenml.metadata.metadata_types import MetadataType, Uri
|
64
63
|
from zenml.orchestrators import ContainerizedOrchestrator
|
65
64
|
from zenml.orchestrators.utils import get_orchestrator_run_name
|
66
65
|
from zenml.stack.stack_validator import StackValidator
|
66
|
+
from zenml.utils import yaml_utils
|
67
67
|
from zenml.utils.io_utils import get_global_config_directory
|
68
68
|
|
69
69
|
if TYPE_CHECKING:
|
70
70
|
from zenml.config.base_settings import BaseSettings
|
71
71
|
from zenml.models import PipelineDeploymentResponse, ScheduleResponse
|
72
72
|
from zenml.stack import Stack
|
73
|
-
from zenml.steps import ResourceSettings
|
74
73
|
|
75
74
|
logger = get_logger(__name__)
|
76
75
|
ENV_ZENML_VERTEX_RUN_ID = "ZENML_VERTEX_RUN_ID"
|
@@ -246,54 +245,48 @@ class VertexOrchestrator(ContainerizedOrchestrator, GoogleCredentialsMixin):
|
|
246
245
|
"schedule to a Vertex orchestrator."
|
247
246
|
)
|
248
247
|
|
249
|
-
def
|
248
|
+
def _create_dynamic_component(
|
250
249
|
self,
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
250
|
+
image: str,
|
251
|
+
command: List[str],
|
252
|
+
arguments: List[str],
|
253
|
+
component_name: str,
|
254
|
+
) -> dsl.PipelineTask:
|
255
|
+
"""Creates a dynamic container component for a Vertex pipeline.
|
256
256
|
|
257
257
|
Args:
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
258
|
+
image: The image to use for the component.
|
259
|
+
command: The command to use for the component.
|
260
|
+
arguments: The arguments to use for the component.
|
261
|
+
component_name: The name of the component.
|
262
|
+
|
263
|
+
Returns:
|
264
|
+
The dynamic container component.
|
263
265
|
"""
|
264
|
-
# Set optional CPU, RAM and GPU constraints for the pipeline
|
265
266
|
|
266
|
-
|
267
|
+
def dynamic_container_component() -> dsl.ContainerSpec:
|
268
|
+
"""Dynamic container component.
|
267
269
|
|
268
|
-
|
269
|
-
|
270
|
+
Returns:
|
271
|
+
The dynamic container component.
|
272
|
+
"""
|
273
|
+
return dsl.ContainerSpec(
|
274
|
+
image=image,
|
275
|
+
command=command,
|
276
|
+
args=arguments,
|
277
|
+
)
|
270
278
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
279
|
+
# Change the name of the function
|
280
|
+
new_container_spec_func = types.FunctionType(
|
281
|
+
dynamic_container_component.__code__,
|
282
|
+
dynamic_container_component.__globals__,
|
283
|
+
name=component_name,
|
284
|
+
argdefs=dynamic_container_component.__defaults__,
|
285
|
+
closure=dynamic_container_component.__closure__,
|
275
286
|
)
|
276
|
-
|
277
|
-
container_op = container_op.set_memory_limit(memory_limit)
|
287
|
+
pipeline_task = dsl.container_component(new_container_spec_func)
|
278
288
|
|
279
|
-
|
280
|
-
resource_settings.gpu_count
|
281
|
-
if resource_settings.gpu_count is not None
|
282
|
-
else self.config.gpu_limit
|
283
|
-
)
|
284
|
-
if gpu_limit is not None and gpu_limit > 0:
|
285
|
-
container_op = container_op.set_gpu_limit(gpu_limit)
|
286
|
-
|
287
|
-
if node_selector_constraint:
|
288
|
-
constraint_label, value = node_selector_constraint
|
289
|
-
if not (
|
290
|
-
constraint_label
|
291
|
-
== GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL
|
292
|
-
and gpu_limit == 0
|
293
|
-
):
|
294
|
-
container_op.add_node_selector_constraint(
|
295
|
-
constraint_label, value
|
296
|
-
)
|
289
|
+
return pipeline_task
|
297
290
|
|
298
291
|
def prepare_or_run_pipeline(
|
299
292
|
self,
|
@@ -363,77 +356,150 @@ class VertexOrchestrator(ContainerizedOrchestrator, GoogleCredentialsMixin):
|
|
363
356
|
else:
|
364
357
|
self._pipeline_root = self.config.pipeline_root
|
365
358
|
|
366
|
-
def
|
367
|
-
"""Create a
|
359
|
+
def _create_dynamic_pipeline() -> Any:
|
360
|
+
"""Create a dynamic pipeline including each step.
|
368
361
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
Additionally, this gives each `ContainerOp` information about its
|
373
|
-
direct downstream steps.
|
374
|
-
|
375
|
-
If this callable is passed to the `compile()` method of
|
376
|
-
`KFPV2Compiler` all `dsl.ContainerOp` instances will be
|
377
|
-
automatically added to a singular `dsl.Pipeline` instance.
|
362
|
+
Returns:
|
363
|
+
pipeline_func
|
378
364
|
"""
|
379
|
-
|
380
|
-
|
365
|
+
step_name_to_dynamic_component: Dict[str, Any] = {}
|
366
|
+
node_selector_constraint: Optional[Tuple[str, str]] = None
|
381
367
|
|
382
368
|
for step_name, step in deployment.step_configurations.items():
|
383
369
|
image = self.get_image(
|
384
|
-
deployment=deployment,
|
370
|
+
deployment=deployment,
|
371
|
+
step_name=step_name,
|
385
372
|
)
|
373
|
+
command = StepEntrypointConfiguration.get_entrypoint_command()
|
386
374
|
arguments = (
|
387
375
|
StepEntrypointConfiguration.get_entrypoint_arguments(
|
388
|
-
step_name=step_name,
|
376
|
+
step_name=step_name,
|
377
|
+
deployment_id=deployment.id,
|
389
378
|
)
|
390
379
|
)
|
391
|
-
|
392
|
-
|
393
|
-
# `dsl.ContainerOp`
|
394
|
-
# class directly is deprecated when using the Kubeflow SDK v2.
|
395
|
-
container_op = kfp.components.load_component_from_text(
|
396
|
-
f"""
|
397
|
-
name: {step_name}
|
398
|
-
implementation:
|
399
|
-
container:
|
400
|
-
image: {image}
|
401
|
-
command: {command + arguments}"""
|
402
|
-
)()
|
403
|
-
|
404
|
-
container_op.set_env_variable(
|
405
|
-
name=ENV_ZENML_VERTEX_RUN_ID,
|
406
|
-
value=dslv2.PIPELINE_JOB_NAME_PLACEHOLDER,
|
380
|
+
dynamic_component = self._create_dynamic_component(
|
381
|
+
image, command, arguments, step_name
|
407
382
|
)
|
408
|
-
|
409
|
-
|
410
|
-
container_op.set_env_variable(name=key, value=value)
|
411
|
-
|
412
|
-
# Set upstream tasks as a dependency of the current step
|
413
|
-
for upstream_step_name in step.spec.upstream_steps:
|
414
|
-
upstream_container_op = step_name_to_container_op[
|
415
|
-
upstream_step_name
|
416
|
-
]
|
417
|
-
container_op.after(upstream_container_op)
|
418
|
-
|
419
|
-
settings = cast(
|
420
|
-
VertexOrchestratorSettings,
|
421
|
-
self.get_settings(step),
|
383
|
+
step_settings = cast(
|
384
|
+
VertexOrchestratorSettings, self.get_settings(step)
|
422
385
|
)
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
386
|
+
pod_settings = step_settings.pod_settings
|
387
|
+
if pod_settings:
|
388
|
+
if pod_settings.host_ipc:
|
389
|
+
logger.warning(
|
390
|
+
"Host IPC is set to `True` but not supported in "
|
391
|
+
"this orchestrator. Ignoring..."
|
392
|
+
)
|
393
|
+
if pod_settings.affinity:
|
394
|
+
logger.warning(
|
395
|
+
"Affinity is set but not supported in Vertex with "
|
396
|
+
"Kubeflow Pipelines 2.x. Ignoring..."
|
397
|
+
)
|
398
|
+
if pod_settings.tolerations:
|
399
|
+
logger.warning(
|
400
|
+
"Tolerations are set but not supported in "
|
401
|
+
"Vertex with Kubeflow Pipelines 2.x. Ignoring..."
|
402
|
+
)
|
403
|
+
if pod_settings.volumes:
|
404
|
+
logger.warning(
|
405
|
+
"Volumes are set but not supported in Vertex with "
|
406
|
+
"Kubeflow Pipelines 2.x. Ignoring..."
|
407
|
+
)
|
408
|
+
if pod_settings.volume_mounts:
|
409
|
+
logger.warning(
|
410
|
+
"Volume mounts are set but not supported in "
|
411
|
+
"Vertex with Kubeflow Pipelines 2.x. Ignoring..."
|
412
|
+
)
|
413
|
+
|
414
|
+
# apply pod settings
|
415
|
+
if (
|
416
|
+
GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL
|
417
|
+
in pod_settings.node_selectors.keys()
|
418
|
+
):
|
419
|
+
node_selector_constraint = (
|
420
|
+
GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL,
|
421
|
+
pod_settings.node_selectors[
|
422
|
+
GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL
|
423
|
+
],
|
424
|
+
)
|
425
|
+
elif step_settings.node_selector_constraint:
|
426
|
+
node_selector_constraint = (
|
427
|
+
GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL,
|
428
|
+
step_settings.node_selector_constraint[1],
|
429
|
+
)
|
430
|
+
|
431
|
+
step_name_to_dynamic_component[step_name] = dynamic_component
|
432
|
+
|
433
|
+
@dsl.pipeline( # type: ignore[misc]
|
434
|
+
display_name=orchestrator_run_name,
|
435
|
+
)
|
436
|
+
def dynamic_pipeline() -> None:
|
437
|
+
"""Dynamic pipeline."""
|
438
|
+
# iterate through the components one by one
|
439
|
+
# (from step_name_to_dynamic_component)
|
440
|
+
for (
|
441
|
+
component_name,
|
442
|
+
component,
|
443
|
+
) in step_name_to_dynamic_component.items():
|
444
|
+
# for each component, check to see what other steps are
|
445
|
+
# upstream of it
|
446
|
+
step = deployment.step_configurations[component_name]
|
447
|
+
upstream_step_components = [
|
448
|
+
step_name_to_dynamic_component[upstream_step_name]
|
449
|
+
for upstream_step_name in step.spec.upstream_steps
|
450
|
+
]
|
451
|
+
task = (
|
452
|
+
component()
|
453
|
+
.set_display_name(
|
454
|
+
name=component_name,
|
455
|
+
)
|
456
|
+
.set_caching_options(enable_caching=False)
|
457
|
+
.set_env_variable(
|
458
|
+
name=ENV_ZENML_VERTEX_RUN_ID,
|
459
|
+
value=dsl.PIPELINE_JOB_NAME_PLACEHOLDER,
|
460
|
+
)
|
461
|
+
.after(*upstream_step_components)
|
462
|
+
)
|
463
|
+
self._configure_container_resources(
|
464
|
+
task,
|
465
|
+
step.config.resource_settings,
|
466
|
+
node_selector_constraint,
|
427
467
|
)
|
428
468
|
|
429
|
-
|
430
|
-
container_op=container_op,
|
431
|
-
resource_settings=step.config.resource_settings,
|
432
|
-
node_selector_constraint=settings.node_selector_constraint,
|
433
|
-
)
|
434
|
-
container_op.set_caching_options(enable_caching=False)
|
469
|
+
return dynamic_pipeline
|
435
470
|
|
436
|
-
|
471
|
+
def _update_json_with_environment(
|
472
|
+
yaml_file_path: str, environment: Dict[str, str]
|
473
|
+
) -> None:
|
474
|
+
"""Updates the env section of the steps in the YAML file with the given environment variables.
|
475
|
+
|
476
|
+
Args:
|
477
|
+
yaml_file_path: The path to the YAML file to update.
|
478
|
+
environment: A dictionary of environment variables to add.
|
479
|
+
"""
|
480
|
+
pipeline_definition = yaml_utils.read_json(pipeline_file_path)
|
481
|
+
|
482
|
+
# Iterate through each component and add the environment variables
|
483
|
+
for executor in pipeline_definition["deploymentSpec"]["executors"]:
|
484
|
+
if (
|
485
|
+
"container"
|
486
|
+
in pipeline_definition["deploymentSpec"]["executors"][
|
487
|
+
executor
|
488
|
+
]
|
489
|
+
):
|
490
|
+
container = pipeline_definition["deploymentSpec"][
|
491
|
+
"executors"
|
492
|
+
][executor]["container"]
|
493
|
+
if "env" not in container:
|
494
|
+
container["env"] = []
|
495
|
+
for key, value in environment.items():
|
496
|
+
container["env"].append({"name": key, "value": value})
|
497
|
+
|
498
|
+
yaml_utils.write_json(pipeline_file_path, pipeline_definition)
|
499
|
+
|
500
|
+
print(
|
501
|
+
f"Updated YAML file with environment variables at {yaml_file_path}"
|
502
|
+
)
|
437
503
|
|
438
504
|
# Save the generated pipeline to a file.
|
439
505
|
fileio.makedirs(self.pipeline_directory)
|
@@ -445,13 +511,17 @@ class VertexOrchestrator(ContainerizedOrchestrator, GoogleCredentialsMixin):
|
|
445
511
|
# Compile the pipeline using the Kubeflow SDK V2 compiler that allows
|
446
512
|
# to generate a JSON representation of the pipeline that can be later
|
447
513
|
# upload to Vertex AI Pipelines service.
|
448
|
-
|
449
|
-
pipeline_func=
|
514
|
+
Compiler().compile(
|
515
|
+
pipeline_func=_create_dynamic_pipeline(),
|
450
516
|
package_path=pipeline_file_path,
|
451
517
|
pipeline_name=_clean_pipeline_name(
|
452
518
|
deployment.pipeline_configuration.name
|
453
519
|
),
|
454
520
|
)
|
521
|
+
|
522
|
+
# Let's update the YAML file with the environment variables
|
523
|
+
_update_json_with_environment(pipeline_file_path, environment)
|
524
|
+
|
455
525
|
logger.info(
|
456
526
|
"Writing Vertex workflow definition to `%s`.", pipeline_file_path
|
457
527
|
)
|
@@ -617,3 +687,64 @@ class VertexOrchestrator(ContainerizedOrchestrator, GoogleCredentialsMixin):
|
|
617
687
|
return {
|
618
688
|
METADATA_ORCHESTRATOR_URL: Uri(run_url),
|
619
689
|
}
|
690
|
+
|
691
|
+
def _configure_container_resources(
|
692
|
+
self,
|
693
|
+
dynamic_component: dsl.PipelineTask,
|
694
|
+
resource_settings: "ResourceSettings",
|
695
|
+
node_selector_constraint: Optional[Tuple[str, str]] = None,
|
696
|
+
) -> dsl.PipelineTask:
|
697
|
+
"""Adds resource requirements to the container.
|
698
|
+
|
699
|
+
Args:
|
700
|
+
dynamic_component: The dynamic component to add the resource
|
701
|
+
settings to.
|
702
|
+
resource_settings: The resource settings to use for this
|
703
|
+
container.
|
704
|
+
node_selector_constraint: Node selector constraint to apply to
|
705
|
+
the container.
|
706
|
+
|
707
|
+
Returns:
|
708
|
+
The dynamic component with the resource settings applied.
|
709
|
+
"""
|
710
|
+
# Set optional CPU, RAM and GPU constraints for the pipeline
|
711
|
+
if resource_settings:
|
712
|
+
cpu_limit = resource_settings.cpu_count or self.config.cpu_limit
|
713
|
+
|
714
|
+
if cpu_limit is not None:
|
715
|
+
dynamic_component = dynamic_component.set_cpu_limit(str(cpu_limit))
|
716
|
+
|
717
|
+
memory_limit = (
|
718
|
+
resource_settings.memory[:-1]
|
719
|
+
if resource_settings.memory
|
720
|
+
else self.config.memory_limit
|
721
|
+
)
|
722
|
+
if memory_limit is not None:
|
723
|
+
dynamic_component = dynamic_component.set_memory_limit(
|
724
|
+
memory_limit
|
725
|
+
)
|
726
|
+
|
727
|
+
gpu_limit = (
|
728
|
+
resource_settings.gpu_count
|
729
|
+
if resource_settings.gpu_count is not None
|
730
|
+
else self.config.gpu_limit
|
731
|
+
)
|
732
|
+
|
733
|
+
if node_selector_constraint:
|
734
|
+
(constraint_label, value) = node_selector_constraint
|
735
|
+
if gpu_limit is not None and gpu_limit > 0:
|
736
|
+
dynamic_component = (
|
737
|
+
dynamic_component.set_accelerator_type(value)
|
738
|
+
.set_accelerator_limit(gpu_limit)
|
739
|
+
.set_gpu_limit(gpu_limit)
|
740
|
+
)
|
741
|
+
elif (
|
742
|
+
constraint_label
|
743
|
+
== GKE_ACCELERATOR_NODE_SELECTOR_CONSTRAINT_LABEL
|
744
|
+
and gpu_limit == 0
|
745
|
+
):
|
746
|
+
logger.warning(
|
747
|
+
"GPU limit is set to 0 but a GPU type is specified. Ignoring GPU settings."
|
748
|
+
)
|
749
|
+
|
750
|
+
return dynamic_component
|
@@ -46,7 +46,7 @@ from google.auth.transport.requests import Request
|
|
46
46
|
from google.cloud import container_v1, storage
|
47
47
|
from google.oauth2 import credentials as gcp_credentials
|
48
48
|
from google.oauth2 import service_account as gcp_service_account
|
49
|
-
from pydantic import Field,
|
49
|
+
from pydantic import Field, field_validator, model_validator
|
50
50
|
|
51
51
|
from zenml.constants import (
|
52
52
|
DOCKER_REGISTRY_RESOURCE_TYPE,
|
@@ -74,6 +74,8 @@ from zenml.service_connectors.service_connector import (
|
|
74
74
|
ServiceConnector,
|
75
75
|
)
|
76
76
|
from zenml.utils.enum_utils import StrEnum
|
77
|
+
from zenml.utils.pydantic_utils import before_validator_handler
|
78
|
+
from zenml.utils.secret_utils import PlainSerializedSecretStr
|
77
79
|
|
78
80
|
logger = get_logger(__name__)
|
79
81
|
|
@@ -85,7 +87,7 @@ GCP_SESSION_EXPIRATION_BUFFER = 15 # 15 minutes
|
|
85
87
|
class GCPUserAccountCredentials(AuthenticationConfig):
|
86
88
|
"""GCP user account credentials."""
|
87
89
|
|
88
|
-
user_account_json:
|
90
|
+
user_account_json: PlainSerializedSecretStr = Field(
|
89
91
|
title="GCP User Account Credentials JSON",
|
90
92
|
)
|
91
93
|
|
@@ -97,30 +99,33 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
97
99
|
"distribute the user account credentials JSON to clients instead.",
|
98
100
|
)
|
99
101
|
|
100
|
-
@
|
102
|
+
@model_validator(mode="before")
|
103
|
+
@classmethod
|
104
|
+
@before_validator_handler
|
101
105
|
def validate_user_account_dict(
|
102
|
-
cls,
|
106
|
+
cls, data: Dict[str, Any]
|
103
107
|
) -> Dict[str, Any]:
|
104
108
|
"""Convert the user account credentials to JSON if given in dict format.
|
105
109
|
|
106
110
|
Args:
|
107
|
-
|
111
|
+
data: The configuration values.
|
108
112
|
|
109
113
|
Returns:
|
110
114
|
The validated configuration values.
|
111
115
|
"""
|
112
|
-
if isinstance(
|
113
|
-
|
114
|
-
|
115
|
-
)
|
116
|
-
return values
|
116
|
+
if isinstance(data.get("user_account_json"), dict):
|
117
|
+
data["user_account_json"] = json.dumps(data["user_account_json"])
|
118
|
+
return data
|
117
119
|
|
118
|
-
@
|
119
|
-
|
120
|
+
@field_validator("user_account_json")
|
121
|
+
@classmethod
|
122
|
+
def validate_user_account_json(
|
123
|
+
cls, value: PlainSerializedSecretStr
|
124
|
+
) -> PlainSerializedSecretStr:
|
120
125
|
"""Validate the user account credentials JSON.
|
121
126
|
|
122
127
|
Args:
|
123
|
-
|
128
|
+
value: The user account credentials JSON.
|
124
129
|
|
125
130
|
Returns:
|
126
131
|
The validated user account credentials JSON.
|
@@ -129,7 +134,7 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
129
134
|
ValueError: If the user account credentials JSON is invalid.
|
130
135
|
"""
|
131
136
|
try:
|
132
|
-
user_account_info = json.loads(
|
137
|
+
user_account_info = json.loads(value.get_secret_value())
|
133
138
|
except json.JSONDecodeError as e:
|
134
139
|
raise ValueError(
|
135
140
|
f"GCP user account credentials is not a valid JSON: {e}"
|
@@ -157,13 +162,13 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
157
162
|
"instead of 'authorized_user'."
|
158
163
|
)
|
159
164
|
|
160
|
-
return
|
165
|
+
return value
|
161
166
|
|
162
167
|
|
163
168
|
class GCPServiceAccountCredentials(AuthenticationConfig):
|
164
169
|
"""GCP service account credentials."""
|
165
170
|
|
166
|
-
service_account_json:
|
171
|
+
service_account_json: PlainSerializedSecretStr = Field(
|
167
172
|
title="GCP Service Account Key JSON",
|
168
173
|
)
|
169
174
|
|
@@ -175,30 +180,35 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
175
180
|
"distribute the service account key JSON to clients instead.",
|
176
181
|
)
|
177
182
|
|
178
|
-
@
|
183
|
+
@model_validator(mode="before")
|
184
|
+
@classmethod
|
185
|
+
@before_validator_handler
|
179
186
|
def validate_service_account_dict(
|
180
|
-
cls,
|
187
|
+
cls, data: Dict[str, Any]
|
181
188
|
) -> Dict[str, Any]:
|
182
189
|
"""Convert the service account credentials to JSON if given in dict format.
|
183
190
|
|
184
191
|
Args:
|
185
|
-
|
192
|
+
data: The configuration values.
|
186
193
|
|
187
194
|
Returns:
|
188
195
|
The validated configuration values.
|
189
196
|
"""
|
190
|
-
if isinstance(
|
191
|
-
|
192
|
-
|
197
|
+
if isinstance(data.get("service_account_json"), dict):
|
198
|
+
data["service_account_json"] = json.dumps(
|
199
|
+
data["service_account_json"]
|
193
200
|
)
|
194
|
-
return
|
201
|
+
return data
|
195
202
|
|
196
|
-
@
|
197
|
-
|
203
|
+
@field_validator("service_account_json")
|
204
|
+
@classmethod
|
205
|
+
def validate_service_account_json(
|
206
|
+
cls, value: PlainSerializedSecretStr
|
207
|
+
) -> PlainSerializedSecretStr:
|
198
208
|
"""Validate the service account credentials JSON.
|
199
209
|
|
200
210
|
Args:
|
201
|
-
|
211
|
+
value: The service account credentials JSON.
|
202
212
|
|
203
213
|
Returns:
|
204
214
|
The validated service account credentials JSON.
|
@@ -207,7 +217,7 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
207
217
|
ValueError: If the service account credentials JSON is invalid.
|
208
218
|
"""
|
209
219
|
try:
|
210
|
-
service_account_info = json.loads(
|
220
|
+
service_account_info = json.loads(value.get_secret_value())
|
211
221
|
except json.JSONDecodeError as e:
|
212
222
|
raise ValueError(
|
213
223
|
f"GCP service account credentials is not a valid JSON: {e}"
|
@@ -243,13 +253,13 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
243
253
|
"instead of 'service_account'."
|
244
254
|
)
|
245
255
|
|
246
|
-
return
|
256
|
+
return value
|
247
257
|
|
248
258
|
|
249
259
|
class GCPExternalAccountCredentials(AuthenticationConfig):
|
250
260
|
"""GCP external account credentials."""
|
251
261
|
|
252
|
-
external_account_json:
|
262
|
+
external_account_json: PlainSerializedSecretStr = Field(
|
253
263
|
title="GCP External Account JSON",
|
254
264
|
)
|
255
265
|
|
@@ -261,30 +271,35 @@ class GCPExternalAccountCredentials(AuthenticationConfig):
|
|
261
271
|
"distribute the external account JSON to clients instead.",
|
262
272
|
)
|
263
273
|
|
264
|
-
@
|
274
|
+
@model_validator(mode="before")
|
275
|
+
@classmethod
|
276
|
+
@before_validator_handler
|
265
277
|
def validate_service_account_dict(
|
266
|
-
cls,
|
278
|
+
cls, data: Dict[str, Any]
|
267
279
|
) -> Dict[str, Any]:
|
268
280
|
"""Convert the external account credentials to JSON if given in dict format.
|
269
281
|
|
270
282
|
Args:
|
271
|
-
|
283
|
+
data: The configuration values.
|
272
284
|
|
273
285
|
Returns:
|
274
286
|
The validated configuration values.
|
275
287
|
"""
|
276
|
-
if isinstance(
|
277
|
-
|
278
|
-
|
288
|
+
if isinstance(data.get("external_account_json"), dict):
|
289
|
+
data["external_account_json"] = json.dumps(
|
290
|
+
data["external_account_json"]
|
279
291
|
)
|
280
|
-
return
|
292
|
+
return data
|
281
293
|
|
282
|
-
@
|
283
|
-
|
294
|
+
@field_validator("external_account_json")
|
295
|
+
@classmethod
|
296
|
+
def validate_external_account_json(
|
297
|
+
cls, value: PlainSerializedSecretStr
|
298
|
+
) -> PlainSerializedSecretStr:
|
284
299
|
"""Validate the external account credentials JSON.
|
285
300
|
|
286
301
|
Args:
|
287
|
-
|
302
|
+
value: The external account credentials JSON.
|
288
303
|
|
289
304
|
Returns:
|
290
305
|
The validated external account credentials JSON.
|
@@ -293,7 +308,7 @@ class GCPExternalAccountCredentials(AuthenticationConfig):
|
|
293
308
|
ValueError: If the external account credentials JSON is invalid.
|
294
309
|
"""
|
295
310
|
try:
|
296
|
-
external_account_info = json.loads(
|
311
|
+
external_account_info = json.loads(value.get_secret_value())
|
297
312
|
except json.JSONDecodeError as e:
|
298
313
|
raise ValueError(
|
299
314
|
f"GCP external account credentials is not a valid JSON: {e}"
|
@@ -322,13 +337,13 @@ class GCPExternalAccountCredentials(AuthenticationConfig):
|
|
322
337
|
"instead of 'external_account'."
|
323
338
|
)
|
324
339
|
|
325
|
-
return
|
340
|
+
return value
|
326
341
|
|
327
342
|
|
328
343
|
class GCPOAuth2Token(AuthenticationConfig):
|
329
344
|
"""GCP OAuth 2.0 token credentials."""
|
330
345
|
|
331
|
-
token:
|
346
|
+
token: PlainSerializedSecretStr = Field(
|
332
347
|
title="GCP OAuth 2.0 Token",
|
333
348
|
)
|
334
349
|
|
@@ -50,7 +50,7 @@ class GitHubCodeRepositoryConfig(BaseCodeRepositoryConfig):
|
|
50
50
|
owner: str
|
51
51
|
repository: str
|
52
52
|
host: Optional[str] = "github.com"
|
53
|
-
token: Optional[str] = SecretField()
|
53
|
+
token: Optional[str] = SecretField(default=None)
|
54
54
|
|
55
55
|
|
56
56
|
class GitHubCodeRepository(BaseCodeRepository):
|