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
zenml/models/v2/base/filter.py
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Base filter model definitions."""
|
15
15
|
|
16
|
+
import json
|
16
17
|
from abc import ABC, abstractmethod
|
17
18
|
from datetime import datetime
|
18
19
|
from typing import (
|
@@ -36,7 +37,7 @@ from pydantic import (
|
|
36
37
|
field_validator,
|
37
38
|
model_validator,
|
38
39
|
)
|
39
|
-
from sqlalchemy import asc, desc
|
40
|
+
from sqlalchemy import Float, and_, asc, cast, desc
|
40
41
|
from sqlmodel import SQLModel
|
41
42
|
|
42
43
|
from zenml.constants import (
|
@@ -63,6 +64,11 @@ logger = get_logger(__name__)
|
|
63
64
|
|
64
65
|
AnyQuery = TypeVar("AnyQuery", bound=Any)
|
65
66
|
|
67
|
+
ONEOF_ERROR = (
|
68
|
+
"When you are using the 'oneof:' filtering make sure that the "
|
69
|
+
"provided value is a json formatted list."
|
70
|
+
)
|
71
|
+
|
66
72
|
|
67
73
|
class Filter(BaseModel, ABC):
|
68
74
|
"""Filter for all fields.
|
@@ -171,8 +177,28 @@ class StrFilter(Filter):
|
|
171
177
|
GenericFilterOps.STARTSWITH,
|
172
178
|
GenericFilterOps.CONTAINS,
|
173
179
|
GenericFilterOps.ENDSWITH,
|
180
|
+
GenericFilterOps.ONEOF,
|
181
|
+
GenericFilterOps.GT,
|
182
|
+
GenericFilterOps.GTE,
|
183
|
+
GenericFilterOps.LT,
|
184
|
+
GenericFilterOps.LTE,
|
174
185
|
]
|
175
186
|
|
187
|
+
@model_validator(mode="after")
|
188
|
+
def check_value_if_operation_oneof(self) -> "StrFilter":
|
189
|
+
"""Validator to check if value is a list if oneof operation is used.
|
190
|
+
|
191
|
+
Raises:
|
192
|
+
ValueError: If the value is not a list
|
193
|
+
|
194
|
+
Returns:
|
195
|
+
self
|
196
|
+
"""
|
197
|
+
if self.operation == GenericFilterOps.ONEOF:
|
198
|
+
if not isinstance(self.value, list):
|
199
|
+
raise ValueError(ONEOF_ERROR)
|
200
|
+
return self
|
201
|
+
|
176
202
|
def generate_query_conditions_from_column(self, column: Any) -> Any:
|
177
203
|
"""Generate query conditions for a string column.
|
178
204
|
|
@@ -181,6 +207,9 @@ class StrFilter(Filter):
|
|
181
207
|
|
182
208
|
Returns:
|
183
209
|
A list of query conditions.
|
210
|
+
|
211
|
+
Raises:
|
212
|
+
ValueError: the comparison of the column to a numeric value fails.
|
184
213
|
"""
|
185
214
|
if self.operation == GenericFilterOps.CONTAINS:
|
186
215
|
return column.like(f"%{self.value}%")
|
@@ -190,6 +219,40 @@ class StrFilter(Filter):
|
|
190
219
|
return column.endswith(f"{self.value}")
|
191
220
|
if self.operation == GenericFilterOps.NOT_EQUALS:
|
192
221
|
return column != self.value
|
222
|
+
if self.operation == GenericFilterOps.ONEOF:
|
223
|
+
return column.in_(self.value)
|
224
|
+
if self.operation in {
|
225
|
+
GenericFilterOps.GT,
|
226
|
+
GenericFilterOps.LT,
|
227
|
+
GenericFilterOps.GTE,
|
228
|
+
GenericFilterOps.LTE,
|
229
|
+
}:
|
230
|
+
try:
|
231
|
+
numeric_column = cast(column, Float)
|
232
|
+
|
233
|
+
assert self.value is not None
|
234
|
+
|
235
|
+
if self.operation == GenericFilterOps.GT:
|
236
|
+
return and_(
|
237
|
+
numeric_column, numeric_column > float(self.value)
|
238
|
+
)
|
239
|
+
if self.operation == GenericFilterOps.LT:
|
240
|
+
return and_(
|
241
|
+
numeric_column, numeric_column < float(self.value)
|
242
|
+
)
|
243
|
+
if self.operation == GenericFilterOps.GTE:
|
244
|
+
return and_(
|
245
|
+
numeric_column, numeric_column >= float(self.value)
|
246
|
+
)
|
247
|
+
if self.operation == GenericFilterOps.LTE:
|
248
|
+
return and_(
|
249
|
+
numeric_column, numeric_column <= float(self.value)
|
250
|
+
)
|
251
|
+
except Exception as e:
|
252
|
+
raise ValueError(
|
253
|
+
f"Failed to compare the column '{column}' to the "
|
254
|
+
f"value '{self.value}' (must be numeric): {e}"
|
255
|
+
)
|
193
256
|
|
194
257
|
return column == self.value
|
195
258
|
|
@@ -211,6 +274,9 @@ class UUIDFilter(StrFilter):
|
|
211
274
|
if isinstance(value, str):
|
212
275
|
return value.replace("-", "")
|
213
276
|
|
277
|
+
if isinstance(value, list):
|
278
|
+
return [str(v).replace("-", "") for v in value]
|
279
|
+
|
214
280
|
return value
|
215
281
|
|
216
282
|
def generate_query_conditions_from_column(self, column: Any) -> Any:
|
@@ -588,6 +654,10 @@ class BaseFilter(BaseModel):
|
|
588
654
|
|
589
655
|
Returns:
|
590
656
|
A tuple of the filter value and the operator.
|
657
|
+
|
658
|
+
Raises:
|
659
|
+
ValueError: when we try to use the `oneof` operator with the wrong
|
660
|
+
value.
|
591
661
|
"""
|
592
662
|
operator = GenericFilterOps.EQUALS # Default operator
|
593
663
|
if isinstance(value, str):
|
@@ -598,6 +668,15 @@ class BaseFilter(BaseModel):
|
|
598
668
|
):
|
599
669
|
value = split_value[1]
|
600
670
|
operator = GenericFilterOps(split_value[0])
|
671
|
+
|
672
|
+
if operator == operator.ONEOF:
|
673
|
+
try:
|
674
|
+
value = json.loads(value)
|
675
|
+
if not isinstance(value, list):
|
676
|
+
raise ValueError
|
677
|
+
except ValueError:
|
678
|
+
raise ValueError(ONEOF_ERROR)
|
679
|
+
|
601
680
|
return value, operator
|
602
681
|
|
603
682
|
def generate_name_or_id_query_conditions(
|
@@ -648,8 +727,8 @@ class BaseFilter(BaseModel):
|
|
648
727
|
|
649
728
|
return or_(*conditions)
|
650
729
|
|
730
|
+
@staticmethod
|
651
731
|
def generate_custom_query_conditions_for_column(
|
652
|
-
self,
|
653
732
|
value: Any,
|
654
733
|
table: Type[SQLModel],
|
655
734
|
column: str,
|
@@ -833,16 +912,17 @@ class FilterGenerator:
|
|
833
912
|
|
834
913
|
# Create str filters
|
835
914
|
if self.is_str_field(column):
|
836
|
-
return
|
837
|
-
|
915
|
+
return self._define_str_filter(
|
916
|
+
operator=GenericFilterOps(operator),
|
838
917
|
column=column,
|
839
918
|
value=value,
|
840
919
|
)
|
841
920
|
|
842
921
|
# Handle unsupported datatypes
|
843
922
|
logger.warning(
|
844
|
-
f"The Datatype {self._model_class.model_fields[column].annotation}
|
845
|
-
"not be supported for filtering. Defaulting to a string
|
923
|
+
f"The Datatype {self._model_class.model_fields[column].annotation} "
|
924
|
+
"might not be supported for filtering. Defaulting to a string "
|
925
|
+
"filter."
|
846
926
|
)
|
847
927
|
return StrFilter(
|
848
928
|
operation=GenericFilterOps(operator),
|
@@ -1032,8 +1112,9 @@ class FilterGenerator:
|
|
1032
1112
|
"Invalid value passed as UUID query parameter."
|
1033
1113
|
) from e
|
1034
1114
|
|
1035
|
-
#
|
1036
|
-
|
1115
|
+
# For equality checks, ensure that the value is a valid UUID.
|
1116
|
+
if operator == GenericFilterOps.ONEOF and not isinstance(value, list):
|
1117
|
+
raise ValueError(ONEOF_ERROR)
|
1037
1118
|
|
1038
1119
|
# Generate the filter.
|
1039
1120
|
uuid_filter = UUIDFilter(
|
@@ -1043,6 +1124,38 @@ class FilterGenerator:
|
|
1043
1124
|
)
|
1044
1125
|
return uuid_filter
|
1045
1126
|
|
1127
|
+
@staticmethod
|
1128
|
+
def _define_str_filter(
|
1129
|
+
column: str, value: Any, operator: GenericFilterOps
|
1130
|
+
) -> StrFilter:
|
1131
|
+
"""Define a str filter for a given column.
|
1132
|
+
|
1133
|
+
Args:
|
1134
|
+
column: The column to filter on.
|
1135
|
+
value: The UUID value by which to filter.
|
1136
|
+
operator: The operator to use for filtering.
|
1137
|
+
|
1138
|
+
Returns:
|
1139
|
+
A Filter object.
|
1140
|
+
|
1141
|
+
Raises:
|
1142
|
+
ValueError: If the value is not a proper value.
|
1143
|
+
"""
|
1144
|
+
# For equality checks, ensure that the value is a valid UUID.
|
1145
|
+
if operator == GenericFilterOps.ONEOF and not isinstance(value, list):
|
1146
|
+
raise ValueError(
|
1147
|
+
"If you are using `oneof:` as a filtering op, the value needs "
|
1148
|
+
"to be a json formatted list string."
|
1149
|
+
)
|
1150
|
+
|
1151
|
+
# Generate the filter.
|
1152
|
+
str_filter = StrFilter(
|
1153
|
+
operation=GenericFilterOps(operator),
|
1154
|
+
column=column,
|
1155
|
+
value=value,
|
1156
|
+
)
|
1157
|
+
return str_filter
|
1158
|
+
|
1046
1159
|
@staticmethod
|
1047
1160
|
def _define_bool_filter(
|
1048
1161
|
column: str, value: Any, operator: GenericFilterOps
|
@@ -474,6 +474,7 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
474
474
|
"user",
|
475
475
|
"model",
|
476
476
|
"pipeline_run",
|
477
|
+
"run_metadata",
|
477
478
|
]
|
478
479
|
artifact_id: Optional[Union[UUID, str]] = Field(
|
479
480
|
default=None,
|
@@ -545,6 +546,10 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
545
546
|
description="Name/ID of a pipeline run that is associated with this "
|
546
547
|
"artifact version.",
|
547
548
|
)
|
549
|
+
run_metadata: Optional[Dict[str, str]] = Field(
|
550
|
+
default=None,
|
551
|
+
description="The run_metadata to filter the artifact versions by.",
|
552
|
+
)
|
548
553
|
|
549
554
|
model_config = ConfigDict(protected_namespaces=())
|
550
555
|
|
@@ -564,6 +569,7 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
564
569
|
ModelSchema,
|
565
570
|
ModelVersionArtifactSchema,
|
566
571
|
PipelineRunSchema,
|
572
|
+
RunMetadataSchema,
|
567
573
|
StepRunInputArtifactSchema,
|
568
574
|
StepRunOutputArtifactSchema,
|
569
575
|
StepRunSchema,
|
@@ -645,6 +651,23 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
645
651
|
)
|
646
652
|
custom_filters.append(pipeline_run_filter)
|
647
653
|
|
654
|
+
if self.run_metadata is not None:
|
655
|
+
from zenml.enums import MetadataResourceTypes
|
656
|
+
|
657
|
+
for key, value in self.run_metadata.items():
|
658
|
+
additional_filter = and_(
|
659
|
+
RunMetadataSchema.resource_id == ArtifactVersionSchema.id,
|
660
|
+
RunMetadataSchema.resource_type
|
661
|
+
== MetadataResourceTypes.ARTIFACT_VERSION,
|
662
|
+
RunMetadataSchema.key == key,
|
663
|
+
self.generate_custom_query_conditions_for_column(
|
664
|
+
value=value,
|
665
|
+
table=RunMetadataSchema,
|
666
|
+
column="value",
|
667
|
+
),
|
668
|
+
)
|
669
|
+
custom_filters.append(additional_filter)
|
670
|
+
|
648
671
|
return custom_filters
|
649
672
|
|
650
673
|
|
@@ -590,6 +590,7 @@ class ModelVersionFilter(WorkspaceScopedTaggableFilter):
|
|
590
590
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
591
591
|
*WorkspaceScopedTaggableFilter.FILTER_EXCLUDE_FIELDS,
|
592
592
|
"user",
|
593
|
+
"run_metadata",
|
593
594
|
]
|
594
595
|
|
595
596
|
name: Optional[str] = Field(
|
@@ -619,6 +620,10 @@ class ModelVersionFilter(WorkspaceScopedTaggableFilter):
|
|
619
620
|
default=None,
|
620
621
|
description="Name/ID of the user that created the model version.",
|
621
622
|
)
|
623
|
+
run_metadata: Optional[Dict[str, str]] = Field(
|
624
|
+
default=None,
|
625
|
+
description="The run_metadata to filter the model versions by.",
|
626
|
+
)
|
622
627
|
|
623
628
|
_model_id: UUID = PrivateAttr(None)
|
624
629
|
|
@@ -651,6 +656,7 @@ class ModelVersionFilter(WorkspaceScopedTaggableFilter):
|
|
651
656
|
|
652
657
|
from zenml.zen_stores.schemas import (
|
653
658
|
ModelVersionSchema,
|
659
|
+
RunMetadataSchema,
|
654
660
|
UserSchema,
|
655
661
|
)
|
656
662
|
|
@@ -665,6 +671,23 @@ class ModelVersionFilter(WorkspaceScopedTaggableFilter):
|
|
665
671
|
)
|
666
672
|
custom_filters.append(user_filter)
|
667
673
|
|
674
|
+
if self.run_metadata is not None:
|
675
|
+
from zenml.enums import MetadataResourceTypes
|
676
|
+
|
677
|
+
for key, value in self.run_metadata.items():
|
678
|
+
additional_filter = and_(
|
679
|
+
RunMetadataSchema.resource_id == ModelVersionSchema.id,
|
680
|
+
RunMetadataSchema.resource_type
|
681
|
+
== MetadataResourceTypes.MODEL_VERSION,
|
682
|
+
RunMetadataSchema.key == key,
|
683
|
+
self.generate_custom_query_conditions_for_column(
|
684
|
+
value=value,
|
685
|
+
table=RunMetadataSchema,
|
686
|
+
column="value",
|
687
|
+
),
|
688
|
+
)
|
689
|
+
custom_filters.append(additional_filter)
|
690
|
+
|
668
691
|
return custom_filters
|
669
692
|
|
670
693
|
def apply_filter(
|
@@ -587,6 +587,7 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
|
|
587
587
|
"stack_component",
|
588
588
|
"pipeline_name",
|
589
589
|
"templatable",
|
590
|
+
"run_metadata",
|
590
591
|
]
|
591
592
|
name: Optional[str] = Field(
|
592
593
|
default=None,
|
@@ -665,6 +666,10 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
|
|
665
666
|
default=None,
|
666
667
|
description="Name/ID of the user that created the run.",
|
667
668
|
)
|
669
|
+
run_metadata: Optional[Dict[str, str]] = Field(
|
670
|
+
default=None,
|
671
|
+
description="The run_metadata to filter the pipeline runs by.",
|
672
|
+
)
|
668
673
|
# TODO: Remove once frontend is ready for it. This is replaced by the more
|
669
674
|
# generic `pipeline` filter below.
|
670
675
|
pipeline_name: Optional[str] = Field(
|
@@ -694,7 +699,6 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
|
|
694
699
|
templatable: Optional[bool] = Field(
|
695
700
|
default=None, description="Whether the run is templatable."
|
696
701
|
)
|
697
|
-
|
698
702
|
model_config = ConfigDict(protected_namespaces=())
|
699
703
|
|
700
704
|
def get_custom_filters(
|
@@ -718,6 +722,7 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
|
|
718
722
|
PipelineDeploymentSchema,
|
719
723
|
PipelineRunSchema,
|
720
724
|
PipelineSchema,
|
725
|
+
RunMetadataSchema,
|
721
726
|
ScheduleSchema,
|
722
727
|
StackComponentSchema,
|
723
728
|
StackCompositionSchema,
|
@@ -887,5 +892,21 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
|
|
887
892
|
)
|
888
893
|
|
889
894
|
custom_filters.append(templatable_filter)
|
895
|
+
if self.run_metadata is not None:
|
896
|
+
from zenml.enums import MetadataResourceTypes
|
897
|
+
|
898
|
+
for key, value in self.run_metadata.items():
|
899
|
+
additional_filter = and_(
|
900
|
+
RunMetadataSchema.resource_id == PipelineRunSchema.id,
|
901
|
+
RunMetadataSchema.resource_type
|
902
|
+
== MetadataResourceTypes.PIPELINE_RUN,
|
903
|
+
RunMetadataSchema.key == key,
|
904
|
+
self.generate_custom_query_conditions_for_column(
|
905
|
+
value=value,
|
906
|
+
table=RunMetadataSchema,
|
907
|
+
column="value",
|
908
|
+
),
|
909
|
+
)
|
910
|
+
custom_filters.append(additional_filter)
|
890
911
|
|
891
912
|
return custom_filters
|
zenml/models/v2/core/step_run.py
CHANGED
@@ -509,6 +509,7 @@ class StepRunFilter(WorkspaceScopedFilter):
|
|
509
509
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
510
510
|
*WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
|
511
511
|
"model",
|
512
|
+
"run_metadata",
|
512
513
|
]
|
513
514
|
|
514
515
|
name: Optional[str] = Field(
|
@@ -571,6 +572,10 @@ class StepRunFilter(WorkspaceScopedFilter):
|
|
571
572
|
default=None,
|
572
573
|
description="Name/ID of the model associated with the step run.",
|
573
574
|
)
|
575
|
+
run_metadata: Optional[Dict[str, str]] = Field(
|
576
|
+
default=None,
|
577
|
+
description="The run_metadata to filter the step runs by.",
|
578
|
+
)
|
574
579
|
|
575
580
|
model_config = ConfigDict(protected_namespaces=())
|
576
581
|
|
@@ -589,6 +594,7 @@ class StepRunFilter(WorkspaceScopedFilter):
|
|
589
594
|
from zenml.zen_stores.schemas import (
|
590
595
|
ModelSchema,
|
591
596
|
ModelVersionSchema,
|
597
|
+
RunMetadataSchema,
|
592
598
|
StepRunSchema,
|
593
599
|
)
|
594
600
|
|
@@ -601,5 +607,21 @@ class StepRunFilter(WorkspaceScopedFilter):
|
|
601
607
|
),
|
602
608
|
)
|
603
609
|
custom_filters.append(model_filter)
|
610
|
+
if self.run_metadata is not None:
|
611
|
+
from zenml.enums import MetadataResourceTypes
|
612
|
+
|
613
|
+
for key, value in self.run_metadata.items():
|
614
|
+
additional_filter = and_(
|
615
|
+
RunMetadataSchema.resource_id == StepRunSchema.id,
|
616
|
+
RunMetadataSchema.resource_type
|
617
|
+
== MetadataResourceTypes.STEP_RUN,
|
618
|
+
RunMetadataSchema.key == key,
|
619
|
+
self.generate_custom_query_conditions_for_column(
|
620
|
+
value=value,
|
621
|
+
table=RunMetadataSchema,
|
622
|
+
column="value",
|
623
|
+
),
|
624
|
+
)
|
625
|
+
custom_filters.append(additional_filter)
|
604
626
|
|
605
627
|
return custom_filters
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
from abc import ABC, abstractmethod
|
17
17
|
from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional, Type, cast
|
18
|
+
from uuid import UUID
|
18
19
|
|
19
20
|
from pydantic import model_validator
|
20
21
|
|
@@ -186,7 +187,17 @@ class BaseOrchestrator(StackComponent, ABC):
|
|
186
187
|
"""
|
187
188
|
self._prepare_run(deployment=deployment)
|
188
189
|
|
189
|
-
|
190
|
+
pipeline_run_id: Optional[UUID] = None
|
191
|
+
schedule_id: Optional[UUID] = None
|
192
|
+
if deployment.schedule:
|
193
|
+
schedule_id = deployment.schedule.id
|
194
|
+
if placeholder_run:
|
195
|
+
pipeline_run_id = placeholder_run.id
|
196
|
+
|
197
|
+
environment = get_config_environment_vars(
|
198
|
+
schedule_id=schedule_id,
|
199
|
+
pipeline_run_id=pipeline_run_id,
|
200
|
+
)
|
190
201
|
|
191
202
|
prevent_client_side_caching = handle_bool_env_var(
|
192
203
|
ENV_ZENML_PREVENT_CLIENT_SIDE_CACHING, default=False
|
@@ -422,7 +422,8 @@ class StepLauncher:
|
|
422
422
|
)
|
423
423
|
)
|
424
424
|
environment = orchestrator_utils.get_config_environment_vars(
|
425
|
-
|
425
|
+
pipeline_run_id=step_run_info.run_id,
|
426
|
+
step_run_id=step_run_info.step_run_id,
|
426
427
|
)
|
427
428
|
if last_retry:
|
428
429
|
environment[ENV_ZENML_IGNORE_FAILURE_HOOK] = str(False)
|
zenml/orchestrators/utils.py
CHANGED
@@ -28,16 +28,16 @@ from zenml.constants import (
|
|
28
28
|
ENV_ZENML_DISABLE_CREDENTIALS_DISK_CACHING,
|
29
29
|
ENV_ZENML_SERVER,
|
30
30
|
ENV_ZENML_STORE_PREFIX,
|
31
|
-
PIPELINE_API_TOKEN_EXPIRES_MINUTES,
|
32
31
|
)
|
33
32
|
from zenml.enums import AuthScheme, StackComponentType, StoreType
|
34
33
|
from zenml.logger import get_logger
|
35
34
|
from zenml.stack import StackComponent
|
36
35
|
from zenml.utils.string_utils import format_name_template
|
37
36
|
|
37
|
+
logger = get_logger(__name__)
|
38
|
+
|
38
39
|
if TYPE_CHECKING:
|
39
40
|
from zenml.artifact_stores.base_artifact_store import BaseArtifactStore
|
40
|
-
from zenml.models import PipelineDeploymentResponse
|
41
41
|
|
42
42
|
|
43
43
|
def get_orchestrator_run_name(pipeline_name: str) -> str:
|
@@ -80,16 +80,23 @@ def is_setting_enabled(
|
|
80
80
|
|
81
81
|
|
82
82
|
def get_config_environment_vars(
|
83
|
-
|
83
|
+
schedule_id: Optional[UUID] = None,
|
84
|
+
pipeline_run_id: Optional[UUID] = None,
|
85
|
+
step_run_id: Optional[UUID] = None,
|
84
86
|
) -> Dict[str, str]:
|
85
87
|
"""Gets environment variables to set for mirroring the active config.
|
86
88
|
|
87
|
-
If a pipeline
|
88
|
-
|
89
|
-
|
89
|
+
If a schedule ID, pipeline run ID or step run ID is given, and the current
|
90
|
+
client is not authenticated to a server with an API key, the environment
|
91
|
+
variables will be updated to include a newly generated workload API token
|
92
|
+
that will be valid for the duration of the schedule, pipeline run, or step
|
93
|
+
run instead of the current API token used to authenticate the client.
|
90
94
|
|
91
95
|
Args:
|
92
|
-
|
96
|
+
schedule_id: Optional schedule ID to use to generate a new API token.
|
97
|
+
pipeline_run_id: Optional pipeline run ID to use to generate a new API
|
98
|
+
token.
|
99
|
+
step_run_id: Optional step run ID to use to generate a new API token.
|
93
100
|
|
94
101
|
Returns:
|
95
102
|
Environment variable dict.
|
@@ -107,34 +114,46 @@ def get_config_environment_vars(
|
|
107
114
|
):
|
108
115
|
credentials_store = get_credentials_store()
|
109
116
|
url = global_config.store_configuration.url
|
110
|
-
api_key = credentials_store.get_api_key(url)
|
111
117
|
api_token = credentials_store.get_token(url, allow_expired=False)
|
112
|
-
if
|
113
|
-
|
114
|
-
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# valid for the duration of the pipeline run.
|
118
|
+
if schedule_id or pipeline_run_id or step_run_id:
|
119
|
+
# When connected to an authenticated ZenML server, if a schedule ID,
|
120
|
+
# pipeline run ID or step run ID is supplied, we need to fetch a new
|
121
|
+
# workload API token scoped to the schedule, pipeline run or step
|
122
|
+
# run.
|
118
123
|
assert isinstance(global_config.zen_store, RestZenStore)
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
|
125
|
+
# If only a schedule is given, the pipeline run credentials will
|
126
|
+
# be valid for the entire duration of the schedule.
|
127
|
+
api_key = credentials_store.get_api_key(url)
|
128
|
+
if not api_key and not pipeline_run_id and not step_run_id:
|
129
|
+
logger.warning(
|
130
|
+
"An API token without an expiration time will be generated "
|
131
|
+
"and used to run this pipeline on a schedule. This is very "
|
132
|
+
"insecure because the API token will be valid for the "
|
133
|
+
"entire lifetime of the schedule and can be used to access "
|
134
|
+
"your user account if accidentally leaked. When deploying "
|
135
|
+
"a pipeline on a schedule, it is strongly advised to use a "
|
136
|
+
"service account API key to authenticate to the ZenML "
|
137
|
+
"server instead of your regular user account. For more "
|
138
|
+
"information, see "
|
139
|
+
"https://docs.zenml.io/how-to/connecting-to-zenml/connect-with-a-service-account"
|
140
|
+
)
|
141
|
+
|
142
|
+
# The schedule, pipeline run or step run credentials are scoped to
|
143
|
+
# the schedule, pipeline run or step run and will only be valid for
|
144
|
+
# the duration of the schedule/pipeline run/step run.
|
129
145
|
new_api_token = global_config.zen_store.get_api_token(
|
130
|
-
pipeline_id=pipeline_id,
|
131
146
|
schedule_id=schedule_id,
|
132
|
-
|
147
|
+
pipeline_run_id=pipeline_run_id,
|
148
|
+
step_run_id=step_run_id,
|
133
149
|
)
|
150
|
+
|
134
151
|
environment_vars[ENV_ZENML_STORE_PREFIX + "API_TOKEN"] = (
|
135
152
|
new_api_token
|
136
153
|
)
|
137
154
|
elif api_token:
|
155
|
+
# For all other cases, the pipeline run environment is configured
|
156
|
+
# with the current access token.
|
138
157
|
environment_vars[ENV_ZENML_STORE_PREFIX + "API_TOKEN"] = (
|
139
158
|
api_token.access_token
|
140
159
|
)
|
@@ -71,7 +71,8 @@ of any potential costs:
|
|
71
71
|
|
72
72
|
- An S3 bucket registered as a [ZenML artifact store](https://docs.zenml.io/stack-components/artifact-stores/s3).
|
73
73
|
- An ECR repository registered as a [ZenML container registry](https://docs.zenml.io/stack-components/container-registries/aws).
|
74
|
-
- Sagemaker registered as a [ZenML orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker)
|
74
|
+
- Sagemaker registered as a [ZenML orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker)
|
75
|
+
as well as a [ZenML step operator](https://docs.zenml.io/stack-components/step-operators/sagemaker).
|
75
76
|
- An IAM user and IAM role with the minimum necessary permissions to access the
|
76
77
|
above resources.
|
77
78
|
- An AWS access key used to give access to ZenML to connect to the above
|
@@ -257,13 +258,29 @@ console.
|
|
257
258
|
|
258
259
|
config: Optional[str] = None
|
259
260
|
if self.deployment_type == STACK_DEPLOYMENT_TERRAFORM:
|
260
|
-
config = f"""
|
261
|
-
|
261
|
+
config = f"""terraform {{
|
262
|
+
required_providers {{
|
263
|
+
aws = {{
|
264
|
+
source = "hashicorp/aws"
|
265
|
+
}}
|
266
|
+
zenml = {{
|
267
|
+
source = "zenml-io/zenml"
|
268
|
+
}}
|
269
|
+
}}
|
270
|
+
}}
|
262
271
|
|
272
|
+
provider "aws" {{
|
263
273
|
region = "{self.location or "eu-central-1"}"
|
264
|
-
|
265
|
-
|
266
|
-
|
274
|
+
}}
|
275
|
+
|
276
|
+
provider "zenml" {{
|
277
|
+
server_url = "{self.zenml_server_url}"
|
278
|
+
api_token = "{self.zenml_server_api_token}"
|
279
|
+
}}
|
280
|
+
|
281
|
+
module "zenml_stack" {{
|
282
|
+
source = "zenml-io/zenml-stack/aws"
|
283
|
+
|
267
284
|
zenml_stack_name = "{self.stack_name}"
|
268
285
|
zenml_stack_deployment = "{self.deployment_type}"
|
269
286
|
}}
|
@@ -259,14 +259,37 @@ ZenML's access to your Azure subscription.
|
|
259
259
|
The configuration or script to deploy the ZenML stack to the
|
260
260
|
specified cloud provider.
|
261
261
|
"""
|
262
|
-
config = f"""
|
262
|
+
config = f"""terraform {{
|
263
|
+
required_providers {{
|
264
|
+
azurerm = {{
|
265
|
+
source = "hashicorp/azurerm"
|
266
|
+
}}
|
267
|
+
azuread = {{
|
268
|
+
source = "hashicorp/azuread"
|
269
|
+
}}
|
270
|
+
zenml = {{
|
271
|
+
source = "zenml-io/zenml"
|
272
|
+
}}
|
273
|
+
}}
|
274
|
+
}}
|
275
|
+
|
276
|
+
provider "azurerm" {{
|
277
|
+
features {{
|
278
|
+
resource_group {{
|
279
|
+
prevent_deletion_if_contains_resources = false
|
280
|
+
}}
|
281
|
+
}}
|
282
|
+
}}
|
283
|
+
|
284
|
+
provider "zenml" {{
|
285
|
+
server_url = "{self.zenml_server_url}"
|
286
|
+
api_token = "{self.zenml_server_api_token}"
|
287
|
+
}}
|
288
|
+
|
289
|
+
module "zenml_stack" {{
|
263
290
|
source = "zenml-io/zenml-stack/azure"
|
264
291
|
|
265
292
|
location = "{self.location or "eastus"}"
|
266
|
-
orchestrator = "azureml"
|
267
|
-
zenml_server_url = "{self.zenml_server_url}"
|
268
|
-
zenml_api_key = ""
|
269
|
-
zenml_api_token = "{self.zenml_server_api_token}"
|
270
293
|
zenml_stack_name = "{self.stack_name}"
|
271
294
|
zenml_stack_deployment = "{self.deployment_type}"
|
272
295
|
}}
|