zenml-nightly 0.58.2.dev20240623__py3-none-any.whl → 0.61.0.dev20240712__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 +30 -9
- RELEASE_NOTES.md +240 -0
- zenml/VERSION +1 -1
- zenml/actions/base_action.py +177 -174
- zenml/actions/pipeline_run/pipeline_run_action.py +28 -23
- zenml/analytics/enums.py +3 -0
- zenml/artifact_stores/base_artifact_store.py +7 -1
- zenml/artifacts/utils.py +13 -10
- zenml/cli/__init__.py +28 -0
- zenml/cli/artifact.py +1 -2
- zenml/cli/integration.py +9 -8
- zenml/cli/server.py +6 -0
- zenml/cli/service_connectors.py +1 -0
- zenml/cli/stack.py +946 -39
- zenml/cli/stack_components.py +7 -0
- zenml/cli/text_utils.py +35 -1
- zenml/cli/utils.py +127 -10
- zenml/client.py +257 -72
- zenml/config/compiler.py +10 -9
- zenml/config/docker_settings.py +33 -14
- zenml/constants.py +11 -2
- zenml/container_registries/base_container_registry.py +1 -0
- zenml/enums.py +7 -0
- zenml/event_hub/base_event_hub.py +5 -5
- zenml/event_hub/event_hub.py +20 -14
- zenml/event_sources/base_event.py +0 -11
- zenml/event_sources/base_event_source.py +7 -0
- zenml/event_sources/webhooks/base_webhook_event_source.py +1 -4
- zenml/exceptions.py +4 -0
- zenml/hooks/hook_validators.py +2 -3
- zenml/integrations/aws/__init__.py +1 -0
- zenml/integrations/azure/__init__.py +1 -0
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +3 -3
- zenml/integrations/deepchecks/__init__.py +1 -0
- zenml/integrations/discord/__init__.py +1 -0
- zenml/integrations/evidently/__init__.py +1 -0
- zenml/integrations/facets/__init__.py +1 -0
- zenml/integrations/feast/__init__.py +1 -0
- zenml/integrations/gcp/__init__.py +3 -1
- zenml/integrations/gcp/google_credentials_mixin.py +1 -1
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
- zenml/integrations/huggingface/__init__.py +1 -0
- zenml/integrations/integration.py +24 -0
- zenml/integrations/kubeflow/__init__.py +3 -0
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
- zenml/integrations/kubernetes/__init__.py +3 -1
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
- zenml/integrations/langchain/__init__.py +1 -0
- zenml/integrations/mlflow/__init__.py +4 -2
- zenml/integrations/neural_prophet/__init__.py +1 -0
- zenml/integrations/polars/__init__.py +1 -0
- zenml/integrations/prodigy/__init__.py +1 -0
- zenml/integrations/pycaret/__init__.py +6 -0
- zenml/integrations/registry.py +37 -0
- zenml/integrations/s3/artifact_stores/s3_artifact_store.py +93 -9
- zenml/integrations/seldon/__init__.py +1 -0
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
- zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
- zenml/integrations/skypilot_aws/__init__.py +2 -1
- zenml/integrations/skypilot_azure/__init__.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
- zenml/integrations/slack/__init__.py +1 -0
- zenml/integrations/tekton/__init__.py +1 -0
- zenml/integrations/tensorboard/__init__.py +0 -1
- zenml/integrations/tensorflow/__init__.py +18 -6
- zenml/integrations/wandb/__init__.py +1 -0
- zenml/logging/step_logging.py +54 -51
- zenml/models/__init__.py +28 -0
- zenml/models/v2/core/action.py +276 -0
- zenml/models/v2/core/component.py +18 -0
- zenml/models/v2/core/model.py +1 -2
- zenml/models/v2/core/service_connector.py +17 -0
- zenml/models/v2/core/stack.py +31 -0
- zenml/models/v2/core/trigger.py +182 -141
- zenml/models/v2/misc/full_stack.py +97 -0
- zenml/models/v2/misc/stack_deployment.py +86 -0
- zenml/new/pipelines/pipeline.py +14 -4
- zenml/new/pipelines/pipeline_decorator.py +1 -2
- zenml/new/pipelines/run_utils.py +1 -12
- zenml/new/steps/step_decorator.py +2 -3
- zenml/orchestrators/input_utils.py +3 -6
- zenml/pipelines/base_pipeline.py +0 -2
- zenml/pipelines/pipeline_decorator.py +1 -2
- zenml/stack/stack.py +3 -6
- zenml/stack/stack_component.py +4 -0
- zenml/stack_deployments/__init__.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +254 -0
- zenml/stack_deployments/gcp_stack_deployment.py +260 -0
- zenml/stack_deployments/stack_deployment.py +208 -0
- zenml/stack_deployments/utils.py +44 -0
- zenml/steps/base_step.py +1 -2
- zenml/steps/step_decorator.py +1 -2
- zenml/types.py +10 -1
- zenml/utils/function_utils.py +1 -1
- zenml/utils/pagination_utils.py +7 -5
- zenml/utils/pipeline_docker_image_builder.py +117 -73
- zenml/utils/pydantic_utils.py +6 -5
- zenml/zen_server/cloud_utils.py +18 -3
- zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
- zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
- zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
- zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
- zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
- zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
- zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
- zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
- zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
- zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
- zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
- zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
- zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
- zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
- zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
- zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
- zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
- zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
- zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
- zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
- zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
- zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
- zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
- zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
- zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
- zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
- zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
- zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
- zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
- zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
- zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
- zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
- zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
- zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
- zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
- zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
- zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
- zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
- zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
- zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
- zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
- zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
- zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
- zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
- zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
- zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
- zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
- zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
- zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
- zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
- zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
- zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
- zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
- zenml/zen_server/dashboard/index.html +7 -7
- zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
- zenml/zen_server/dashboard_legacy/index.html +1 -1
- zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.chunk.js.map} +1 -1
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
- zenml/zen_server/pipeline_deployment/utils.py +57 -44
- zenml/zen_server/rbac/models.py +1 -0
- zenml/zen_server/rbac/utils.py +22 -1
- zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
- zenml/zen_server/routers/actions_endpoints.py +324 -0
- zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
- zenml/zen_server/routers/triggers_endpoints.py +30 -158
- zenml/zen_server/routers/workspaces_endpoints.py +64 -0
- zenml/zen_server/zen_server_api.py +4 -0
- zenml/zen_stores/migrations/utils.py +1 -1
- zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
- zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
- zenml/zen_stores/rest_zen_store.py +248 -8
- zenml/zen_stores/schemas/__init__.py +2 -0
- zenml/zen_stores/schemas/action_schemas.py +192 -0
- zenml/zen_stores/schemas/stack_schemas.py +10 -0
- zenml/zen_stores/schemas/step_run_schemas.py +27 -11
- zenml/zen_stores/schemas/trigger_schemas.py +43 -50
- zenml/zen_stores/schemas/user_schemas.py +10 -2
- zenml/zen_stores/schemas/workspace_schemas.py +5 -0
- zenml/zen_stores/sql_zen_store.py +540 -36
- zenml/zen_stores/zen_store_interface.py +165 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +33 -11
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +213 -193
- zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
- zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
- zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
- zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
- zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
- zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
- zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
- zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
- zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
- zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
- zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
- zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
- zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
- zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
- zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
- zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
- zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
- zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
- zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
- zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
- zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
- zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
- zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
- zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
- zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
- zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
- zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
- zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
- zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
- zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
- zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
- zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
- zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
@@ -111,12 +111,14 @@ from zenml.enums import (
|
|
111
111
|
SecretsStoreType,
|
112
112
|
SorterOps,
|
113
113
|
StackComponentType,
|
114
|
+
StackDeploymentProvider,
|
114
115
|
StepRunInputArtifactType,
|
115
116
|
StepRunOutputArtifactType,
|
116
117
|
StoreType,
|
117
118
|
TaggableResourceTypes,
|
118
119
|
)
|
119
120
|
from zenml.exceptions import (
|
121
|
+
ActionExistsError,
|
120
122
|
AuthorizationException,
|
121
123
|
BackupSecretsStoreNotConfiguredError,
|
122
124
|
EntityExistsError,
|
@@ -130,6 +132,10 @@ from zenml.exceptions import (
|
|
130
132
|
from zenml.io import fileio
|
131
133
|
from zenml.logger import get_console_handler, get_logger, get_logging_level
|
132
134
|
from zenml.models import (
|
135
|
+
ActionFilter,
|
136
|
+
ActionRequest,
|
137
|
+
ActionResponse,
|
138
|
+
ActionUpdate,
|
133
139
|
APIKeyFilter,
|
134
140
|
APIKeyInternalResponse,
|
135
141
|
APIKeyInternalUpdate,
|
@@ -159,6 +165,7 @@ from zenml.models import (
|
|
159
165
|
ComponentRequest,
|
160
166
|
ComponentResponse,
|
161
167
|
ComponentUpdate,
|
168
|
+
DeployedStack,
|
162
169
|
EventSourceFilter,
|
163
170
|
EventSourceRequest,
|
164
171
|
EventSourceResponse,
|
@@ -167,6 +174,7 @@ from zenml.models import (
|
|
167
174
|
FlavorRequest,
|
168
175
|
FlavorResponse,
|
169
176
|
FlavorUpdate,
|
177
|
+
FullStackRequest,
|
170
178
|
LogsResponse,
|
171
179
|
ModelFilter,
|
172
180
|
ModelRequest,
|
@@ -237,6 +245,8 @@ from zenml.models import (
|
|
237
245
|
ServiceRequest,
|
238
246
|
ServiceResponse,
|
239
247
|
ServiceUpdate,
|
248
|
+
StackDeploymentConfig,
|
249
|
+
StackDeploymentInfo,
|
240
250
|
StackFilter,
|
241
251
|
StackRequest,
|
242
252
|
StackResponse,
|
@@ -289,6 +299,7 @@ from zenml.zen_stores.migrations.alembic import (
|
|
289
299
|
)
|
290
300
|
from zenml.zen_stores.migrations.utils import MigrationUtils
|
291
301
|
from zenml.zen_stores.schemas import (
|
302
|
+
ActionSchema,
|
292
303
|
APIKeySchema,
|
293
304
|
ArtifactSchema,
|
294
305
|
ArtifactVersionSchema,
|
@@ -1542,12 +1553,18 @@ class SqlZenStore(BaseZenStore):
|
|
1542
1553
|
revisions_afterwards = self.alembic.current_revisions()
|
1543
1554
|
|
1544
1555
|
if current_revisions != revisions_afterwards:
|
1545
|
-
|
1546
|
-
current_revisions
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1556
|
+
try:
|
1557
|
+
if current_revisions and version.parse(
|
1558
|
+
current_revisions[0]
|
1559
|
+
) < version.parse("0.57.1"):
|
1560
|
+
# We want to send the missing user enriched events for users
|
1561
|
+
# which were created pre 0.57.1 and only on one upgrade
|
1562
|
+
self._should_send_user_enriched_events = True
|
1563
|
+
except version.InvalidVersion:
|
1564
|
+
# This can happen if the database is not currently
|
1565
|
+
# stamped with an official ZenML version (e.g. in
|
1566
|
+
# development environments).
|
1567
|
+
pass
|
1551
1568
|
|
1552
1569
|
self._sync_flavors()
|
1553
1570
|
|
@@ -1739,6 +1756,205 @@ class SqlZenStore(BaseZenStore):
|
|
1739
1756
|
|
1740
1757
|
self.activate_server(request)
|
1741
1758
|
|
1759
|
+
# -------------------- Actions --------------------
|
1760
|
+
|
1761
|
+
def _fail_if_action_with_name_exists(
|
1762
|
+
self, action_name: str, workspace_id: UUID, session: Session
|
1763
|
+
) -> None:
|
1764
|
+
"""Raise an exception if an action with same name exists.
|
1765
|
+
|
1766
|
+
Args:
|
1767
|
+
action_name: The name of the action.
|
1768
|
+
workspace_id: Workspace ID of the action.
|
1769
|
+
session: DB Session.
|
1770
|
+
|
1771
|
+
Raises:
|
1772
|
+
ActionExistsError: If an action with the given name already exists.
|
1773
|
+
"""
|
1774
|
+
existing_domain_action = session.exec(
|
1775
|
+
select(ActionSchema)
|
1776
|
+
.where(ActionSchema.name == action_name)
|
1777
|
+
.where(ActionSchema.workspace_id == workspace_id)
|
1778
|
+
).first()
|
1779
|
+
if existing_domain_action is not None:
|
1780
|
+
workspace = self._get_workspace_schema(
|
1781
|
+
workspace_name_or_id=workspace_id, session=session
|
1782
|
+
)
|
1783
|
+
raise ActionExistsError(
|
1784
|
+
f"Unable to register action with name "
|
1785
|
+
f"'{action_name}': Found an existing action with "
|
1786
|
+
f"the same name in the active workspace, '{workspace.name}'."
|
1787
|
+
)
|
1788
|
+
|
1789
|
+
def create_action(self, action: ActionRequest) -> ActionResponse:
|
1790
|
+
"""Create an action.
|
1791
|
+
|
1792
|
+
Args:
|
1793
|
+
action: The action to create.
|
1794
|
+
|
1795
|
+
Returns:
|
1796
|
+
The created action.
|
1797
|
+
"""
|
1798
|
+
with Session(self.engine) as session:
|
1799
|
+
self._fail_if_action_with_name_exists(
|
1800
|
+
action_name=action.name,
|
1801
|
+
workspace_id=action.workspace,
|
1802
|
+
session=session,
|
1803
|
+
)
|
1804
|
+
|
1805
|
+
# Verify that the given service account exists
|
1806
|
+
self._get_account_schema(
|
1807
|
+
account_name_or_id=action.service_account_id,
|
1808
|
+
session=session,
|
1809
|
+
service_account=True,
|
1810
|
+
)
|
1811
|
+
|
1812
|
+
new_action = ActionSchema.from_request(action)
|
1813
|
+
session.add(new_action)
|
1814
|
+
session.commit()
|
1815
|
+
session.refresh(new_action)
|
1816
|
+
|
1817
|
+
return new_action.to_model(
|
1818
|
+
include_metadata=True, include_resources=True
|
1819
|
+
)
|
1820
|
+
|
1821
|
+
def _get_action(
|
1822
|
+
self,
|
1823
|
+
action_id: UUID,
|
1824
|
+
session: Session,
|
1825
|
+
) -> ActionSchema:
|
1826
|
+
"""Get an action by ID.
|
1827
|
+
|
1828
|
+
Args:
|
1829
|
+
action_id: The ID of the action to get.
|
1830
|
+
session: The DB session.
|
1831
|
+
|
1832
|
+
Returns:
|
1833
|
+
The action schema.
|
1834
|
+
"""
|
1835
|
+
return self._get_schema_by_name_or_id(
|
1836
|
+
object_name_or_id=action_id,
|
1837
|
+
schema_class=ActionSchema,
|
1838
|
+
schema_name="action",
|
1839
|
+
session=session,
|
1840
|
+
)
|
1841
|
+
|
1842
|
+
def get_action(
|
1843
|
+
self,
|
1844
|
+
action_id: UUID,
|
1845
|
+
hydrate: bool = True,
|
1846
|
+
) -> ActionResponse:
|
1847
|
+
"""Get an action by ID.
|
1848
|
+
|
1849
|
+
Args:
|
1850
|
+
action_id: The ID of the action to get.
|
1851
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1852
|
+
by including metadata fields in the response.
|
1853
|
+
|
1854
|
+
Returns:
|
1855
|
+
The action.
|
1856
|
+
"""
|
1857
|
+
with Session(self.engine) as session:
|
1858
|
+
action = self._get_action(action_id=action_id, session=session)
|
1859
|
+
|
1860
|
+
return action.to_model(
|
1861
|
+
include_metadata=hydrate, include_resources=hydrate
|
1862
|
+
)
|
1863
|
+
|
1864
|
+
def list_actions(
|
1865
|
+
self,
|
1866
|
+
action_filter_model: ActionFilter,
|
1867
|
+
hydrate: bool = False,
|
1868
|
+
) -> Page[ActionResponse]:
|
1869
|
+
"""List all actions matching the given filter criteria.
|
1870
|
+
|
1871
|
+
Args:
|
1872
|
+
action_filter_model: All filter parameters including pagination
|
1873
|
+
params.
|
1874
|
+
hydrate: Flag deciding whether to hydrate the output model(s)
|
1875
|
+
by including metadata fields in the response.
|
1876
|
+
|
1877
|
+
Returns:
|
1878
|
+
A page of actions matching the filter criteria.
|
1879
|
+
"""
|
1880
|
+
with Session(self.engine) as session:
|
1881
|
+
query = select(ActionSchema)
|
1882
|
+
return self.filter_and_paginate(
|
1883
|
+
session=session,
|
1884
|
+
query=query,
|
1885
|
+
table=ActionSchema,
|
1886
|
+
filter_model=action_filter_model,
|
1887
|
+
hydrate=hydrate,
|
1888
|
+
)
|
1889
|
+
|
1890
|
+
def update_action(
|
1891
|
+
self,
|
1892
|
+
action_id: UUID,
|
1893
|
+
action_update: ActionUpdate,
|
1894
|
+
) -> ActionResponse:
|
1895
|
+
"""Update an existing action.
|
1896
|
+
|
1897
|
+
Args:
|
1898
|
+
action_id: The ID of the action to update.
|
1899
|
+
action_update: The update to be applied to the action.
|
1900
|
+
|
1901
|
+
Returns:
|
1902
|
+
The updated action.
|
1903
|
+
"""
|
1904
|
+
with Session(self.engine) as session:
|
1905
|
+
action = self._get_action(session=session, action_id=action_id)
|
1906
|
+
|
1907
|
+
if action_update.service_account_id:
|
1908
|
+
# Verify that the given service account exists
|
1909
|
+
self._get_account_schema(
|
1910
|
+
account_name_or_id=action_update.service_account_id,
|
1911
|
+
session=session,
|
1912
|
+
service_account=True,
|
1913
|
+
)
|
1914
|
+
|
1915
|
+
# In case of a renaming update, make sure no action already exists
|
1916
|
+
# with that name
|
1917
|
+
if action_update.name:
|
1918
|
+
if action.name != action_update.name:
|
1919
|
+
self._fail_if_action_with_name_exists(
|
1920
|
+
action_name=action_update.name,
|
1921
|
+
workspace_id=action.workspace.id,
|
1922
|
+
session=session,
|
1923
|
+
)
|
1924
|
+
|
1925
|
+
action.update(action_update=action_update)
|
1926
|
+
session.add(action)
|
1927
|
+
session.commit()
|
1928
|
+
|
1929
|
+
session.refresh(action)
|
1930
|
+
|
1931
|
+
return action.to_model(
|
1932
|
+
include_metadata=True, include_resources=True
|
1933
|
+
)
|
1934
|
+
|
1935
|
+
def delete_action(self, action_id: UUID) -> None:
|
1936
|
+
"""Delete an action.
|
1937
|
+
|
1938
|
+
Args:
|
1939
|
+
action_id: The ID of the action to delete.
|
1940
|
+
|
1941
|
+
Raises:
|
1942
|
+
IllegalOperationError: If the action can't be deleted
|
1943
|
+
because it's used by triggers.
|
1944
|
+
"""
|
1945
|
+
with Session(self.engine) as session:
|
1946
|
+
action = self._get_action(action_id=action_id, session=session)
|
1947
|
+
|
1948
|
+
# Prevent deletion of action if it is used by a trigger
|
1949
|
+
if action.triggers:
|
1950
|
+
raise IllegalOperationError(
|
1951
|
+
f"Unable to delete action with ID `{action_id}` "
|
1952
|
+
f"as it is used by {len(action.triggers)} triggers."
|
1953
|
+
)
|
1954
|
+
|
1955
|
+
session.delete(action)
|
1956
|
+
session.commit()
|
1957
|
+
|
1742
1958
|
# ------------------------- API Keys -------------------------
|
1743
1959
|
|
1744
1960
|
def _get_api_key(
|
@@ -4183,11 +4399,9 @@ class SqlZenStore(BaseZenStore):
|
|
4183
4399
|
event_source: The event_source to create.
|
4184
4400
|
session: The Session
|
4185
4401
|
|
4186
|
-
Returns:
|
4187
|
-
None
|
4188
|
-
|
4189
4402
|
Raises:
|
4190
|
-
EventSourceExistsError:
|
4403
|
+
EventSourceExistsError: If an event source with the given name
|
4404
|
+
already exists.
|
4191
4405
|
"""
|
4192
4406
|
existing_domain_event_source = session.exec(
|
4193
4407
|
select(EventSourceSchema)
|
@@ -4203,7 +4417,6 @@ class SqlZenStore(BaseZenStore):
|
|
4203
4417
|
f"'{event_source.name}': Found an existing event source with "
|
4204
4418
|
f"the same name in the active workspace, '{workspace.name}'."
|
4205
4419
|
)
|
4206
|
-
return None
|
4207
4420
|
|
4208
4421
|
def create_event_source(
|
4209
4422
|
self, event_source: EventSourceRequest
|
@@ -4269,7 +4482,7 @@ class SqlZenStore(BaseZenStore):
|
|
4269
4482
|
with Session(self.engine) as session:
|
4270
4483
|
return self._get_event_source(
|
4271
4484
|
event_source_id=event_source_id, session=session
|
4272
|
-
).to_model(include_metadata=hydrate, include_resources=
|
4485
|
+
).to_model(include_metadata=hydrate, include_resources=hydrate)
|
4273
4486
|
|
4274
4487
|
def list_event_sources(
|
4275
4488
|
self,
|
@@ -4333,6 +4546,8 @@ class SqlZenStore(BaseZenStore):
|
|
4333
4546
|
|
4334
4547
|
Raises:
|
4335
4548
|
KeyError: if the event_source doesn't exist.
|
4549
|
+
IllegalOperationError: If the event source can't be deleted
|
4550
|
+
because it's used by triggers.
|
4336
4551
|
"""
|
4337
4552
|
with Session(self.engine) as session:
|
4338
4553
|
event_source = self._get_event_source(
|
@@ -4343,12 +4558,17 @@ class SqlZenStore(BaseZenStore):
|
|
4343
4558
|
f"Unable to delete event_source with ID `{event_source_id}`: "
|
4344
4559
|
f"No event_source with this ID found."
|
4345
4560
|
)
|
4561
|
+
|
4562
|
+
# Prevent deletion of event source if it is used by a trigger
|
4563
|
+
if event_source.triggers:
|
4564
|
+
raise IllegalOperationError(
|
4565
|
+
f"Unable to delete event_source with ID `{event_source_id}`"
|
4566
|
+
f" as it is used by {len(event_source.triggers)} triggers."
|
4567
|
+
)
|
4568
|
+
|
4346
4569
|
session.delete(event_source)
|
4347
4570
|
session.commit()
|
4348
4571
|
|
4349
|
-
# TODO: catch and throw proper error if it can't be deleted due to
|
4350
|
-
# not-null constraints on triggers
|
4351
|
-
|
4352
4572
|
# ----------------------------- Pipeline runs -----------------------------
|
4353
4573
|
|
4354
4574
|
def create_run(
|
@@ -6702,6 +6922,9 @@ class SqlZenStore(BaseZenStore):
|
|
6702
6922
|
name=stack.name,
|
6703
6923
|
description=stack.description,
|
6704
6924
|
components=defined_components,
|
6925
|
+
labels=base64.b64encode(
|
6926
|
+
json.dumps(stack.labels).encode("utf-8")
|
6927
|
+
),
|
6705
6928
|
)
|
6706
6929
|
|
6707
6930
|
session.add(new_stack_schema)
|
@@ -6710,6 +6933,223 @@ class SqlZenStore(BaseZenStore):
|
|
6710
6933
|
|
6711
6934
|
return new_stack_schema.to_model(include_metadata=True)
|
6712
6935
|
|
6936
|
+
def create_full_stack(self, full_stack: FullStackRequest) -> StackResponse:
|
6937
|
+
"""Register a full stack.
|
6938
|
+
|
6939
|
+
Args:
|
6940
|
+
full_stack: The full stack configuration.
|
6941
|
+
|
6942
|
+
Returns:
|
6943
|
+
The registered stack.
|
6944
|
+
|
6945
|
+
Raises:
|
6946
|
+
ValueError: If the full stack creation fails, due to the corrupted
|
6947
|
+
input.
|
6948
|
+
RuntimeError: If the full stack creation fails, due to unforeseen
|
6949
|
+
errors.
|
6950
|
+
"""
|
6951
|
+
# For clean-up purposes, each created entity is tracked here
|
6952
|
+
service_connectors_created_ids: List[UUID] = []
|
6953
|
+
components_created_ids: List[UUID] = []
|
6954
|
+
|
6955
|
+
try:
|
6956
|
+
# Validate the name of the new stack
|
6957
|
+
validate_name(full_stack)
|
6958
|
+
|
6959
|
+
if full_stack.labels is None:
|
6960
|
+
full_stack.labels = {}
|
6961
|
+
|
6962
|
+
full_stack.labels.update({"zenml:full_stack": True})
|
6963
|
+
|
6964
|
+
# Service Connectors
|
6965
|
+
service_connectors: List[ServiceConnectorResponse] = []
|
6966
|
+
|
6967
|
+
for connector_id_or_info in full_stack.service_connectors:
|
6968
|
+
# Fetch an existing service connector
|
6969
|
+
if isinstance(connector_id_or_info, UUID):
|
6970
|
+
service_connectors.append(
|
6971
|
+
self.get_service_connector(connector_id_or_info)
|
6972
|
+
)
|
6973
|
+
# Create a new service connector
|
6974
|
+
else:
|
6975
|
+
connector_name = full_stack.name
|
6976
|
+
while True:
|
6977
|
+
try:
|
6978
|
+
service_connector_request = ServiceConnectorRequest(
|
6979
|
+
name=connector_name,
|
6980
|
+
connector_type=connector_id_or_info.type,
|
6981
|
+
auth_method=connector_id_or_info.auth_method,
|
6982
|
+
configuration=connector_id_or_info.configuration,
|
6983
|
+
user=full_stack.user,
|
6984
|
+
workspace=full_stack.workspace,
|
6985
|
+
labels={
|
6986
|
+
k: str(v)
|
6987
|
+
for k, v in full_stack.labels.items()
|
6988
|
+
},
|
6989
|
+
)
|
6990
|
+
service_connector_response = (
|
6991
|
+
self.create_service_connector(
|
6992
|
+
service_connector=service_connector_request
|
6993
|
+
)
|
6994
|
+
)
|
6995
|
+
service_connectors.append(
|
6996
|
+
service_connector_response
|
6997
|
+
)
|
6998
|
+
service_connectors_created_ids.append(
|
6999
|
+
service_connector_response.id
|
7000
|
+
)
|
7001
|
+
break
|
7002
|
+
except EntityExistsError:
|
7003
|
+
connector_name = (
|
7004
|
+
f"{full_stack.name}-{random_str(4)}".lower()
|
7005
|
+
)
|
7006
|
+
continue
|
7007
|
+
|
7008
|
+
# Stack Components
|
7009
|
+
components_mapping: Dict[StackComponentType, List[UUID]] = {}
|
7010
|
+
for (
|
7011
|
+
component_type,
|
7012
|
+
component_info,
|
7013
|
+
) in full_stack.components.items():
|
7014
|
+
# Fetch an existing component
|
7015
|
+
if isinstance(component_info, UUID):
|
7016
|
+
component = self.get_stack_component(
|
7017
|
+
component_id=component_info
|
7018
|
+
)
|
7019
|
+
# Create a new component
|
7020
|
+
else:
|
7021
|
+
flavor_list = self.list_flavors(
|
7022
|
+
flavor_filter_model=FlavorFilter(
|
7023
|
+
name=component_info.flavor,
|
7024
|
+
type=component_type,
|
7025
|
+
)
|
7026
|
+
)
|
7027
|
+
if not len(flavor_list):
|
7028
|
+
raise ValueError(
|
7029
|
+
f"Flavor '{component_info.flavor}' not found "
|
7030
|
+
f"for component type '{component_type}'."
|
7031
|
+
)
|
7032
|
+
|
7033
|
+
flavor_model = flavor_list[0]
|
7034
|
+
|
7035
|
+
component_name = full_stack.name
|
7036
|
+
while True:
|
7037
|
+
try:
|
7038
|
+
component_request = ComponentRequest(
|
7039
|
+
name=component_name,
|
7040
|
+
type=component_type,
|
7041
|
+
flavor=component_info.flavor,
|
7042
|
+
configuration=component_info.configuration,
|
7043
|
+
user=full_stack.user,
|
7044
|
+
workspace=full_stack.workspace,
|
7045
|
+
labels=full_stack.labels,
|
7046
|
+
)
|
7047
|
+
component = self.create_stack_component(
|
7048
|
+
component=component_request
|
7049
|
+
)
|
7050
|
+
components_created_ids.append(component.id)
|
7051
|
+
break
|
7052
|
+
except EntityExistsError:
|
7053
|
+
component_name = (
|
7054
|
+
f"{full_stack.name}-{random_str(4)}".lower()
|
7055
|
+
)
|
7056
|
+
continue
|
7057
|
+
|
7058
|
+
if component_info.service_connector_index is not None:
|
7059
|
+
service_connector = service_connectors[
|
7060
|
+
component_info.service_connector_index
|
7061
|
+
]
|
7062
|
+
|
7063
|
+
requirements = flavor_model.connector_requirements
|
7064
|
+
|
7065
|
+
if not requirements:
|
7066
|
+
raise ValueError(
|
7067
|
+
f"The '{flavor_model.name}' implementation "
|
7068
|
+
"does not support using a service connector to "
|
7069
|
+
"connect to resources."
|
7070
|
+
)
|
7071
|
+
|
7072
|
+
if component_info.service_connector_resource_id:
|
7073
|
+
resource_id = (
|
7074
|
+
component_info.service_connector_resource_id
|
7075
|
+
)
|
7076
|
+
else:
|
7077
|
+
resource_id = None
|
7078
|
+
resource_type = requirements.resource_type
|
7079
|
+
if requirements.resource_id_attr is not None:
|
7080
|
+
resource_id = component_info.configuration.get(
|
7081
|
+
requirements.resource_id_attr
|
7082
|
+
)
|
7083
|
+
|
7084
|
+
satisfied, msg = requirements.is_satisfied_by(
|
7085
|
+
connector=service_connector,
|
7086
|
+
component=component,
|
7087
|
+
)
|
7088
|
+
|
7089
|
+
if not satisfied:
|
7090
|
+
raise ValueError(
|
7091
|
+
"Please pick a connector that is "
|
7092
|
+
"compatible with the component flavor and "
|
7093
|
+
"try again.."
|
7094
|
+
)
|
7095
|
+
|
7096
|
+
if not resource_id:
|
7097
|
+
if service_connector.resource_id:
|
7098
|
+
resource_id = service_connector.resource_id
|
7099
|
+
elif service_connector.supports_instances:
|
7100
|
+
raise ValueError(
|
7101
|
+
f"Multiple {resource_type} resources "
|
7102
|
+
"are available for the selected "
|
7103
|
+
"connector. Please use a `resource_id` "
|
7104
|
+
"to configure a "
|
7105
|
+
f"{resource_type} resource."
|
7106
|
+
)
|
7107
|
+
|
7108
|
+
component_update = ComponentUpdate(
|
7109
|
+
connector=service_connector.id,
|
7110
|
+
connector_resource_id=resource_id,
|
7111
|
+
)
|
7112
|
+
self.update_stack_component(
|
7113
|
+
component_id=component.id,
|
7114
|
+
component_update=component_update,
|
7115
|
+
)
|
7116
|
+
|
7117
|
+
components_mapping[component_type] = [
|
7118
|
+
component.id,
|
7119
|
+
]
|
7120
|
+
|
7121
|
+
# Stack
|
7122
|
+
stack_name = full_stack.name
|
7123
|
+
while True:
|
7124
|
+
try:
|
7125
|
+
stack_request = StackRequest(
|
7126
|
+
user=full_stack.user,
|
7127
|
+
workspace=full_stack.workspace,
|
7128
|
+
name=stack_name,
|
7129
|
+
description=full_stack.description,
|
7130
|
+
components=components_mapping,
|
7131
|
+
labels=full_stack.labels,
|
7132
|
+
)
|
7133
|
+
stack_response = self.create_stack(stack_request)
|
7134
|
+
|
7135
|
+
break
|
7136
|
+
except EntityExistsError:
|
7137
|
+
stack_name = f"{full_stack.name}-{random_str(4)}".lower()
|
7138
|
+
|
7139
|
+
return stack_response
|
7140
|
+
|
7141
|
+
except Exception as e:
|
7142
|
+
for component_id in components_created_ids:
|
7143
|
+
self.delete_stack_component(component_id=component_id)
|
7144
|
+
for service_connector_id in service_connectors_created_ids:
|
7145
|
+
self.delete_service_connector(
|
7146
|
+
service_connector_id=service_connector_id
|
7147
|
+
)
|
7148
|
+
raise RuntimeError(
|
7149
|
+
f"Full Stack creation has failed {e}. Cleaning up the "
|
7150
|
+
f"created entities."
|
7151
|
+
) from e
|
7152
|
+
|
6713
7153
|
def get_stack(self, stack_id: UUID, hydrate: bool = True) -> StackResponse:
|
6714
7154
|
"""Get a stack by its unique ID.
|
6715
7155
|
|
@@ -6986,6 +7426,69 @@ class SqlZenStore(BaseZenStore):
|
|
6986
7426
|
workspace_id=workspace.id,
|
6987
7427
|
)
|
6988
7428
|
|
7429
|
+
# ---------------- Stack deployments-----------------
|
7430
|
+
|
7431
|
+
def get_stack_deployment_info(
|
7432
|
+
self,
|
7433
|
+
provider: StackDeploymentProvider,
|
7434
|
+
) -> StackDeploymentInfo:
|
7435
|
+
"""Get information about a stack deployment provider.
|
7436
|
+
|
7437
|
+
Args:
|
7438
|
+
provider: The stack deployment provider.
|
7439
|
+
|
7440
|
+
Raises:
|
7441
|
+
NotImplementedError: Stack deployments are not supported by the
|
7442
|
+
local ZenML deployment.
|
7443
|
+
"""
|
7444
|
+
raise NotImplementedError(
|
7445
|
+
"Stack deployments are not supported by local ZenML deployments."
|
7446
|
+
)
|
7447
|
+
|
7448
|
+
def get_stack_deployment_config(
|
7449
|
+
self,
|
7450
|
+
provider: StackDeploymentProvider,
|
7451
|
+
stack_name: str,
|
7452
|
+
location: Optional[str] = None,
|
7453
|
+
) -> StackDeploymentConfig:
|
7454
|
+
"""Return the cloud provider console URL and configuration needed to deploy the ZenML stack.
|
7455
|
+
|
7456
|
+
Args:
|
7457
|
+
provider: The stack deployment provider.
|
7458
|
+
stack_name: The name of the stack.
|
7459
|
+
location: The location where the stack should be deployed.
|
7460
|
+
|
7461
|
+
Raises:
|
7462
|
+
NotImplementedError: Stack deployments are not supported by the
|
7463
|
+
local ZenML deployment.
|
7464
|
+
"""
|
7465
|
+
raise NotImplementedError(
|
7466
|
+
"Stack deployments are not supported by local ZenML deployments."
|
7467
|
+
)
|
7468
|
+
|
7469
|
+
def get_stack_deployment_stack(
|
7470
|
+
self,
|
7471
|
+
provider: StackDeploymentProvider,
|
7472
|
+
stack_name: str,
|
7473
|
+
location: Optional[str] = None,
|
7474
|
+
date_start: Optional[datetime] = None,
|
7475
|
+
) -> Optional[DeployedStack]:
|
7476
|
+
"""Return a matching ZenML stack that was deployed and registered.
|
7477
|
+
|
7478
|
+
Args:
|
7479
|
+
provider: The stack deployment provider.
|
7480
|
+
stack_name: The name of the stack.
|
7481
|
+
location: The location where the stack should be deployed.
|
7482
|
+
date_start: The date when the deployment started.
|
7483
|
+
|
7484
|
+
Raises:
|
7485
|
+
NotImplementedError: Stack deployments are not supported by the
|
7486
|
+
local ZenML deployment.
|
7487
|
+
"""
|
7488
|
+
raise NotImplementedError(
|
7489
|
+
"Stack deployments are not supported by local ZenML deployments."
|
7490
|
+
)
|
7491
|
+
|
6989
7492
|
# ----------------------------- Step runs -----------------------------
|
6990
7493
|
|
6991
7494
|
def create_run_step(self, step_run: StepRunRequest) -> StepRunResponse:
|
@@ -7478,19 +7981,19 @@ class SqlZenStore(BaseZenStore):
|
|
7478
7981
|
The newly created trigger.
|
7479
7982
|
"""
|
7480
7983
|
with Session(self.engine) as session:
|
7481
|
-
# Verify that the given
|
7482
|
-
self.
|
7483
|
-
event_source_id=trigger.event_source_id, session=session
|
7484
|
-
)
|
7984
|
+
# Verify that the given action exists
|
7985
|
+
self._get_action(action_id=trigger.action_id, session=session)
|
7485
7986
|
|
7486
|
-
|
7487
|
-
|
7488
|
-
|
7489
|
-
|
7490
|
-
|
7491
|
-
|
7987
|
+
if trigger.event_source_id:
|
7988
|
+
# Verify that the given event_source exists
|
7989
|
+
self._get_event_source(
|
7990
|
+
event_source_id=trigger.event_source_id, session=session
|
7991
|
+
)
|
7992
|
+
|
7993
|
+
# Verify that the action exists
|
7994
|
+
self._get_action(action_id=trigger.action_id, session=session)
|
7492
7995
|
|
7493
|
-
# Verify that the trigger
|
7996
|
+
# Verify that the trigger name is unique
|
7494
7997
|
self._fail_if_trigger_with_name_exists(
|
7495
7998
|
trigger_name=trigger.name,
|
7496
7999
|
workspace_id=trigger.workspace,
|
@@ -7520,7 +8023,7 @@ class SqlZenStore(BaseZenStore):
|
|
7520
8023
|
The trigger with the given ID.
|
7521
8024
|
|
7522
8025
|
Raises:
|
7523
|
-
KeyError:
|
8026
|
+
KeyError: If the trigger doesn't exist.
|
7524
8027
|
"""
|
7525
8028
|
with Session(self.engine) as session:
|
7526
8029
|
trigger = session.exec(
|
@@ -7573,7 +8076,8 @@ class SqlZenStore(BaseZenStore):
|
|
7573
8076
|
The updated trigger.
|
7574
8077
|
|
7575
8078
|
Raises:
|
7576
|
-
KeyError:
|
8079
|
+
KeyError: If the trigger doesn't exist.
|
8080
|
+
ValueError: If both a schedule and an event source are provided.
|
7577
8081
|
"""
|
7578
8082
|
with Session(self.engine) as session:
|
7579
8083
|
# Check if trigger with the domain key (name, workspace, owner)
|
@@ -7583,16 +8087,16 @@ class SqlZenStore(BaseZenStore):
|
|
7583
8087
|
).first()
|
7584
8088
|
if existing_trigger is None:
|
7585
8089
|
raise KeyError(
|
7586
|
-
f"Unable to update trigger with id '{trigger_id}':
|
7587
|
-
f"existing trigger with this id."
|
8090
|
+
f"Unable to update trigger with id '{trigger_id}': No "
|
8091
|
+
f"existing trigger with this id exists."
|
7588
8092
|
)
|
7589
8093
|
|
7590
|
-
|
7591
|
-
|
7592
|
-
|
7593
|
-
|
7594
|
-
|
7595
|
-
|
8094
|
+
# Verify that either a schedule or an event source is provided, not
|
8095
|
+
# both
|
8096
|
+
if existing_trigger.event_source and trigger_update.schedule:
|
8097
|
+
raise ValueError(
|
8098
|
+
"Unable to update trigger: A trigger cannot have both a "
|
8099
|
+
"schedule and an event source."
|
7596
8100
|
)
|
7597
8101
|
|
7598
8102
|
# In case of a renaming update, make sure no trigger already exists
|