zenml-nightly 0.70.0.dev20241125__py3-none-any.whl → 0.71.0.dev20241220__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.
- README.md +4 -4
- RELEASE_NOTES.md +112 -0
- zenml/VERSION +1 -1
- zenml/artifact_stores/base_artifact_store.py +2 -2
- zenml/artifacts/artifact_config.py +15 -6
- zenml/artifacts/utils.py +59 -32
- zenml/cli/__init__.py +22 -4
- zenml/cli/base.py +5 -5
- zenml/cli/login.py +26 -0
- zenml/cli/pipeline.py +111 -62
- zenml/cli/server.py +20 -20
- zenml/cli/service_connectors.py +3 -3
- zenml/cli/stack.py +0 -3
- zenml/cli/stack_components.py +0 -1
- zenml/cli/utils.py +0 -5
- zenml/client.py +62 -20
- zenml/config/compiler.py +12 -3
- zenml/config/pipeline_configurations.py +20 -0
- zenml/config/pipeline_run_configuration.py +1 -0
- zenml/config/secret_reference_mixin.py +1 -1
- zenml/config/server_config.py +4 -0
- zenml/config/step_configurations.py +21 -0
- zenml/constants.py +10 -0
- zenml/enums.py +1 -0
- zenml/image_builders/base_image_builder.py +5 -2
- zenml/image_builders/build_context.py +7 -16
- zenml/image_builders/local_image_builder.py +13 -3
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/aws/__init__.py +3 -0
- zenml/integrations/aws/flavors/__init__.py +6 -0
- zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
- 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 +14 -6
- zenml/integrations/constants.py +1 -0
- zenml/integrations/feast/__init__.py +1 -1
- zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -9
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +2 -1
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +11 -0
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +46 -2
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +13 -2
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +3 -1
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +3 -2
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +3 -2
- zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +11 -0
- 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 +69 -53
- zenml/integrations/registry.py +2 -2
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +12 -0
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +13 -5
- zenml/io/filesystem.py +2 -2
- zenml/io/local_filesystem.py +3 -3
- zenml/materializers/built_in_materializer.py +18 -1
- zenml/materializers/structured_string_materializer.py +8 -3
- zenml/model/model.py +23 -101
- zenml/model/utils.py +21 -17
- zenml/models/__init__.py +6 -0
- zenml/models/v2/base/filter.py +26 -30
- zenml/models/v2/base/scoped.py +258 -5
- zenml/models/v2/core/artifact_version.py +21 -29
- zenml/models/v2/core/code_repository.py +1 -12
- zenml/models/v2/core/component.py +5 -68
- zenml/models/v2/core/flavor.py +1 -11
- zenml/models/v2/core/model.py +1 -57
- zenml/models/v2/core/model_version.py +11 -36
- zenml/models/v2/core/model_version_artifact.py +11 -3
- zenml/models/v2/core/model_version_pipeline_run.py +14 -3
- zenml/models/v2/core/pipeline.py +47 -55
- zenml/models/v2/core/pipeline_build.py +67 -12
- zenml/models/v2/core/pipeline_deployment.py +0 -10
- zenml/models/v2/core/pipeline_run.py +110 -32
- zenml/models/v2/core/run_metadata.py +30 -9
- zenml/models/v2/core/run_template.py +21 -29
- zenml/models/v2/core/schedule.py +0 -10
- zenml/models/v2/core/secret.py +0 -14
- zenml/models/v2/core/service.py +9 -16
- zenml/models/v2/core/service_connector.py +0 -11
- zenml/models/v2/core/stack.py +21 -30
- zenml/models/v2/core/step_run.py +24 -18
- zenml/models/v2/core/trigger.py +19 -3
- zenml/models/v2/misc/run_metadata.py +38 -0
- zenml/orchestrators/base_orchestrator.py +13 -1
- zenml/orchestrators/input_utils.py +19 -6
- zenml/orchestrators/output_utils.py +5 -1
- zenml/orchestrators/publish_utils.py +12 -5
- zenml/orchestrators/step_launcher.py +16 -16
- zenml/orchestrators/step_run_utils.py +18 -197
- zenml/orchestrators/step_runner.py +40 -3
- zenml/orchestrators/utils.py +79 -50
- zenml/pipelines/build_utils.py +12 -0
- zenml/pipelines/pipeline_decorator.py +4 -0
- zenml/pipelines/pipeline_definition.py +26 -8
- zenml/pipelines/run_utils.py +9 -5
- zenml/service_connectors/service_connector_utils.py +3 -9
- zenml/stack/stack_component.py +1 -1
- zenml/stack_deployments/aws_stack_deployment.py +22 -0
- zenml/steps/base_step.py +11 -1
- zenml/steps/entrypoint_function_utils.py +7 -3
- zenml/steps/step_decorator.py +4 -0
- zenml/steps/utils.py +23 -7
- zenml/types.py +4 -0
- zenml/utils/archivable.py +65 -36
- zenml/utils/code_utils.py +8 -4
- zenml/utils/docker_utils.py +9 -0
- zenml/utils/metadata_utils.py +186 -153
- zenml/utils/string_utils.py +41 -16
- zenml/utils/visualization_utils.py +4 -1
- zenml/zen_server/auth.py +9 -10
- zenml/zen_server/cloud_utils.py +3 -1
- zenml/zen_server/dashboard/assets/{404-NVXKFp-x.js → 404-Cqu3EDCm.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-CK0KJUen.js → @reactflow-D2Y7BWwz.js} +1 -1
- zenml/zen_server/dashboard/assets/{AlertDialogDropdownItem-DezXKmDf.js → AlertDialogDropdownItem-BHd71pVS.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-JzR8CEtw.js → CodeSnippet-DIonwetW.js} +1 -1
- zenml/zen_server/dashboard/assets/{CollapsibleCard-DQW_ktMO.js → CollapsibleCard-CDnC97pB.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-DL2kwkRd.js → Commands-BVEXKAOj.js} +1 -1
- zenml/zen_server/dashboard/assets/{ComponentBadge-D_g62Wv8.js → ComponentBadge-CrRvovox.js} +1 -1
- zenml/zen_server/dashboard/assets/{CopyButton-LNcWaa14.js → CopyButton-B6wGAhQv.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-DknpE5ej.js → CsvVizualization-CjcT7LMm.js} +5 -5
- zenml/zen_server/dashboard/assets/DeleteAlertDialog-D2ELtM2W.js +1 -0
- zenml/zen_server/dashboard/assets/{DialogItem-Bxf8FuAT.js → DialogItem-DXIMhBgU.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-DYflYyps.js → Error-B8uUfTpL.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-C7zyIQKZ.js → ExecutionStatus-ibAdY-dG.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-oYSGpLqd.js → Helpbox-BfAfhKHw.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-Cx4xGoXR.js → Infobox-M_SMOu96.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-DiGOWNKF.js → InlineAvatar-DBA0a0-a.js} +1 -1
- zenml/zen_server/dashboard/assets/{NestedCollapsible-DYbgyKxK.js → NestedCollapsible-DpgmEFKw.js} +1 -1
- zenml/zen_server/dashboard/assets/{Partials-03iZf8-N.js → Partials-D_ldD9if.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProBadge-D_EB8HNo.js → ProBadge-DQbfFotM.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProCta-DqNS4v3x.js → ProCta-Bcpb4rcY.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderIcon-Bki2aw8w.js → ProviderIcon-BZpgPigN.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderRadio-8f43sPD4.js → ProviderRadio-DWPnMuQ1.js} +1 -1
- zenml/zen_server/dashboard/assets/RunSelector-DgRGaAc6.js +1 -0
- zenml/zen_server/dashboard/assets/{RunsBody-07YEO7qI.js → RunsBody-KecfSkjY.js} +1 -1
- zenml/zen_server/dashboard/assets/{SearchField-lp1KgU4e.js → SearchField-n-ILHnaP.js} +1 -1
- zenml/zen_server/dashboard/assets/{SecretTooltip-CgnbyeOx.js → SecretTooltip-B8MrX5yu.js} +1 -1
- zenml/zen_server/dashboard/assets/{SetPassword-CpP418A2.js → SetPassword-B_IVq_wg.js} +1 -1
- zenml/zen_server/dashboard/assets/StackList-TWPBYnkF.js +1 -0
- zenml/zen_server/dashboard/assets/{Tabs-BktHkCJJ.js → Tabs-Rg857zmd.js} +1 -1
- zenml/zen_server/dashboard/assets/{Tick-BlMoIlJT.js → Tick-COg4A-xo.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-Sc0A0pP-.js → UpdatePasswordSchemas-C6Aj3hm6.js} +1 -1
- zenml/zen_server/dashboard/assets/{UsageReason-YYduL4fj.js → UsageReason-BTLbx7w4.js} +1 -1
- zenml/zen_server/dashboard/assets/{WizardFooter-dgmizSJC.js → WizardFooter-BCAj69Vj.js} +1 -1
- zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-D-c2G6lV.js → all-pipeline-runs-query-DMXkDrV2.js} +1 -1
- zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
- zenml/zen_server/dashboard/assets/{create-stack-DM_JPgef.js → create-stack-HfdbhLs4.js} +1 -1
- zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
- zenml/zen_server/dashboard/assets/delete-run-DZ4hIXff.js +1 -0
- zenml/zen_server/dashboard/assets/{form-schemas-K6FYKjwa.js → form-schemas-B0AVEd9b.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-BAkC7FXi.js → index-DPqSWjug.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-CEV4Cvaf.js → index-DScjfBRb.js} +1 -1
- zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
- zenml/zen_server/dashboard/assets/{index-CCOPpudF.js → index-FO-p0GU7.js} +5 -5
- zenml/zen_server/dashboard/assets/{index-B1mVPYxf.js → index-I3bKUGUj.js} +1 -1
- zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
- zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-hf-lK87O.js → login-mutation-BQeo4wTY.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-BGirLjU-.js → not-found-gAJ5aDdR.js} +1 -1
- zenml/zen_server/dashboard/assets/page-9Y9-gig0.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DjRJCGb3.js → page-AUwiQ14W.js} +1 -1
- zenml/zen_server/dashboard/assets/page-B6XU7yYT.js +2 -0
- zenml/zen_server/dashboard/assets/{page-C00YAkaB.js → page-BKZYc2Zv.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CdMWnQak.js → page-BU9FG4sR.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D7S3aCbF.js → page-B_Apk3xg.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Djikxq_S.js → page-BdowiCbr.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Bg8OjTRe.js +1 -0
- zenml/zen_server/dashboard/assets/page-BxL4qD4_.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DakHVWXF.js → page-CWxT5K5J.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CXuQufSe.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DLC-bNBP.js → page-CcQr8CPP.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CD-DcWoy.js → page-Ce4Hrjnr.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CiYxgZP_.js +1 -0
- zenml/zen_server/dashboard/assets/page-Cldq1mpe.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BDigxVpo.js → page-D4wdonLm.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D6uU2ax4.js → page-D8ObrbH8.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DXSTpqRD.js → page-DFuAUGt4.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CbpvrsDL.js → page-DGazBpuP.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-COXXJj1k.js → page-DO1UcqPX.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DRYXdL5o.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Df-Fw0aq.js → page-DYEquBC2.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Dk32IeZm.js +1 -0
- zenml/zen_server/dashboard/assets/{page-yYC9OI-E.js → page-I3nKFGie.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-6m6yHHlE.js → page-M0w-n6vn.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Vcxara9U.js → page-R5dx3xGF.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BR68V0V1.js → page-bT5pOvcB.js} +1 -1
- zenml/zen_server/dashboard/assets/page-hUqK889I.js +6 -0
- zenml/zen_server/dashboard/assets/{page-CjGdWY13.js → page-h_Stveon.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D01JhjQB.js → page-r8XK5vR7.js} +1 -1
- zenml/zen_server/dashboard/assets/page-u_-ZXBKb.js +1 -0
- zenml/zen_server/dashboard/assets/page-zaMqB_ao.js +1 -0
- zenml/zen_server/dashboard/assets/{persist-GjC8PZoC.js → persist-AppN1B0J.js} +1 -1
- zenml/zen_server/dashboard/assets/{persist-Coz7ZWvz.js → persist-DAUi_3za.js} +1 -1
- zenml/zen_server/dashboard/assets/service-BqqeXLEe.js +2 -0
- zenml/zen_server/dashboard/assets/{sharedSchema-CQb14VSr.js → sharedSchema-uXN9FLLk.js} +1 -1
- zenml/zen_server/dashboard/assets/{stack-detail-query-OPEW-cDJ.js → stack-detail-query-XfZBiBP2.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-LwuQfHYn.js → update-server-settings-mutation-BWmgVJwA.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-CkvKAnwF.js → url-BLwMbzES.js} +1 -1
- zenml/zen_server/dashboard/index.html +4 -4
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/rbac/endpoint_utils.py +6 -4
- zenml/zen_server/rbac/models.py +3 -2
- zenml/zen_server/rbac/rbac_sql_zen_store.py +173 -0
- zenml/zen_server/rbac/utils.py +4 -7
- zenml/zen_server/routers/auth_endpoints.py +22 -11
- zenml/zen_server/routers/steps_endpoints.py +7 -1
- zenml/zen_server/routers/users_endpoints.py +35 -37
- zenml/zen_server/routers/workspaces_endpoints.py +44 -55
- zenml/zen_server/template_execution/utils.py +4 -1
- zenml/zen_server/utils.py +4 -3
- zenml/zen_stores/base_zen_store.py +10 -2
- zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
- zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
- zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
- zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +7 -6
- zenml/zen_stores/rest_zen_store.py +76 -43
- zenml/zen_stores/schemas/__init__.py +5 -1
- zenml/zen_stores/schemas/artifact_schemas.py +12 -11
- zenml/zen_stores/schemas/component_schemas.py +0 -3
- zenml/zen_stores/schemas/model_schemas.py +55 -17
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
- zenml/zen_stores/schemas/pipeline_run_schemas.py +52 -18
- zenml/zen_stores/schemas/pipeline_schemas.py +5 -0
- zenml/zen_stores/schemas/run_metadata_schemas.py +66 -31
- zenml/zen_stores/schemas/step_run_schemas.py +40 -13
- zenml/zen_stores/schemas/utils.py +47 -3
- zenml/zen_stores/sql_zen_store.py +462 -134
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/METADATA +5 -5
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/RECORD +239 -217
- zenml/utils/cloud_utils.py +0 -40
- zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +0 -1
- zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +0 -1
- zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +0 -1
- zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +0 -1
- zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +0 -1
- zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +0 -1
- zenml/zen_server/dashboard/assets/page-BU7huvKw.js +0 -6
- zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +0 -1
- zenml/zen_server/dashboard/assets/page-CwxrFarU.js +0 -1
- zenml/zen_server/dashboard/assets/page-DfbXf_8s.js +0 -1
- zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +0 -3
- zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +0 -1
- zenml/zen_server/dashboard/assets/page-Xynx4btY.js +0 -14
- zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +0 -1
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/entry_points.txt +0 -0
@@ -41,7 +41,6 @@ from zenml.constants import (
|
|
41
41
|
from zenml.enums import (
|
42
42
|
APITokenType,
|
43
43
|
AuthScheme,
|
44
|
-
ExecutionStatus,
|
45
44
|
OAuthDeviceStatus,
|
46
45
|
OAuthGrantTypes,
|
47
46
|
)
|
@@ -452,6 +451,7 @@ def device_authorization(
|
|
452
451
|
@handle_exceptions
|
453
452
|
def api_token(
|
454
453
|
token_type: APITokenType = APITokenType.GENERIC,
|
454
|
+
expires_in: Optional[int] = None,
|
455
455
|
schedule_id: Optional[UUID] = None,
|
456
456
|
pipeline_run_id: Optional[UUID] = None,
|
457
457
|
step_run_id: Optional[UUID] = None,
|
@@ -463,7 +463,8 @@ def api_token(
|
|
463
463
|
of API tokens are supported:
|
464
464
|
|
465
465
|
* Generic API token: This token is short-lived and can be used for
|
466
|
-
generic automation tasks.
|
466
|
+
generic automation tasks. The expiration can be set by the user, but the
|
467
|
+
server will impose a maximum expiration time.
|
467
468
|
* Workload API token: This token is scoped to a specific pipeline run, step
|
468
469
|
run or schedule and is used by pipeline workloads to authenticate with the
|
469
470
|
server. A pipeline run ID, step run ID or schedule ID must be provided and
|
@@ -475,6 +476,10 @@ def api_token(
|
|
475
476
|
|
476
477
|
Args:
|
477
478
|
token_type: The type of API token to generate.
|
479
|
+
expires_in: The expiration time of the generic API token in seconds.
|
480
|
+
If not set, the server will use the default expiration time for
|
481
|
+
generic API tokens. The server also imposes a maximum expiration
|
482
|
+
time.
|
478
483
|
schedule_id: The ID of the schedule to scope the workload API token to.
|
479
484
|
pipeline_run_id: The ID of the pipeline run to scope the workload API
|
480
485
|
token to.
|
@@ -502,9 +507,19 @@ def api_token(
|
|
502
507
|
|
503
508
|
config = server_config()
|
504
509
|
|
510
|
+
if not expires_in:
|
511
|
+
expires_in = config.generic_api_token_lifetime
|
512
|
+
|
513
|
+
if expires_in > config.generic_api_token_max_lifetime:
|
514
|
+
raise ValueError(
|
515
|
+
f"The maximum expiration time for generic API tokens allowed "
|
516
|
+
f"by this server is {config.generic_api_token_max_lifetime} "
|
517
|
+
"seconds."
|
518
|
+
)
|
519
|
+
|
505
520
|
return generate_access_token(
|
506
521
|
user_id=token.user_id,
|
507
|
-
expires_in=
|
522
|
+
expires_in=expires_in,
|
508
523
|
).access_token
|
509
524
|
|
510
525
|
verify_permission(
|
@@ -573,10 +588,7 @@ def api_token(
|
|
573
588
|
"security reasons."
|
574
589
|
)
|
575
590
|
|
576
|
-
if pipeline_run.status
|
577
|
-
ExecutionStatus.FAILED,
|
578
|
-
ExecutionStatus.COMPLETED,
|
579
|
-
]:
|
591
|
+
if pipeline_run.status.is_finished:
|
580
592
|
raise ValueError(
|
581
593
|
f"The execution of pipeline run {pipeline_run_id} has already "
|
582
594
|
"concluded and API tokens can no longer be generated for it "
|
@@ -593,10 +605,7 @@ def api_token(
|
|
593
605
|
"be generated for non-existent step runs for security reasons."
|
594
606
|
)
|
595
607
|
|
596
|
-
if step_run.status
|
597
|
-
ExecutionStatus.FAILED,
|
598
|
-
ExecutionStatus.COMPLETED,
|
599
|
-
]:
|
608
|
+
if step_run.status.is_finished:
|
600
609
|
raise ValueError(
|
601
610
|
f"The execution of step run {step_run_id} has already "
|
602
611
|
"concluded and API tokens can no longer be generated for it "
|
@@ -611,4 +620,6 @@ def api_token(
|
|
611
620
|
schedule_id=schedule_id,
|
612
621
|
pipeline_run_id=pipeline_run_id,
|
613
622
|
step_run_id=step_run_id,
|
623
|
+
# Never expire the token
|
624
|
+
expires_in=0,
|
614
625
|
).access_token
|
@@ -142,10 +142,16 @@ def get_step(
|
|
142
142
|
Returns:
|
143
143
|
The step.
|
144
144
|
"""
|
145
|
-
step
|
145
|
+
# We always fetch the step hydrated because we need the pipeline_run_id
|
146
|
+
# for the permission checks. If the user requested an unhydrated response,
|
147
|
+
# we later remove the metadata
|
148
|
+
step = zen_store().get_run_step(step_id, hydrate=True)
|
146
149
|
pipeline_run = zen_store().get_run(step.pipeline_run_id)
|
147
150
|
verify_permission_for_model(pipeline_run, action=Action.READ)
|
148
151
|
|
152
|
+
if hydrate is False:
|
153
|
+
step.metadata = None
|
154
|
+
|
149
155
|
return dehydrate_response_model(step)
|
150
156
|
|
151
157
|
|
@@ -46,14 +46,10 @@ from zenml.zen_server.auth import (
|
|
46
46
|
)
|
47
47
|
from zenml.zen_server.exceptions import error_response
|
48
48
|
from zenml.zen_server.rate_limit import RequestLimiter
|
49
|
-
from zenml.zen_server.rbac.endpoint_utils import (
|
50
|
-
verify_permissions_and_create_entity,
|
51
|
-
)
|
52
49
|
from zenml.zen_server.rbac.models import Action, Resource, ResourceType
|
53
50
|
from zenml.zen_server.rbac.utils import (
|
54
51
|
dehydrate_page,
|
55
52
|
dehydrate_response_model,
|
56
|
-
get_allowed_resource_ids,
|
57
53
|
get_schema_for_resource_type,
|
58
54
|
update_resource_membership,
|
59
55
|
verify_permission_for_model,
|
@@ -112,17 +108,18 @@ def list_users(
|
|
112
108
|
Returns:
|
113
109
|
A list of all users.
|
114
110
|
"""
|
115
|
-
allowed_ids = get_allowed_resource_ids(resource_type=ResourceType.USER)
|
116
|
-
if allowed_ids is not None:
|
117
|
-
|
118
|
-
|
119
|
-
else:
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
111
|
+
# allowed_ids = get_allowed_resource_ids(resource_type=ResourceType.USER)
|
112
|
+
# if allowed_ids is not None:
|
113
|
+
# # Make sure users can see themselves
|
114
|
+
# allowed_ids.add(auth_context.user.id)
|
115
|
+
# else:
|
116
|
+
# if not auth_context.user.is_admin and not server_config().rbac_enabled:
|
117
|
+
# allowed_ids = {auth_context.user.id}
|
118
|
+
if not auth_context.user.is_admin and not server_config().rbac_enabled:
|
119
|
+
user_filter_model.configure_rbac(
|
120
|
+
authenticated_user_id=auth_context.user.id,
|
121
|
+
id={auth_context.user.id},
|
122
|
+
)
|
126
123
|
|
127
124
|
page = zen_store().list_users(
|
128
125
|
user_filter_model=user_filter_model, hydrate=hydrate
|
@@ -175,11 +172,12 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
175
172
|
auth_context.user.is_admin, "create user"
|
176
173
|
)
|
177
174
|
|
178
|
-
new_user = verify_permissions_and_create_entity(
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
)
|
175
|
+
# new_user = verify_permissions_and_create_entity(
|
176
|
+
# request_model=user,
|
177
|
+
# resource_type=ResourceType.USER,
|
178
|
+
# create_method=zen_store().create_user,
|
179
|
+
# )
|
180
|
+
new_user = zen_store().create_user(user)
|
183
181
|
|
184
182
|
# add back the original unhashed activation token, if generated, to
|
185
183
|
# send it back to the client
|
@@ -217,10 +215,10 @@ def get_user(
|
|
217
215
|
verify_admin_status_if_no_rbac(
|
218
216
|
auth_context.user.is_admin, "get other user"
|
219
217
|
)
|
220
|
-
verify_permission_for_model(
|
221
|
-
|
222
|
-
|
223
|
-
)
|
218
|
+
# verify_permission_for_model(
|
219
|
+
# user,
|
220
|
+
# action=Action.READ,
|
221
|
+
# )
|
224
222
|
|
225
223
|
return dehydrate_response_model(user)
|
226
224
|
|
@@ -304,10 +302,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
304
302
|
verify_admin_status_if_no_rbac(
|
305
303
|
auth_context.user.is_admin, "update other user account"
|
306
304
|
)
|
307
|
-
verify_permission_for_model(
|
308
|
-
|
309
|
-
|
310
|
-
)
|
305
|
+
# verify_permission_for_model(
|
306
|
+
# user,
|
307
|
+
# action=Action.UPDATE,
|
308
|
+
# )
|
311
309
|
|
312
310
|
# Validate a password change
|
313
311
|
if user_update.password is not None:
|
@@ -497,10 +495,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
497
495
|
verify_admin_status_if_no_rbac(
|
498
496
|
auth_context.user.is_admin, "deactivate user"
|
499
497
|
)
|
500
|
-
verify_permission_for_model(
|
501
|
-
|
502
|
-
|
503
|
-
)
|
498
|
+
# verify_permission_for_model(
|
499
|
+
# user,
|
500
|
+
# action=Action.UPDATE,
|
501
|
+
# )
|
504
502
|
|
505
503
|
user_update = UserUpdate(
|
506
504
|
active=False,
|
@@ -548,10 +546,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
548
546
|
verify_admin_status_if_no_rbac(
|
549
547
|
auth_context.user.is_admin, "delete user"
|
550
548
|
)
|
551
|
-
verify_permission_for_model(
|
552
|
-
|
553
|
-
|
554
|
-
)
|
549
|
+
# verify_permission_for_model(
|
550
|
+
# user,
|
551
|
+
# action=Action.DELETE,
|
552
|
+
# )
|
555
553
|
|
556
554
|
zen_store().delete_user(user_name_or_id=user_name_or_id)
|
557
555
|
|
@@ -746,7 +744,7 @@ if server_config().rbac_enabled:
|
|
746
744
|
KeyError: If no resource with the given type and ID exists.
|
747
745
|
"""
|
748
746
|
user = zen_store().get_user(user_name_or_id)
|
749
|
-
verify_permission_for_model(user, action=Action.READ)
|
747
|
+
# verify_permission_for_model(user, action=Action.READ)
|
750
748
|
|
751
749
|
if user.id == auth_context.user.id:
|
752
750
|
raise ValueError(
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for workspaces."""
|
15
15
|
|
16
|
-
from typing import Dict, List, Optional, Tuple, Union
|
16
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -98,13 +98,13 @@ from zenml.zen_server.feature_gate.endpoint_utils import (
|
|
98
98
|
)
|
99
99
|
from zenml.zen_server.rbac.endpoint_utils import (
|
100
100
|
verify_permissions_and_create_entity,
|
101
|
-
verify_permissions_and_delete_entity,
|
102
|
-
verify_permissions_and_get_entity,
|
103
101
|
verify_permissions_and_list_entities,
|
104
|
-
verify_permissions_and_update_entity,
|
105
102
|
)
|
106
103
|
from zenml.zen_server.rbac.models import Action, ResourceType
|
107
104
|
from zenml.zen_server.rbac.utils import (
|
105
|
+
batch_verify_permissions_for_models,
|
106
|
+
dehydrate_page,
|
107
|
+
dehydrate_response_model,
|
108
108
|
get_allowed_resource_ids,
|
109
109
|
verify_permission,
|
110
110
|
verify_permission_for_model,
|
@@ -146,12 +146,10 @@ def list_workspaces(
|
|
146
146
|
Returns:
|
147
147
|
A list of workspaces.
|
148
148
|
"""
|
149
|
-
|
150
|
-
|
151
|
-
resource_type=ResourceType.WORKSPACE,
|
152
|
-
list_method=zen_store().list_workspaces,
|
153
|
-
hydrate=hydrate,
|
149
|
+
workspaces = zen_store().list_workspaces(
|
150
|
+
workspace_filter_model, hydrate=hydrate
|
154
151
|
)
|
152
|
+
return dehydrate_page(workspaces)
|
155
153
|
|
156
154
|
|
157
155
|
@router.post(
|
@@ -160,7 +158,7 @@ def list_workspaces(
|
|
160
158
|
)
|
161
159
|
@handle_exceptions
|
162
160
|
def create_workspace(
|
163
|
-
|
161
|
+
workspace_request: WorkspaceRequest,
|
164
162
|
_: AuthContext = Security(authorize),
|
165
163
|
) -> WorkspaceResponse:
|
166
164
|
"""Creates a workspace based on the requestBody.
|
@@ -168,16 +166,13 @@ def create_workspace(
|
|
168
166
|
# noqa: DAR401
|
169
167
|
|
170
168
|
Args:
|
171
|
-
|
169
|
+
workspace_request: Workspace to create.
|
172
170
|
|
173
171
|
Returns:
|
174
172
|
The created workspace.
|
175
173
|
"""
|
176
|
-
|
177
|
-
|
178
|
-
resource_type=ResourceType.WORKSPACE,
|
179
|
-
create_method=zen_store().create_workspace,
|
180
|
-
)
|
174
|
+
workspace = zen_store().create_workspace(workspace_request)
|
175
|
+
return dehydrate_response_model(workspace)
|
181
176
|
|
182
177
|
|
183
178
|
@router.get(
|
@@ -203,11 +198,10 @@ def get_workspace(
|
|
203
198
|
Returns:
|
204
199
|
The requested workspace.
|
205
200
|
"""
|
206
|
-
|
207
|
-
|
208
|
-
get_method=zen_store().get_workspace,
|
209
|
-
hydrate=hydrate,
|
201
|
+
workspace = zen_store().get_workspace(
|
202
|
+
workspace_name_or_id, hydrate=hydrate
|
210
203
|
)
|
204
|
+
return dehydrate_response_model(workspace)
|
211
205
|
|
212
206
|
|
213
207
|
@router.put(
|
@@ -231,12 +225,11 @@ def update_workspace(
|
|
231
225
|
Returns:
|
232
226
|
The updated workspace.
|
233
227
|
"""
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
get_method=zen_store().get_workspace,
|
238
|
-
update_method=zen_store().update_workspace,
|
228
|
+
workspace = zen_store().get_workspace(workspace_name_or_id, hydrate=False)
|
229
|
+
updated_workspace = zen_store().update_workspace(
|
230
|
+
workspace_id=workspace.id, workspace_update=workspace_update
|
239
231
|
)
|
232
|
+
return dehydrate_response_model(updated_workspace)
|
240
233
|
|
241
234
|
|
242
235
|
@router.delete(
|
@@ -253,11 +246,7 @@ def delete_workspace(
|
|
253
246
|
Args:
|
254
247
|
workspace_name_or_id: Name or ID of the workspace.
|
255
248
|
"""
|
256
|
-
|
257
|
-
id=workspace_name_or_id,
|
258
|
-
get_method=zen_store().get_workspace,
|
259
|
-
delete_method=zen_store().delete_workspace,
|
260
|
-
)
|
249
|
+
zen_store().delete_workspace(workspace_name_or_id)
|
261
250
|
|
262
251
|
|
263
252
|
@router.get(
|
@@ -951,20 +940,21 @@ def get_or_create_pipeline_run(
|
|
951
940
|
"is not supported."
|
952
941
|
)
|
953
942
|
|
954
|
-
|
955
|
-
|
956
|
-
|
943
|
+
def _pre_creation_hook() -> None:
|
944
|
+
verify_permission(
|
945
|
+
resource_type=ResourceType.PIPELINE_RUN, action=Action.CREATE
|
946
|
+
)
|
947
|
+
check_entitlement(resource_type=ResourceType.PIPELINE_RUN)
|
957
948
|
|
958
949
|
run, created = zen_store().get_or_create_run(
|
959
|
-
pipeline_run=pipeline_run,
|
960
|
-
pre_creation_hook=lambda: check_entitlement(
|
961
|
-
resource_type=ResourceType.PIPELINE_RUN
|
962
|
-
),
|
950
|
+
pipeline_run=pipeline_run, pre_creation_hook=_pre_creation_hook
|
963
951
|
)
|
964
952
|
if created:
|
965
953
|
report_usage(
|
966
954
|
resource_type=ResourceType.PIPELINE_RUN, resource_id=run.id
|
967
955
|
)
|
956
|
+
else:
|
957
|
+
verify_permission_for_model(run, action=Action.READ)
|
968
958
|
|
969
959
|
return run, created
|
970
960
|
|
@@ -1009,24 +999,23 @@ def create_run_metadata(
|
|
1009
999
|
"is not supported."
|
1010
1000
|
)
|
1011
1001
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
)
|
1002
|
+
verify_models: List[Any] = []
|
1003
|
+
for resource in run_metadata.resources:
|
1004
|
+
if resource.type == MetadataResourceTypes.PIPELINE_RUN:
|
1005
|
+
verify_models.append(zen_store().get_run(resource.id))
|
1006
|
+
elif resource.type == MetadataResourceTypes.STEP_RUN:
|
1007
|
+
verify_models.append(zen_store().get_run_step(resource.id))
|
1008
|
+
elif resource.type == MetadataResourceTypes.ARTIFACT_VERSION:
|
1009
|
+
verify_models.append(zen_store().get_artifact_version(resource.id))
|
1010
|
+
elif resource.type == MetadataResourceTypes.MODEL_VERSION:
|
1011
|
+
verify_models.append(zen_store().get_model_version(resource.id))
|
1012
|
+
else:
|
1013
|
+
raise RuntimeError(f"Unknown resource type: {resource.type}")
|
1014
|
+
|
1015
|
+
batch_verify_permissions_for_models(
|
1016
|
+
models=verify_models,
|
1017
|
+
action=Action.UPDATE,
|
1018
|
+
)
|
1030
1019
|
|
1031
1020
|
verify_permission(
|
1032
1021
|
resource_type=ResourceType.RUN_METADATA, action=Action.CREATE
|
@@ -122,13 +122,15 @@ def run_template(
|
|
122
122
|
placeholder_run = create_placeholder_run(deployment=new_deployment)
|
123
123
|
assert placeholder_run
|
124
124
|
|
125
|
-
# We create an API token scoped to the pipeline run
|
125
|
+
# We create an API token scoped to the pipeline run that never expires
|
126
126
|
api_token = generate_access_token(
|
127
127
|
user_id=auth_context.user.id,
|
128
128
|
pipeline_run_id=placeholder_run.id,
|
129
129
|
# Keep the original API key or device scopes, if any
|
130
130
|
api_key=auth_context.api_key,
|
131
131
|
device=auth_context.device,
|
132
|
+
# Never expire the token
|
133
|
+
expires_in=0,
|
132
134
|
).access_token
|
133
135
|
|
134
136
|
environment = {
|
@@ -363,6 +365,7 @@ def deployment_request_from_template(
|
|
363
365
|
"external_input_artifacts",
|
364
366
|
"model_artifacts_or_metadata",
|
365
367
|
"client_lazy_loaders",
|
368
|
+
"substitutions",
|
366
369
|
"outputs",
|
367
370
|
}
|
368
371
|
),
|
zenml/zen_server/utils.py
CHANGED
@@ -421,6 +421,8 @@ def make_dependable(cls: Type[BaseModel]) -> Callable[..., Any]:
|
|
421
421
|
"""
|
422
422
|
from fastapi import Query
|
423
423
|
|
424
|
+
from zenml.zen_server.exceptions import error_detail
|
425
|
+
|
424
426
|
def init_cls_and_handle_errors(*args: Any, **kwargs: Any) -> BaseModel:
|
425
427
|
from fastapi import HTTPException
|
426
428
|
|
@@ -428,9 +430,8 @@ def make_dependable(cls: Type[BaseModel]) -> Callable[..., Any]:
|
|
428
430
|
inspect.signature(init_cls_and_handle_errors).bind(*args, **kwargs)
|
429
431
|
return cls(*args, **kwargs)
|
430
432
|
except ValidationError as e:
|
431
|
-
|
432
|
-
|
433
|
-
raise HTTPException(422, detail=e.errors())
|
433
|
+
detail = error_detail(e, exception_type=ValueError)
|
434
|
+
raise HTTPException(422, detail=detail)
|
434
435
|
|
435
436
|
params = {v.name: v for v in inspect.signature(cls).parameters.values()}
|
436
437
|
query_params = getattr(cls, "API_MULTI_INPUT_PARAMS", [])
|
@@ -36,6 +36,7 @@ from zenml.constants import (
|
|
36
36
|
DEFAULT_STACK_AND_COMPONENT_NAME,
|
37
37
|
DEFAULT_WORKSPACE_NAME,
|
38
38
|
ENV_ZENML_DEFAULT_WORKSPACE_NAME,
|
39
|
+
ENV_ZENML_SERVER,
|
39
40
|
IS_DEBUG_ENV,
|
40
41
|
)
|
41
42
|
from zenml.enums import (
|
@@ -155,9 +156,16 @@ class BaseZenStore(
|
|
155
156
|
TypeError: If the store type is unsupported.
|
156
157
|
"""
|
157
158
|
if store_type == StoreType.SQL:
|
158
|
-
|
159
|
+
if os.environ.get(ENV_ZENML_SERVER):
|
160
|
+
from zenml.zen_server.rbac.rbac_sql_zen_store import (
|
161
|
+
RBACSqlZenStore,
|
162
|
+
)
|
163
|
+
|
164
|
+
return RBACSqlZenStore
|
165
|
+
else:
|
166
|
+
from zenml.zen_stores.sql_zen_store import SqlZenStore
|
159
167
|
|
160
|
-
|
168
|
+
return SqlZenStore
|
161
169
|
elif store_type == StoreType.REST:
|
162
170
|
from zenml.zen_stores.rest_zen_store import RestZenStore
|
163
171
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""Release [0.71.0].
|
2
|
+
|
3
|
+
Revision ID: 0.71.0
|
4
|
+
Revises: cc269488e5a9
|
5
|
+
Create Date: 2024-12-04 20:44:19.316139
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
# revision identifiers, used by Alembic.
|
10
|
+
revision = "0.71.0"
|
11
|
+
down_revision = "cc269488e5a9"
|
12
|
+
branch_labels = None
|
13
|
+
depends_on = None
|
14
|
+
|
15
|
+
|
16
|
+
def upgrade() -> None:
|
17
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
18
|
+
pass
|
19
|
+
|
20
|
+
|
21
|
+
def downgrade() -> None:
|
22
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
23
|
+
pass
|
@@ -0,0 +1,37 @@
|
|
1
|
+
"""Add step run unique constraint [26351d482b9e].
|
2
|
+
|
3
|
+
Revision ID: 26351d482b9e
|
4
|
+
Revises: 0.71.0
|
5
|
+
Create Date: 2024-12-03 11:46:57.541578
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
from alembic import op
|
10
|
+
|
11
|
+
# revision identifiers, used by Alembic.
|
12
|
+
revision = "26351d482b9e"
|
13
|
+
down_revision = "0.71.0"
|
14
|
+
branch_labels = None
|
15
|
+
depends_on = None
|
16
|
+
|
17
|
+
|
18
|
+
def upgrade() -> None:
|
19
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
20
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
21
|
+
with op.batch_alter_table("step_run", schema=None) as batch_op:
|
22
|
+
batch_op.create_unique_constraint(
|
23
|
+
"unique_step_name_for_pipeline_run", ["name", "pipeline_run_id"]
|
24
|
+
)
|
25
|
+
|
26
|
+
# ### end Alembic commands ###
|
27
|
+
|
28
|
+
|
29
|
+
def downgrade() -> None:
|
30
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
31
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
32
|
+
with op.batch_alter_table("step_run", schema=None) as batch_op:
|
33
|
+
batch_op.drop_constraint(
|
34
|
+
"unique_step_name_for_pipeline_run", type_="unique"
|
35
|
+
)
|
36
|
+
|
37
|
+
# ### end Alembic commands ###
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"""Add model version producer run unique constraint [a1237ba94fd8].
|
2
|
+
|
3
|
+
Revision ID: a1237ba94fd8
|
4
|
+
Revises: 26351d482b9e
|
5
|
+
Create Date: 2024-12-13 10:28:55.432414
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sqlalchemy as sa
|
10
|
+
import sqlmodel
|
11
|
+
from alembic import op
|
12
|
+
|
13
|
+
# revision identifiers, used by Alembic.
|
14
|
+
revision = "a1237ba94fd8"
|
15
|
+
down_revision = "26351d482b9e"
|
16
|
+
branch_labels = None
|
17
|
+
depends_on = None
|
18
|
+
|
19
|
+
|
20
|
+
def upgrade() -> None:
|
21
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
22
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
23
|
+
with op.batch_alter_table("model_version", schema=None) as batch_op:
|
24
|
+
batch_op.add_column(
|
25
|
+
sa.Column(
|
26
|
+
"producer_run_id_if_numeric",
|
27
|
+
sqlmodel.sql.sqltypes.GUID(),
|
28
|
+
nullable=True,
|
29
|
+
)
|
30
|
+
)
|
31
|
+
|
32
|
+
# Set the producer_run_id_if_numeric column to the model version ID for
|
33
|
+
# existing rows
|
34
|
+
connection = op.get_bind()
|
35
|
+
metadata = sa.MetaData()
|
36
|
+
metadata.reflect(only=("model_version",), bind=connection)
|
37
|
+
model_version_table = sa.Table("model_version", metadata)
|
38
|
+
|
39
|
+
connection.execute(
|
40
|
+
model_version_table.update().values(
|
41
|
+
producer_run_id_if_numeric=model_version_table.c.id
|
42
|
+
)
|
43
|
+
)
|
44
|
+
|
45
|
+
with op.batch_alter_table("model_version", schema=None) as batch_op:
|
46
|
+
batch_op.alter_column(
|
47
|
+
"producer_run_id_if_numeric",
|
48
|
+
existing_type=sqlmodel.sql.sqltypes.GUID(),
|
49
|
+
nullable=False,
|
50
|
+
)
|
51
|
+
batch_op.create_unique_constraint(
|
52
|
+
"unique_numeric_version_for_pipeline_run",
|
53
|
+
["model_id", "producer_run_id_if_numeric"],
|
54
|
+
)
|
55
|
+
|
56
|
+
# ### end Alembic commands ###
|
57
|
+
|
58
|
+
|
59
|
+
def downgrade() -> None:
|
60
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
61
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
62
|
+
with op.batch_alter_table("model_version", schema=None) as batch_op:
|
63
|
+
batch_op.drop_constraint(
|
64
|
+
"unique_numeric_version_for_pipeline_run", type_="unique"
|
65
|
+
)
|
66
|
+
batch_op.drop_column("producer_run_id_if_numeric")
|
67
|
+
|
68
|
+
# ### end Alembic commands ###
|
@@ -0,0 +1,36 @@
|
|
1
|
+
"""Remove component spec path [b73bc71f1106].
|
2
|
+
|
3
|
+
Revision ID: b73bc71f1106
|
4
|
+
Revises: ec6307720f92
|
5
|
+
Create Date: 2024-11-29 09:36:33.089945
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sqlalchemy as sa
|
10
|
+
from alembic import op
|
11
|
+
|
12
|
+
# revision identifiers, used by Alembic.
|
13
|
+
revision = "b73bc71f1106"
|
14
|
+
down_revision = "ec6307720f92"
|
15
|
+
branch_labels = None
|
16
|
+
depends_on = None
|
17
|
+
|
18
|
+
|
19
|
+
def upgrade() -> None:
|
20
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
22
|
+
with op.batch_alter_table("stack_component", schema=None) as batch_op:
|
23
|
+
batch_op.drop_column("component_spec_path")
|
24
|
+
|
25
|
+
# ### end Alembic commands ###
|
26
|
+
|
27
|
+
|
28
|
+
def downgrade() -> None:
|
29
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
30
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
31
|
+
with op.batch_alter_table("stack_component", schema=None) as batch_op:
|
32
|
+
batch_op.add_column(
|
33
|
+
sa.Column("component_spec_path", sa.VARCHAR(), nullable=True)
|
34
|
+
)
|
35
|
+
|
36
|
+
# ### end Alembic commands ###
|