zenml-nightly 0.68.1.dev20241111__py3-none-any.whl → 0.70.0.dev20241114__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 +1 -1
- RELEASE_NOTES.md +77 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +2 -0
- zenml/artifacts/utils.py +5 -1
- zenml/cli/base.py +1 -1
- zenml/client.py +9 -2
- zenml/config/server_config.py +17 -1
- zenml/constants.py +1 -7
- zenml/enums.py +8 -0
- zenml/exceptions.py +4 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +1 -14
- zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +29 -9
- zenml/model/model.py +16 -62
- zenml/model/utils.py +5 -0
- zenml/models/v2/base/filter.py +121 -8
- zenml/models/v2/core/artifact_version.py +23 -0
- zenml/models/v2/core/model_version.py +23 -0
- zenml/models/v2/core/pipeline_run.py +22 -1
- zenml/models/v2/core/step_run.py +22 -0
- zenml/orchestrators/base_orchestrator.py +12 -1
- zenml/orchestrators/step_launcher.py +2 -1
- zenml/orchestrators/utils.py +45 -26
- zenml/stack_deployments/aws_stack_deployment.py +23 -6
- zenml/stack_deployments/azure_stack_deployment.py +28 -5
- zenml/stack_deployments/gcp_stack_deployment.py +25 -8
- zenml/stack_deployments/stack_deployment.py +3 -5
- zenml/steps/utils.py +5 -0
- zenml/utils/metadata_utils.py +335 -0
- zenml/zen_server/auth.py +221 -3
- zenml/zen_server/cache.py +208 -0
- zenml/zen_server/dashboard/assets/{404-DT4QRUqN.js → 404-NVXKFp-x.js} +1 -1
- zenml/zen_server/dashboard/assets/{@radix-DP6vWzyx.js → @radix-DeK6qiuw.js} +1 -1
- zenml/zen_server/dashboard/assets/{@react-router-BMhZulnd.js → @react-router-B3Z5rLr2.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-8U9qNlMR.js → @reactflow-CK0KJUen.js} +2 -2
- zenml/zen_server/dashboard/assets/{@tanstack-BUCbhJyH.js → @tanstack-DT5WLu9C.js} +1 -1
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-DezXKmDf.js +1 -0
- zenml/zen_server/dashboard/assets/{CodeSnippet-CqybNv0k.js → CodeSnippet-JzR8CEtw.js} +2 -2
- zenml/zen_server/dashboard/assets/{CollapsibleCard-0r_8G2Lj.js → CollapsibleCard-DQW_ktMO.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-BDjgBQKi.js → Commands-DL2kwkRd.js} +1 -1
- zenml/zen_server/dashboard/assets/ComponentBadge-D_g62Wv8.js +1 -0
- zenml/zen_server/dashboard/assets/{CopyButton-C745BrKi.js → CopyButton-LNcWaa14.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-PpAq0CeZ.js → CsvVizualization-DknpE5ej.js} +5 -5
- zenml/zen_server/dashboard/assets/{DialogItem-DcVCZEew.js → DialogItem-Bxf8FuAT.js} +1 -1
- zenml/zen_server/dashboard/assets/{DisplayDate-BeXgUG_C.js → DisplayDate-CDMUcQHS.js} +1 -1
- zenml/zen_server/dashboard/assets/{EmptyState-DeK7H4pr.js → EmptyState-BzdlCwp3.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-BMlzibXj.js → Error-DYflYyps.js} +1 -1
- zenml/zen_server/dashboard/assets/ExecutionStatus-C7zyIQKZ.js +1 -0
- zenml/zen_server/dashboard/assets/{Helpbox-BLf40fLV.js → Helpbox-oYSGpLqd.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-BwisKifi.js → Infobox-Cx4xGoXR.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-jEgodSgX.js → InlineAvatar-DiGOWNKF.js} +1 -1
- zenml/zen_server/dashboard/assets/{Lock-3lLt1ih0.js → Lock-CYYy18Mm.js} +1 -1
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-8O9kTr-2.js → MarkdownVisualization-ylXaAxev.js} +1 -1
- zenml/zen_server/dashboard/assets/NestedCollapsible-DYbgyKxK.js +1 -0
- zenml/zen_server/dashboard/assets/{NumberBox-T9eELfLZ.js → NumberBox-Dtp3J6g5.js} +1 -1
- zenml/zen_server/dashboard/assets/Partials-03iZf8-N.js +1 -0
- zenml/zen_server/dashboard/assets/{PasswordChecker-CW0kqY0W.js → PasswordChecker-B0nadgh6.js} +1 -1
- zenml/zen_server/dashboard/assets/ProBadge-D_EB8HNo.js +1 -0
- zenml/zen_server/dashboard/assets/ProCta-DqNS4v3x.js +1 -0
- zenml/zen_server/dashboard/assets/ProviderIcon-Bki2aw8w.js +1 -0
- zenml/zen_server/dashboard/assets/{ProviderRadio-BROY1700.js → ProviderRadio-8f43sPD4.js} +1 -1
- zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +1 -0
- zenml/zen_server/dashboard/assets/RunsBody-07YEO7qI.js +1 -0
- zenml/zen_server/dashboard/assets/SearchField-lp1KgU4e.js +1 -0
- zenml/zen_server/dashboard/assets/{SecretTooltip-C_qByGWB.js → SecretTooltip-CgnbyeOx.js} +1 -1
- zenml/zen_server/dashboard/assets/{SetPassword-7pRB00El.js → SetPassword-CpP418A2.js} +1 -1
- zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +1 -0
- zenml/zen_server/dashboard/assets/Tabs-BktHkCJJ.js +1 -0
- zenml/zen_server/dashboard/assets/Tick-BlMoIlJT.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DckMEkFf.js → UpdatePasswordSchemas-Sc0A0pP-.js} +1 -1
- zenml/zen_server/dashboard/assets/{UsageReason-DVceN14P.js → UsageReason-YYduL4fj.js} +1 -1
- zenml/zen_server/dashboard/assets/{WizardFooter-CW0Cvd70.js → WizardFooter-dgmizSJC.js} +1 -1
- zenml/zen_server/dashboard/assets/all-pipeline-runs-query-D-c2G6lV.js +1 -0
- zenml/zen_server/dashboard/assets/check-DloQpStc.js +1 -0
- zenml/zen_server/dashboard/assets/{check-circle-Dwxliy1Z.js → check-circle-jNbX5-sR.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-down-8wLBS5pQ.js → chevron-down-6JyMkfjR.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-DoD8iXWM.js → chevron-right-double-D7ojK9Co.js} +1 -1
- zenml/zen_server/dashboard/assets/{code-browser-CZUQs3Wa.js → code-browser-CUFUIHfp.js} +1 -1
- zenml/zen_server/dashboard/assets/{copy-CaSMXwiU.js → copy-C8XQA2Ug.js} +1 -1
- zenml/zen_server/dashboard/assets/create-stack-DM_JPgef.js +1 -0
- zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +1 -0
- zenml/zen_server/dashboard/assets/{docker-BFNgg-z3.js → docker-BdA9vrnW.js} +1 -1
- zenml/zen_server/dashboard/assets/{dots-horizontal-DK5Duzx4.js → dots-horizontal-otGBOSDJ.js} +1 -1
- zenml/zen_server/dashboard/assets/{form-schemas-1AyOCx90.js → form-schemas-K6FYKjwa.js} +1 -1
- zenml/zen_server/dashboard/assets/{gcp-7M2Yf3ZK.js → gcp-CFtm4BA7.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-Dam461dC.js → help-Cc9bBIJH.js} +1 -1
- zenml/zen_server/dashboard/assets/index-B1mVPYxf.js +1 -0
- zenml/zen_server/dashboard/assets/index-BAkC7FXi.js +1 -0
- zenml/zen_server/dashboard/assets/{index-QQb7wQEC.js → index-CCOPpudF.js} +8 -8
- zenml/zen_server/dashboard/assets/index-CEV4Cvaf.js +1 -0
- zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +1 -0
- zenml/zen_server/dashboard/assets/{index-BVJ8n2-j.js → index-Uu49AX48.js} +1 -1
- zenml/zen_server/dashboard/assets/{index.esm-cuVep_NJ.js → index.esm-Dy6Z9Ung.js} +1 -1
- zenml/zen_server/dashboard/assets/{kubernetes--g7r02Zu.js → kubernetes-B2wmAJ1d.js} +1 -1
- zenml/zen_server/dashboard/assets/{layout-DCSYN7-C.js → layout-BtHBmE4w.js} +1 -1
- zenml/zen_server/dashboard/assets/{link-external-CBEk6kEG.js → link-external-b9AXw_sW.js} +1 -1
- zenml/zen_server/dashboard/assets/{login-mutation-DTcAFP1l.js → login-mutation-hf-lK87O.js} +1 -1
- zenml/zen_server/dashboard/assets/{logs-D5bdJGur.js → logs-WMSM52RF.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-Cc-JkRH2.js → not-found-BGirLjU-.js} +1 -1
- zenml/zen_server/dashboard/assets/{package-Cs35Szwh.js → package-C6uypY4h.js} +1 -1
- zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DH_Z7iW1.js → page-6m6yHHlE.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BDigxVpo.js +1 -0
- zenml/zen_server/dashboard/assets/page-BR68V0V1.js +1 -0
- zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BQQKaabe.js → page-BU7huvKw.js} +3 -3
- zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +1 -0
- zenml/zen_server/dashboard/assets/page-C00YAkaB.js +1 -0
- zenml/zen_server/dashboard/assets/{page-N4qoPHKb.js → page-CD-DcWoy.js} +1 -1
- zenml/zen_server/dashboard/assets/page-COXXJj1k.js +1 -0
- zenml/zen_server/dashboard/assets/page-CbpvrsDL.js +1 -0
- zenml/zen_server/dashboard/assets/page-CdMWnQak.js +1 -0
- zenml/zen_server/dashboard/assets/{page-ClUVkl-O.js → page-CjGdWY13.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CwxrFarU.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DLixvR-7.js → page-D01JhjQB.js} +1 -1
- zenml/zen_server/dashboard/assets/page-D6uU2ax4.js +1 -0
- zenml/zen_server/dashboard/assets/page-D7S3aCbF.js +1 -0
- zenml/zen_server/dashboard/assets/{page-9yplj5JT.js → page-DLC-bNBP.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DXSTpqRD.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DzpVUZ8f.js → page-DakHVWXF.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DIOXwhiD.js → page-Df-Fw0aq.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-B-y2XKIc.js → page-DfbXf_8s.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DjRJCGb3.js +1 -0
- zenml/zen_server/dashboard/assets/{page-C0N5q3l7.js → page-Djikxq_S.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +3 -0
- zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +1 -0
- zenml/zen_server/dashboard/assets/page-Vcxara9U.js +1 -0
- zenml/zen_server/dashboard/assets/page-Xynx4btY.js +14 -0
- zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +1 -0
- zenml/zen_server/dashboard/assets/page-yYC9OI-E.js +1 -0
- zenml/zen_server/dashboard/assets/{persist-DNb5cdrU.js → persist-Coz7ZWvz.js} +1 -1
- zenml/zen_server/dashboard/assets/{persist-CP0JmYZ4.js → persist-GjC8PZoC.js} +1 -1
- zenml/zen_server/dashboard/assets/{plus-C9IxgN2M.js → plus-tf1V2hTJ.js} +1 -1
- zenml/zen_server/dashboard/assets/{refresh-BVu22P_C.js → refresh-BjOeWlEq.js} +1 -1
- zenml/zen_server/dashboard/assets/{rocket-CONEmRmB.js → rocket-DjT2cDvG.js} +1 -1
- zenml/zen_server/dashboard/assets/sharedSchema-CQb14VSr.js +14 -0
- zenml/zen_server/dashboard/assets/stack-detail-query-OPEW-cDJ.js +1 -0
- zenml/zen_server/dashboard/assets/{tick-circle-CM1ZScbQ.js → tick-circle-BEX_Tp4v.js} +1 -1
- zenml/zen_server/dashboard/assets/{trash-DkJHMOg7.js → trash-arLUMWMS.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-DsU8cNVl.js → update-server-settings-mutation-LwuQfHYn.js} +1 -1
- zenml/zen_server/dashboard/assets/upgrade-form-CwRHBuXB.webp +0 -0
- zenml/zen_server/dashboard/assets/url-CkvKAnwF.js +1 -0
- zenml/zen_server/dashboard/assets/{zod-D89GC_vc.js → zod-BwEbpOxH.js} +1 -1
- zenml/zen_server/dashboard/index.html +7 -7
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/exceptions.py +2 -0
- zenml/zen_server/jwt.py +30 -13
- zenml/zen_server/routers/auth_endpoints.py +134 -102
- zenml/zen_server/routers/logs_endpoints.py +66 -0
- zenml/zen_server/template_execution/utils.py +14 -16
- zenml/zen_server/utils.py +27 -0
- zenml/zen_server/zen_server_api.py +6 -1
- zenml/zen_stores/migrations/versions/0.70.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/904464ea4041_add_pipeline_model_run_unique_constraints.py +192 -0
- zenml/zen_stores/rest_zen_store.py +13 -10
- zenml/zen_stores/schemas/model_schemas.py +25 -1
- zenml/zen_stores/schemas/pipeline_run_schemas.py +5 -0
- zenml/zen_stores/schemas/pipeline_schemas.py +8 -2
- zenml/zen_stores/sql_zen_store.py +215 -121
- {zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/METADATA +2 -2
- {zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/RECORD +165 -151
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-C6N2rGrB.js +0 -1
- zenml/zen_server/dashboard/assets/ComponentBadge-DUiEYJHu.js +0 -1
- zenml/zen_server/dashboard/assets/ComponentFallbackDialog-BFoH5K4V.js +0 -1
- zenml/zen_server/dashboard/assets/ComponentIcon-CAIoUis2.js +0 -1
- zenml/zen_server/dashboard/assets/Partials-YPBB3V4q.js +0 -1
- zenml/zen_server/dashboard/assets/ProviderIcon-Bb3Xha5A.js +0 -1
- zenml/zen_server/dashboard/assets/RunSelector-DCiL3M1c.js +0 -1
- zenml/zen_server/dashboard/assets/SearchField-DfUiGFVd.js +0 -1
- zenml/zen_server/dashboard/assets/Tick-CykQFPj2.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-B-s_HMDm.js +0 -1
- zenml/zen_server/dashboard/assets/codespaces-BitYDX9d.gif +0 -0
- zenml/zen_server/dashboard/assets/create-stack-CEmaPZ4c.js +0 -1
- zenml/zen_server/dashboard/assets/delete-run-D-LKbGyz.js +0 -1
- zenml/zen_server/dashboard/assets/index-Bpmj40BI.js +0 -1
- zenml/zen_server/dashboard/assets/index-CbU4Ln_E.css +0 -1
- zenml/zen_server/dashboard/assets/index-DKPhqP2B.js +0 -1
- zenml/zen_server/dashboard/assets/page-BBpOxVcY.js +0 -1
- zenml/zen_server/dashboard/assets/page-BRInM1Lg.js +0 -1
- zenml/zen_server/dashboard/assets/page-BjjlMk7s.js +0 -1
- zenml/zen_server/dashboard/assets/page-Bvd7YH2A.js +0 -1
- zenml/zen_server/dashboard/assets/page-CT3Nep8W.js +0 -1
- zenml/zen_server/dashboard/assets/page-C_f47pBf.js +0 -1
- zenml/zen_server/dashboard/assets/page-Cmv8C_yM.js +0 -3
- zenml/zen_server/dashboard/assets/page-CyN2bdWG.js +0 -1
- zenml/zen_server/dashboard/assets/page-CzzXH4fs.js +0 -1
- zenml/zen_server/dashboard/assets/page-DTlGjgnG.js +0 -1
- zenml/zen_server/dashboard/assets/page-Dbpl86h0.js +0 -1
- zenml/zen_server/dashboard/assets/page-Ddgy6kDS.js +0 -1
- zenml/zen_server/dashboard/assets/page-DtCAfBLy.js +0 -9
- zenml/zen_server/dashboard/assets/page-Dx16z7nA.js +0 -1
- zenml/zen_server/dashboard/assets/page-McUyYbo1.js +0 -1
- zenml/zen_server/dashboard/assets/page-T1P3RyAR.js +0 -1
- zenml/zen_server/dashboard/assets/page-bKaULTGG.js +0 -1
- zenml/zen_server/dashboard/assets/page-sbXUJy9t.js +0 -1
- zenml/zen_server/dashboard/assets/sharedSchema-TMLu-nYQ.js +0 -14
- zenml/zen_server/dashboard/assets/stack-detail-query-xmYxSsUY.js +0 -1
- zenml/zen_server/dashboard/assets/url-D5le3J4q.js +0 -1
- {zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/entry_points.txt +0 -0
@@ -18,6 +18,7 @@ import json
|
|
18
18
|
import logging
|
19
19
|
import math
|
20
20
|
import os
|
21
|
+
import random
|
21
22
|
import re
|
22
23
|
import sys
|
23
24
|
import time
|
@@ -126,6 +127,7 @@ from zenml.exceptions import (
|
|
126
127
|
ActionExistsError,
|
127
128
|
AuthorizationException,
|
128
129
|
BackupSecretsStoreNotConfiguredError,
|
130
|
+
EntityCreationError,
|
129
131
|
EntityExistsError,
|
130
132
|
EventSourceExistsError,
|
131
133
|
IllegalOperationError,
|
@@ -372,6 +374,25 @@ logger = get_logger(__name__)
|
|
372
374
|
ZENML_SQLITE_DB_FILENAME = "zenml.db"
|
373
375
|
|
374
376
|
|
377
|
+
def exponential_backoff_with_jitter(
|
378
|
+
attempt: int, base_duration: float = 0.05
|
379
|
+
) -> float:
|
380
|
+
"""Exponential backoff with jitter.
|
381
|
+
|
382
|
+
Implemented the `Full jitter` algorithm described in
|
383
|
+
https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
384
|
+
|
385
|
+
Args:
|
386
|
+
attempt: The backoff attempt.
|
387
|
+
base_duration: The backoff base duration.
|
388
|
+
|
389
|
+
Returns:
|
390
|
+
The backoff duration.
|
391
|
+
"""
|
392
|
+
exponential_backoff = base_duration * 1.5**attempt
|
393
|
+
return random.uniform(0, exponential_backoff)
|
394
|
+
|
395
|
+
|
375
396
|
class SQLDatabaseDriver(StrEnum):
|
376
397
|
"""SQL database drivers supported by the SQL ZenML store."""
|
377
398
|
|
@@ -2782,7 +2803,9 @@ class SqlZenStore(BaseZenStore):
|
|
2782
2803
|
artifact_version: The artifact version to create.
|
2783
2804
|
|
2784
2805
|
Raises:
|
2785
|
-
EntityExistsError: If
|
2806
|
+
EntityExistsError: If an artifact version with the same name
|
2807
|
+
already exists.
|
2808
|
+
EntityCreationError: If the artifact version creation failed.
|
2786
2809
|
|
2787
2810
|
Returns:
|
2788
2811
|
The created artifact version.
|
@@ -2823,7 +2846,7 @@ class SqlZenStore(BaseZenStore):
|
|
2823
2846
|
artifact_version_id = artifact_version_schema.id
|
2824
2847
|
except IntegrityError:
|
2825
2848
|
if remaining_tries == 0:
|
2826
|
-
raise
|
2849
|
+
raise EntityCreationError(
|
2827
2850
|
f"Failed to create version for artifact "
|
2828
2851
|
f"{artifact_schema.name}. This is most likely "
|
2829
2852
|
"caused by multiple parallel requests that try "
|
@@ -2831,12 +2854,14 @@ class SqlZenStore(BaseZenStore):
|
|
2831
2854
|
"database."
|
2832
2855
|
)
|
2833
2856
|
else:
|
2834
|
-
|
2835
|
-
# parallelization
|
2836
|
-
sleep_duration = 0.05 * 1.5 ** (
|
2857
|
+
attempt = (
|
2837
2858
|
MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
|
2838
2859
|
- remaining_tries
|
2839
2860
|
)
|
2861
|
+
sleep_duration = exponential_backoff_with_jitter(
|
2862
|
+
attempt=attempt
|
2863
|
+
)
|
2864
|
+
|
2840
2865
|
logger.debug(
|
2841
2866
|
"Failed to create artifact version %s "
|
2842
2867
|
"(version %s) due to an integrity error. "
|
@@ -4229,20 +4254,6 @@ class SqlZenStore(BaseZenStore):
|
|
4229
4254
|
EntityExistsError: If an identical pipeline already exists.
|
4230
4255
|
"""
|
4231
4256
|
with Session(self.engine) as session:
|
4232
|
-
# Check if pipeline with the given name already exists
|
4233
|
-
existing_pipeline = session.exec(
|
4234
|
-
select(PipelineSchema)
|
4235
|
-
.where(PipelineSchema.name == pipeline.name)
|
4236
|
-
.where(PipelineSchema.workspace_id == pipeline.workspace)
|
4237
|
-
).first()
|
4238
|
-
if existing_pipeline is not None:
|
4239
|
-
raise EntityExistsError(
|
4240
|
-
f"Unable to create pipeline in workspace "
|
4241
|
-
f"'{pipeline.workspace}': A pipeline with this name "
|
4242
|
-
"already exists."
|
4243
|
-
)
|
4244
|
-
|
4245
|
-
# Create the pipeline
|
4246
4257
|
new_pipeline = PipelineSchema.from_request(pipeline)
|
4247
4258
|
|
4248
4259
|
if pipeline.tags:
|
@@ -4253,7 +4264,14 @@ class SqlZenStore(BaseZenStore):
|
|
4253
4264
|
)
|
4254
4265
|
|
4255
4266
|
session.add(new_pipeline)
|
4256
|
-
|
4267
|
+
try:
|
4268
|
+
session.commit()
|
4269
|
+
except IntegrityError:
|
4270
|
+
raise EntityExistsError(
|
4271
|
+
f"Unable to create pipeline in workspace "
|
4272
|
+
f"'{pipeline.workspace}': A pipeline with the name "
|
4273
|
+
f"{pipeline.name} already exists."
|
4274
|
+
)
|
4257
4275
|
session.refresh(new_pipeline)
|
4258
4276
|
|
4259
4277
|
return new_pipeline.to_model(
|
@@ -5097,6 +5115,26 @@ class SqlZenStore(BaseZenStore):
|
|
5097
5115
|
|
5098
5116
|
# ----------------------------- Pipeline runs -----------------------------
|
5099
5117
|
|
5118
|
+
def _pipeline_run_exists(self, workspace_id: UUID, name: str) -> bool:
|
5119
|
+
"""Check if a pipeline name with a certain name exists.
|
5120
|
+
|
5121
|
+
Args:
|
5122
|
+
workspace_id: The workspace to check.
|
5123
|
+
name: The run name.
|
5124
|
+
|
5125
|
+
Returns:
|
5126
|
+
If a pipeline run with the given name exists.
|
5127
|
+
"""
|
5128
|
+
with Session(self.engine) as session:
|
5129
|
+
return (
|
5130
|
+
session.exec(
|
5131
|
+
select(PipelineRunSchema.id)
|
5132
|
+
.where(PipelineRunSchema.workspace_id == workspace_id)
|
5133
|
+
.where(PipelineRunSchema.name == name)
|
5134
|
+
).first()
|
5135
|
+
is not None
|
5136
|
+
)
|
5137
|
+
|
5100
5138
|
def create_run(
|
5101
5139
|
self, pipeline_run: PipelineRunRequest
|
5102
5140
|
) -> PipelineRunResponse:
|
@@ -5112,18 +5150,6 @@ class SqlZenStore(BaseZenStore):
|
|
5112
5150
|
EntityExistsError: If a run with the same name already exists.
|
5113
5151
|
"""
|
5114
5152
|
with Session(self.engine) as session:
|
5115
|
-
# Check if pipeline run with same name already exists.
|
5116
|
-
existing_domain_run = session.exec(
|
5117
|
-
select(PipelineRunSchema).where(
|
5118
|
-
PipelineRunSchema.name == pipeline_run.name
|
5119
|
-
)
|
5120
|
-
).first()
|
5121
|
-
if existing_domain_run is not None:
|
5122
|
-
raise EntityExistsError(
|
5123
|
-
f"Unable to create pipeline run: A pipeline run with name "
|
5124
|
-
f"'{pipeline_run.name}' already exists."
|
5125
|
-
)
|
5126
|
-
|
5127
5153
|
# Create the pipeline run
|
5128
5154
|
new_run = PipelineRunSchema.from_request(pipeline_run)
|
5129
5155
|
|
@@ -5135,7 +5161,22 @@ class SqlZenStore(BaseZenStore):
|
|
5135
5161
|
)
|
5136
5162
|
|
5137
5163
|
session.add(new_run)
|
5138
|
-
|
5164
|
+
try:
|
5165
|
+
session.commit()
|
5166
|
+
except IntegrityError:
|
5167
|
+
if self._pipeline_run_exists(
|
5168
|
+
workspace_id=pipeline_run.workspace, name=pipeline_run.name
|
5169
|
+
):
|
5170
|
+
raise EntityExistsError(
|
5171
|
+
f"Unable to create pipeline run: A pipeline run with "
|
5172
|
+
f"name '{pipeline_run.name}' already exists."
|
5173
|
+
)
|
5174
|
+
else:
|
5175
|
+
raise EntityExistsError(
|
5176
|
+
"Unable to create pipeline run: A pipeline run with "
|
5177
|
+
"the same deployment_id and orchestrator_run_id "
|
5178
|
+
"already exists."
|
5179
|
+
)
|
5139
5180
|
|
5140
5181
|
return new_run.to_model(
|
5141
5182
|
include_metadata=True, include_resources=True
|
@@ -5327,21 +5368,14 @@ class SqlZenStore(BaseZenStore):
|
|
5327
5368
|
if pre_creation_hook:
|
5328
5369
|
pre_creation_hook()
|
5329
5370
|
return self.create_run(pipeline_run), True
|
5330
|
-
except
|
5331
|
-
# Creating the run failed
|
5332
|
-
# -
|
5333
|
-
#
|
5334
|
-
#
|
5335
|
-
#
|
5336
|
-
#
|
5337
|
-
#
|
5338
|
-
# case we want to fail) or a run created by a step of the same
|
5339
|
-
# pipeline run (in which case we want to return it).
|
5340
|
-
# Note: The IntegrityError might also be raised when other unique
|
5341
|
-
# constraints get violated. The only other such constraint is the
|
5342
|
-
# primary key constraint on the run ID, which means we randomly
|
5343
|
-
# generated an existing UUID. In this case the call below will fail,
|
5344
|
-
# but the chance of that happening is so low we don't handle it.
|
5371
|
+
except EntityExistsError as create_error:
|
5372
|
+
# Creating the run failed because
|
5373
|
+
# - a run with the same deployment_id and orchestrator_run_id
|
5374
|
+
# exists. We now fetch and return that run.
|
5375
|
+
# - a run with the same name already exists. This could be either a
|
5376
|
+
# different run (in which case we want to fail) or a run created
|
5377
|
+
# by a step of the same pipeline run (in which case we want to
|
5378
|
+
# return it).
|
5345
5379
|
try:
|
5346
5380
|
return (
|
5347
5381
|
self._get_run_by_orchestrator_run_id(
|
@@ -5351,18 +5385,11 @@ class SqlZenStore(BaseZenStore):
|
|
5351
5385
|
False,
|
5352
5386
|
)
|
5353
5387
|
except KeyError:
|
5354
|
-
if
|
5355
|
-
|
5356
|
-
|
5357
|
-
|
5358
|
-
|
5359
|
-
|
5360
|
-
# This should never happen as the run creation failed with an
|
5361
|
-
# IntegrityError which means a run with the deployment_id and
|
5362
|
-
# orchestrator_run_id exists.
|
5363
|
-
raise RuntimeError(
|
5364
|
-
f"Failed to get or create run: {create_error}"
|
5365
|
-
)
|
5388
|
+
# We should only get here if the run creation failed because
|
5389
|
+
# of a name conflict. We raise the error that happened during
|
5390
|
+
# creation in any case to forward the error message to the
|
5391
|
+
# user.
|
5392
|
+
raise create_error
|
5366
5393
|
|
5367
5394
|
def list_runs(
|
5368
5395
|
self,
|
@@ -10000,19 +10027,10 @@ class SqlZenStore(BaseZenStore):
|
|
10000
10027
|
The newly created model.
|
10001
10028
|
|
10002
10029
|
Raises:
|
10003
|
-
EntityExistsError: If a
|
10030
|
+
EntityExistsError: If a model with the given name already exists.
|
10004
10031
|
"""
|
10005
10032
|
validate_name(model)
|
10006
10033
|
with Session(self.engine) as session:
|
10007
|
-
existing_model = session.exec(
|
10008
|
-
select(ModelSchema).where(ModelSchema.name == model.name)
|
10009
|
-
).first()
|
10010
|
-
if existing_model is not None:
|
10011
|
-
raise EntityExistsError(
|
10012
|
-
f"Unable to create model {model.name}: "
|
10013
|
-
"A model with this name already exists."
|
10014
|
-
)
|
10015
|
-
|
10016
10034
|
model_schema = ModelSchema.from_request(model)
|
10017
10035
|
session.add(model_schema)
|
10018
10036
|
|
@@ -10022,7 +10040,14 @@ class SqlZenStore(BaseZenStore):
|
|
10022
10040
|
resource_id=model_schema.id,
|
10023
10041
|
resource_type=TaggableResourceTypes.MODEL,
|
10024
10042
|
)
|
10025
|
-
|
10043
|
+
try:
|
10044
|
+
session.commit()
|
10045
|
+
except IntegrityError:
|
10046
|
+
raise EntityExistsError(
|
10047
|
+
f"Unable to create model {model.name}: "
|
10048
|
+
"A model with this name already exists."
|
10049
|
+
)
|
10050
|
+
|
10026
10051
|
return model_schema.to_model(
|
10027
10052
|
include_metadata=True, include_resources=True
|
10028
10053
|
)
|
@@ -10158,6 +10183,50 @@ class SqlZenStore(BaseZenStore):
|
|
10158
10183
|
|
10159
10184
|
# ----------------------------- Model Versions -----------------------------
|
10160
10185
|
|
10186
|
+
def _get_next_numeric_version_for_model(
|
10187
|
+
self, session: Session, model_id: UUID
|
10188
|
+
) -> int:
|
10189
|
+
"""Get the next numeric version for a model.
|
10190
|
+
|
10191
|
+
Args:
|
10192
|
+
session: DB session.
|
10193
|
+
model_id: ID of the model for which to get the next numeric
|
10194
|
+
version.
|
10195
|
+
|
10196
|
+
Returns:
|
10197
|
+
The next numeric version.
|
10198
|
+
"""
|
10199
|
+
current_max_version = session.exec(
|
10200
|
+
select(func.max(ModelVersionSchema.number)).where(
|
10201
|
+
ModelVersionSchema.model_id == model_id
|
10202
|
+
)
|
10203
|
+
).first()
|
10204
|
+
|
10205
|
+
if current_max_version is None:
|
10206
|
+
return 1
|
10207
|
+
else:
|
10208
|
+
return int(current_max_version) + 1
|
10209
|
+
|
10210
|
+
def _model_version_exists(self, model_id: UUID, version: str) -> bool:
|
10211
|
+
"""Check if a model version with a certain version exists.
|
10212
|
+
|
10213
|
+
Args:
|
10214
|
+
model_id: The model ID of the version.
|
10215
|
+
version: The version name.
|
10216
|
+
|
10217
|
+
Returns:
|
10218
|
+
If a model version with the given version name exists.
|
10219
|
+
"""
|
10220
|
+
with Session(self.engine) as session:
|
10221
|
+
return (
|
10222
|
+
session.exec(
|
10223
|
+
select(ModelVersionSchema.id)
|
10224
|
+
.where(ModelVersionSchema.model_id == model_id)
|
10225
|
+
.where(ModelVersionSchema.name == version)
|
10226
|
+
).first()
|
10227
|
+
is not None
|
10228
|
+
)
|
10229
|
+
|
10161
10230
|
@track_decorator(AnalyticsEvent.CREATED_MODEL_VERSION)
|
10162
10231
|
def create_model_version(
|
10163
10232
|
self, model_version: ModelVersionRequest
|
@@ -10172,70 +10241,95 @@ class SqlZenStore(BaseZenStore):
|
|
10172
10241
|
|
10173
10242
|
Raises:
|
10174
10243
|
ValueError: If `number` is not None during model version creation.
|
10175
|
-
EntityExistsError: If a
|
10244
|
+
EntityExistsError: If a model version with the given name already
|
10245
|
+
exists.
|
10246
|
+
EntityCreationError: If the model version creation failed.
|
10176
10247
|
"""
|
10177
10248
|
if model_version.number is not None:
|
10178
10249
|
raise ValueError(
|
10179
10250
|
"`number` field must be None during model version creation."
|
10180
10251
|
)
|
10181
|
-
with Session(self.engine) as session:
|
10182
|
-
model_version_ = model_version.model_copy()
|
10183
|
-
model = self.get_model(model_version_.model)
|
10184
10252
|
|
10185
|
-
|
10186
|
-
query = session.exec(
|
10187
|
-
select(ModelVersionSchema)
|
10188
|
-
.where(ModelVersionSchema.model_id == model.id)
|
10189
|
-
.where(ModelVersionSchema.name == model_version_.name)
|
10190
|
-
)
|
10191
|
-
existing_model_version = query.fetchmany(tolerance + 1)
|
10192
|
-
if (
|
10193
|
-
existing_model_version is not None
|
10194
|
-
and len(existing_model_version) > tolerance
|
10195
|
-
):
|
10196
|
-
raise EntityExistsError(
|
10197
|
-
f"Unable to create model version {model_version_.name}: "
|
10198
|
-
f"A model version with this name already exists in {model.name} model."
|
10199
|
-
)
|
10253
|
+
model = self.get_model(model_version.model)
|
10200
10254
|
|
10201
|
-
|
10202
|
-
|
10203
|
-
|
10204
|
-
.where(ModelVersionSchema.model_id == model.id)
|
10205
|
-
.order_by(ModelVersionSchema.number.desc()) # type: ignore[attr-defined]
|
10206
|
-
).first()
|
10255
|
+
has_custom_name = model_version.name is not None
|
10256
|
+
if has_custom_name:
|
10257
|
+
validate_name(model_version)
|
10207
10258
|
|
10208
|
-
|
10209
|
-
all_versions.number + 1 if all_versions else 1
|
10210
|
-
)
|
10259
|
+
model_version_id = None
|
10211
10260
|
|
10212
|
-
|
10213
|
-
|
10214
|
-
|
10215
|
-
|
10261
|
+
remaining_tries = MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
|
10262
|
+
while remaining_tries > 0:
|
10263
|
+
remaining_tries -= 1
|
10264
|
+
try:
|
10265
|
+
with Session(self.engine) as session:
|
10266
|
+
model_version.number = (
|
10267
|
+
self._get_next_numeric_version_for_model(
|
10268
|
+
session=session,
|
10269
|
+
model_id=model.id,
|
10270
|
+
)
|
10271
|
+
)
|
10272
|
+
if not has_custom_name:
|
10273
|
+
model_version.name = str(model_version.number)
|
10216
10274
|
|
10217
|
-
|
10218
|
-
|
10219
|
-
|
10220
|
-
|
10275
|
+
model_version_schema = ModelVersionSchema.from_request(
|
10276
|
+
model_version
|
10277
|
+
)
|
10278
|
+
session.add(model_version_schema)
|
10279
|
+
session.commit()
|
10221
10280
|
|
10222
|
-
|
10223
|
-
|
10224
|
-
|
10225
|
-
|
10226
|
-
|
10227
|
-
)
|
10228
|
-
|
10229
|
-
|
10230
|
-
|
10231
|
-
|
10232
|
-
|
10233
|
-
|
10281
|
+
model_version_id = model_version_schema.id
|
10282
|
+
break
|
10283
|
+
except IntegrityError:
|
10284
|
+
if has_custom_name and self._model_version_exists(
|
10285
|
+
model_id=model.id, version=cast(str, model_version.name)
|
10286
|
+
):
|
10287
|
+
# We failed not because of a version number conflict,
|
10288
|
+
# but because the user requested a version name that
|
10289
|
+
# is already taken -> We don't retry anymore but fail
|
10290
|
+
# immediately.
|
10291
|
+
raise EntityExistsError(
|
10292
|
+
f"Unable to create model version "
|
10293
|
+
f"{model.name} (version "
|
10294
|
+
f"{model_version.name}): A model with the "
|
10295
|
+
"same name and version already exists."
|
10296
|
+
)
|
10297
|
+
elif remaining_tries == 0:
|
10298
|
+
raise EntityCreationError(
|
10299
|
+
f"Failed to create version for model "
|
10300
|
+
f"{model.name}. This is most likely "
|
10301
|
+
"caused by multiple parallel requests that try "
|
10302
|
+
"to create versions for this model in the "
|
10303
|
+
"database."
|
10304
|
+
)
|
10305
|
+
else:
|
10306
|
+
attempt = (
|
10307
|
+
MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
|
10308
|
+
- remaining_tries
|
10309
|
+
)
|
10310
|
+
sleep_duration = exponential_backoff_with_jitter(
|
10311
|
+
attempt=attempt
|
10312
|
+
)
|
10313
|
+
logger.debug(
|
10314
|
+
"Failed to create model version %s "
|
10315
|
+
"(version %s) due to an integrity error. "
|
10316
|
+
"Retrying in %f seconds.",
|
10317
|
+
model.name,
|
10318
|
+
model_version.number,
|
10319
|
+
sleep_duration,
|
10320
|
+
)
|
10321
|
+
time.sleep(sleep_duration)
|
10234
10322
|
|
10235
|
-
|
10236
|
-
|
10323
|
+
assert model_version_id
|
10324
|
+
if model_version.tags:
|
10325
|
+
self._attach_tags_to_resource(
|
10326
|
+
tag_names=model_version.tags,
|
10327
|
+
resource_id=model_version_id,
|
10328
|
+
resource_type=TaggableResourceTypes.MODEL_VERSION,
|
10237
10329
|
)
|
10238
10330
|
|
10331
|
+
return self.get_model_version(model_version_id)
|
10332
|
+
|
10239
10333
|
def get_model_version(
|
10240
10334
|
self, model_version_id: UUID, hydrate: bool = True
|
10241
10335
|
) -> ModelVersionResponse:
|
{zenml_nightly-0.68.1.dev20241111.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: zenml-nightly
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.70.0.dev20241114
|
4
4
|
Summary: ZenML: Write production-ready ML code.
|
5
5
|
Home-page: https://zenml.io
|
6
6
|
License: Apache-2.0
|
@@ -474,7 +474,7 @@ the Apache License Version 2.0.
|
|
474
474
|
<a href="https://github.com/zenml-io/zenml-projects">Projects Showcase</a>
|
475
475
|
<br />
|
476
476
|
<br />
|
477
|
-
🎉 Version 0.
|
477
|
+
🎉 Version 0.70.0 is out. Check out the release notes
|
478
478
|
<a href="https://github.com/zenml-io/zenml/releases">here</a>.
|
479
479
|
<br />
|
480
480
|
🖥️ Download our VS Code Extension <a href="https://marketplace.visualstudio.com/items?itemName=ZenML.zenml-vscode">here</a>.
|