zenml-nightly 0.70.0.dev20241201__py3-none-any.whl → 0.71.0.dev20241220__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- README.md +4 -4
- RELEASE_NOTES.md +112 -0
- zenml/VERSION +1 -1
- zenml/artifacts/artifact_config.py +8 -5
- zenml/artifacts/utils.py +3 -1
- zenml/cli/__init__.py +4 -4
- zenml/cli/base.py +1 -1
- zenml/cli/pipeline.py +48 -79
- zenml/cli/server.py +19 -19
- zenml/client.py +54 -2
- zenml/config/secret_reference_mixin.py +1 -1
- zenml/config/server_config.py +4 -0
- zenml/constants.py +10 -0
- zenml/image_builders/base_image_builder.py +5 -2
- zenml/image_builders/build_context.py +7 -16
- zenml/integrations/aws/__init__.py +3 -0
- zenml/integrations/aws/flavors/__init__.py +6 -0
- zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
- zenml/integrations/aws/image_builders/__init__.py +20 -0
- zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +2 -1
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +11 -0
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +0 -1
- zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +11 -0
- zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
- zenml/integrations/neptune/experiment_trackers/run_state.py +69 -53
- zenml/integrations/registry.py +2 -2
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +12 -0
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +13 -5
- zenml/materializers/built_in_materializer.py +1 -1
- zenml/model/model.py +12 -16
- zenml/model/utils.py +3 -1
- zenml/models/v2/base/filter.py +26 -30
- zenml/models/v2/base/scoped.py +258 -5
- zenml/models/v2/core/artifact_version.py +15 -26
- zenml/models/v2/core/code_repository.py +1 -12
- zenml/models/v2/core/component.py +5 -46
- zenml/models/v2/core/flavor.py +1 -11
- zenml/models/v2/core/model.py +1 -57
- zenml/models/v2/core/model_version.py +5 -33
- zenml/models/v2/core/model_version_artifact.py +11 -3
- zenml/models/v2/core/model_version_pipeline_run.py +14 -3
- zenml/models/v2/core/pipeline.py +47 -55
- zenml/models/v2/core/pipeline_build.py +67 -12
- zenml/models/v2/core/pipeline_deployment.py +0 -10
- zenml/models/v2/core/pipeline_run.py +91 -29
- zenml/models/v2/core/run_template.py +21 -29
- zenml/models/v2/core/schedule.py +0 -10
- zenml/models/v2/core/secret.py +0 -14
- zenml/models/v2/core/service.py +9 -16
- zenml/models/v2/core/service_connector.py +0 -11
- zenml/models/v2/core/stack.py +21 -30
- zenml/models/v2/core/step_run.py +18 -14
- zenml/models/v2/core/trigger.py +19 -3
- zenml/orchestrators/base_orchestrator.py +13 -1
- zenml/orchestrators/output_utils.py +5 -1
- zenml/orchestrators/step_launcher.py +9 -13
- zenml/orchestrators/step_run_utils.py +8 -204
- zenml/orchestrators/utils.py +55 -27
- zenml/pipelines/build_utils.py +12 -0
- zenml/service_connectors/service_connector_utils.py +3 -9
- zenml/stack/stack_component.py +1 -1
- zenml/stack_deployments/aws_stack_deployment.py +22 -0
- zenml/utils/archivable.py +65 -36
- zenml/utils/code_utils.py +8 -4
- zenml/utils/docker_utils.py +9 -0
- zenml/zen_server/auth.py +9 -10
- zenml/zen_server/dashboard/assets/{404-NVXKFp-x.js → 404-Cqu3EDCm.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-CK0KJUen.js → @reactflow-D2Y7BWwz.js} +1 -1
- zenml/zen_server/dashboard/assets/{AlertDialogDropdownItem-DezXKmDf.js → AlertDialogDropdownItem-BHd71pVS.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-JzR8CEtw.js → CodeSnippet-DIonwetW.js} +1 -1
- zenml/zen_server/dashboard/assets/{CollapsibleCard-DQW_ktMO.js → CollapsibleCard-CDnC97pB.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-DL2kwkRd.js → Commands-BVEXKAOj.js} +1 -1
- zenml/zen_server/dashboard/assets/{ComponentBadge-D_g62Wv8.js → ComponentBadge-CrRvovox.js} +1 -1
- zenml/zen_server/dashboard/assets/{CopyButton-LNcWaa14.js → CopyButton-B6wGAhQv.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-DknpE5ej.js → CsvVizualization-CjcT7LMm.js} +5 -5
- zenml/zen_server/dashboard/assets/DeleteAlertDialog-D2ELtM2W.js +1 -0
- zenml/zen_server/dashboard/assets/{DialogItem-Bxf8FuAT.js → DialogItem-DXIMhBgU.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-DYflYyps.js → Error-B8uUfTpL.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-C7zyIQKZ.js → ExecutionStatus-ibAdY-dG.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-oYSGpLqd.js → Helpbox-BfAfhKHw.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-Cx4xGoXR.js → Infobox-M_SMOu96.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-DiGOWNKF.js → InlineAvatar-DBA0a0-a.js} +1 -1
- zenml/zen_server/dashboard/assets/{NestedCollapsible-DYbgyKxK.js → NestedCollapsible-DpgmEFKw.js} +1 -1
- zenml/zen_server/dashboard/assets/{Partials-03iZf8-N.js → Partials-D_ldD9if.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProBadge-D_EB8HNo.js → ProBadge-DQbfFotM.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProCta-DqNS4v3x.js → ProCta-Bcpb4rcY.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderIcon-Bki2aw8w.js → ProviderIcon-BZpgPigN.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderRadio-8f43sPD4.js → ProviderRadio-DWPnMuQ1.js} +1 -1
- zenml/zen_server/dashboard/assets/RunSelector-DgRGaAc6.js +1 -0
- zenml/zen_server/dashboard/assets/{RunsBody-07YEO7qI.js → RunsBody-KecfSkjY.js} +1 -1
- zenml/zen_server/dashboard/assets/{SearchField-lp1KgU4e.js → SearchField-n-ILHnaP.js} +1 -1
- zenml/zen_server/dashboard/assets/{SecretTooltip-CgnbyeOx.js → SecretTooltip-B8MrX5yu.js} +1 -1
- zenml/zen_server/dashboard/assets/{SetPassword-CpP418A2.js → SetPassword-B_IVq_wg.js} +1 -1
- zenml/zen_server/dashboard/assets/StackList-TWPBYnkF.js +1 -0
- zenml/zen_server/dashboard/assets/{Tabs-BktHkCJJ.js → Tabs-Rg857zmd.js} +1 -1
- zenml/zen_server/dashboard/assets/{Tick-BlMoIlJT.js → Tick-COg4A-xo.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-Sc0A0pP-.js → UpdatePasswordSchemas-C6Aj3hm6.js} +1 -1
- zenml/zen_server/dashboard/assets/{UsageReason-YYduL4fj.js → UsageReason-BTLbx7w4.js} +1 -1
- zenml/zen_server/dashboard/assets/{WizardFooter-dgmizSJC.js → WizardFooter-BCAj69Vj.js} +1 -1
- zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-D-c2G6lV.js → all-pipeline-runs-query-DMXkDrV2.js} +1 -1
- zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
- zenml/zen_server/dashboard/assets/{create-stack-DM_JPgef.js → create-stack-HfdbhLs4.js} +1 -1
- zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
- zenml/zen_server/dashboard/assets/delete-run-DZ4hIXff.js +1 -0
- zenml/zen_server/dashboard/assets/{form-schemas-K6FYKjwa.js → form-schemas-B0AVEd9b.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-BAkC7FXi.js → index-DPqSWjug.js} +1 -1
- zenml/zen_server/dashboard/assets/{index-CEV4Cvaf.js → index-DScjfBRb.js} +1 -1
- zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
- zenml/zen_server/dashboard/assets/{index-CCOPpudF.js → index-FO-p0GU7.js} +5 -5
- zenml/zen_server/dashboard/assets/{index-B1mVPYxf.js → index-I3bKUGUj.js} +1 -1
- zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
- zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-hf-lK87O.js → login-mutation-BQeo4wTY.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-BGirLjU-.js → not-found-gAJ5aDdR.js} +1 -1
- zenml/zen_server/dashboard/assets/page-9Y9-gig0.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DjRJCGb3.js → page-AUwiQ14W.js} +1 -1
- zenml/zen_server/dashboard/assets/page-B6XU7yYT.js +2 -0
- zenml/zen_server/dashboard/assets/{page-C00YAkaB.js → page-BKZYc2Zv.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CdMWnQak.js → page-BU9FG4sR.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D7S3aCbF.js → page-B_Apk3xg.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Djikxq_S.js → page-BdowiCbr.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Bg8OjTRe.js +1 -0
- zenml/zen_server/dashboard/assets/page-BxL4qD4_.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DakHVWXF.js → page-CWxT5K5J.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CXuQufSe.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DLC-bNBP.js → page-CcQr8CPP.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CD-DcWoy.js → page-Ce4Hrjnr.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CiYxgZP_.js +1 -0
- zenml/zen_server/dashboard/assets/page-Cldq1mpe.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BDigxVpo.js → page-D4wdonLm.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D6uU2ax4.js → page-D8ObrbH8.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DXSTpqRD.js → page-DFuAUGt4.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CbpvrsDL.js → page-DGazBpuP.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-COXXJj1k.js → page-DO1UcqPX.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DRYXdL5o.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Df-Fw0aq.js → page-DYEquBC2.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Dk32IeZm.js +1 -0
- zenml/zen_server/dashboard/assets/{page-yYC9OI-E.js → page-I3nKFGie.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-6m6yHHlE.js → page-M0w-n6vn.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Vcxara9U.js → page-R5dx3xGF.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BR68V0V1.js → page-bT5pOvcB.js} +1 -1
- zenml/zen_server/dashboard/assets/page-hUqK889I.js +6 -0
- zenml/zen_server/dashboard/assets/{page-CjGdWY13.js → page-h_Stveon.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-D01JhjQB.js → page-r8XK5vR7.js} +1 -1
- zenml/zen_server/dashboard/assets/page-u_-ZXBKb.js +1 -0
- zenml/zen_server/dashboard/assets/page-zaMqB_ao.js +1 -0
- zenml/zen_server/dashboard/assets/{persist-GjC8PZoC.js → persist-AppN1B0J.js} +1 -1
- zenml/zen_server/dashboard/assets/{persist-Coz7ZWvz.js → persist-DAUi_3za.js} +1 -1
- zenml/zen_server/dashboard/assets/service-BqqeXLEe.js +2 -0
- zenml/zen_server/dashboard/assets/{sharedSchema-CQb14VSr.js → sharedSchema-uXN9FLLk.js} +1 -1
- zenml/zen_server/dashboard/assets/{stack-detail-query-OPEW-cDJ.js → stack-detail-query-XfZBiBP2.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-LwuQfHYn.js → update-server-settings-mutation-BWmgVJwA.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-CkvKAnwF.js → url-BLwMbzES.js} +1 -1
- zenml/zen_server/dashboard/index.html +4 -4
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/rbac/rbac_sql_zen_store.py +173 -0
- zenml/zen_server/routers/auth_endpoints.py +22 -11
- zenml/zen_server/routers/steps_endpoints.py +7 -1
- zenml/zen_server/template_execution/utils.py +3 -1
- zenml/zen_server/utils.py +4 -3
- zenml/zen_stores/base_zen_store.py +10 -2
- zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
- zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
- zenml/zen_stores/rest_zen_store.py +76 -43
- zenml/zen_stores/schemas/model_schemas.py +42 -6
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
- zenml/zen_stores/schemas/pipeline_run_schemas.py +12 -6
- zenml/zen_stores/schemas/pipeline_schemas.py +5 -0
- zenml/zen_stores/schemas/step_run_schemas.py +8 -1
- zenml/zen_stores/sql_zen_store.py +332 -100
- {zenml_nightly-0.70.0.dev20241201.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/METADATA +5 -5
- {zenml_nightly-0.70.0.dev20241201.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/RECORD +179 -164
- zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +0 -1
- zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +0 -1
- zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +0 -1
- zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +0 -1
- zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +0 -1
- zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +0 -1
- zenml/zen_server/dashboard/assets/page-BU7huvKw.js +0 -6
- zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +0 -1
- zenml/zen_server/dashboard/assets/page-CwxrFarU.js +0 -1
- zenml/zen_server/dashboard/assets/page-DfbXf_8s.js +0 -1
- zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +0 -3
- zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +0 -1
- zenml/zen_server/dashboard/assets/page-Xynx4btY.js +0 -14
- zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +0 -1
- {zenml_nightly-0.70.0.dev20241201.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.70.0.dev20241201.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.70.0.dev20241201.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/entry_points.txt +0 -0
zenml/models/v2/base/scoped.py
CHANGED
@@ -23,6 +23,7 @@ from typing import (
|
|
23
23
|
Optional,
|
24
24
|
Type,
|
25
25
|
TypeVar,
|
26
|
+
Union,
|
26
27
|
)
|
27
28
|
from uuid import UUID
|
28
29
|
|
@@ -151,16 +152,32 @@ class UserScopedFilter(BaseFilter):
|
|
151
152
|
|
152
153
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
153
154
|
*BaseFilter.FILTER_EXCLUDE_FIELDS,
|
155
|
+
"user",
|
154
156
|
"scope_user",
|
155
157
|
]
|
156
158
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
157
159
|
*BaseFilter.CLI_EXCLUDE_FIELDS,
|
160
|
+
"user_id",
|
158
161
|
"scope_user",
|
159
162
|
]
|
163
|
+
CUSTOM_SORTING_OPTIONS: ClassVar[List[str]] = [
|
164
|
+
*BaseFilter.CUSTOM_SORTING_OPTIONS,
|
165
|
+
"user",
|
166
|
+
]
|
167
|
+
|
160
168
|
scope_user: Optional[UUID] = Field(
|
161
169
|
default=None,
|
162
170
|
description="The user to scope this query to.",
|
163
171
|
)
|
172
|
+
user_id: Optional[Union[UUID, str]] = Field(
|
173
|
+
default=None,
|
174
|
+
description="UUID of the user that created the entity.",
|
175
|
+
union_mode="left_to_right",
|
176
|
+
)
|
177
|
+
user: Optional[Union[UUID, str]] = Field(
|
178
|
+
default=None,
|
179
|
+
description="Name/ID of the user that created the entity.",
|
180
|
+
)
|
164
181
|
|
165
182
|
def set_scope_user(self, user_id: UUID) -> None:
|
166
183
|
"""Set the user that is performing the filtering to scope the response.
|
@@ -170,6 +187,73 @@ class UserScopedFilter(BaseFilter):
|
|
170
187
|
"""
|
171
188
|
self.scope_user = user_id
|
172
189
|
|
190
|
+
def get_custom_filters(
|
191
|
+
self, table: Type["AnySchema"]
|
192
|
+
) -> List["ColumnElement[bool]"]:
|
193
|
+
"""Get custom filters.
|
194
|
+
|
195
|
+
Args:
|
196
|
+
table: The query table.
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
A list of custom filters.
|
200
|
+
"""
|
201
|
+
custom_filters = super().get_custom_filters(table)
|
202
|
+
|
203
|
+
from sqlmodel import and_
|
204
|
+
|
205
|
+
from zenml.zen_stores.schemas import UserSchema
|
206
|
+
|
207
|
+
if self.user:
|
208
|
+
user_filter = and_(
|
209
|
+
getattr(table, "user_id") == UserSchema.id,
|
210
|
+
self.generate_name_or_id_query_conditions(
|
211
|
+
value=self.user,
|
212
|
+
table=UserSchema,
|
213
|
+
additional_columns=["full_name"],
|
214
|
+
),
|
215
|
+
)
|
216
|
+
custom_filters.append(user_filter)
|
217
|
+
|
218
|
+
return custom_filters
|
219
|
+
|
220
|
+
def apply_sorting(
|
221
|
+
self,
|
222
|
+
query: AnyQuery,
|
223
|
+
table: Type["AnySchema"],
|
224
|
+
) -> AnyQuery:
|
225
|
+
"""Apply sorting to the query.
|
226
|
+
|
227
|
+
Args:
|
228
|
+
query: The query to which to apply the sorting.
|
229
|
+
table: The query table.
|
230
|
+
|
231
|
+
Returns:
|
232
|
+
The query with sorting applied.
|
233
|
+
"""
|
234
|
+
from sqlmodel import asc, desc
|
235
|
+
|
236
|
+
from zenml.enums import SorterOps
|
237
|
+
from zenml.zen_stores.schemas import UserSchema
|
238
|
+
|
239
|
+
sort_by, operand = self.sorting_params
|
240
|
+
|
241
|
+
if sort_by == "user":
|
242
|
+
column = UserSchema.name
|
243
|
+
|
244
|
+
query = query.join(
|
245
|
+
UserSchema, getattr(table, "user_id") == UserSchema.id
|
246
|
+
)
|
247
|
+
|
248
|
+
if operand == SorterOps.ASCENDING:
|
249
|
+
query = query.order_by(asc(column))
|
250
|
+
else:
|
251
|
+
query = query.order_by(desc(column))
|
252
|
+
|
253
|
+
return query
|
254
|
+
|
255
|
+
return super().apply_sorting(query=query, table=table)
|
256
|
+
|
173
257
|
def apply_filter(
|
174
258
|
self,
|
175
259
|
query: AnyQuery,
|
@@ -240,21 +324,37 @@ class WorkspaceScopedResponse(
|
|
240
324
|
return self.get_metadata().workspace
|
241
325
|
|
242
326
|
|
243
|
-
class WorkspaceScopedFilter(
|
327
|
+
class WorkspaceScopedFilter(UserScopedFilter):
|
244
328
|
"""Model to enable advanced scoping with workspace."""
|
245
329
|
|
246
330
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
247
|
-
*
|
331
|
+
*UserScopedFilter.FILTER_EXCLUDE_FIELDS,
|
332
|
+
"workspace",
|
248
333
|
"scope_workspace",
|
249
334
|
]
|
250
335
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
251
|
-
*
|
336
|
+
*UserScopedFilter.CLI_EXCLUDE_FIELDS,
|
337
|
+
"workspace_id",
|
338
|
+
"workspace",
|
252
339
|
"scope_workspace",
|
253
340
|
]
|
341
|
+
CUSTOM_SORTING_OPTIONS: ClassVar[List[str]] = [
|
342
|
+
*UserScopedFilter.CUSTOM_SORTING_OPTIONS,
|
343
|
+
"workspace",
|
344
|
+
]
|
254
345
|
scope_workspace: Optional[UUID] = Field(
|
255
346
|
default=None,
|
256
347
|
description="The workspace to scope this query to.",
|
257
348
|
)
|
349
|
+
workspace_id: Optional[Union[UUID, str]] = Field(
|
350
|
+
default=None,
|
351
|
+
description="UUID of the workspace that this entity belongs to.",
|
352
|
+
union_mode="left_to_right",
|
353
|
+
)
|
354
|
+
workspace: Optional[Union[UUID, str]] = Field(
|
355
|
+
default=None,
|
356
|
+
description="Name/ID of the workspace that this entity belongs to.",
|
357
|
+
)
|
258
358
|
|
259
359
|
def set_scope_workspace(self, workspace_id: UUID) -> None:
|
260
360
|
"""Set the workspace to scope this response.
|
@@ -264,6 +364,35 @@ class WorkspaceScopedFilter(BaseFilter):
|
|
264
364
|
"""
|
265
365
|
self.scope_workspace = workspace_id
|
266
366
|
|
367
|
+
def get_custom_filters(
|
368
|
+
self, table: Type["AnySchema"]
|
369
|
+
) -> List["ColumnElement[bool]"]:
|
370
|
+
"""Get custom filters.
|
371
|
+
|
372
|
+
Args:
|
373
|
+
table: The query table.
|
374
|
+
|
375
|
+
Returns:
|
376
|
+
A list of custom filters.
|
377
|
+
"""
|
378
|
+
custom_filters = super().get_custom_filters(table)
|
379
|
+
|
380
|
+
from sqlmodel import and_
|
381
|
+
|
382
|
+
from zenml.zen_stores.schemas import WorkspaceSchema
|
383
|
+
|
384
|
+
if self.workspace:
|
385
|
+
workspace_filter = and_(
|
386
|
+
getattr(table, "workspace_id") == WorkspaceSchema.id,
|
387
|
+
self.generate_name_or_id_query_conditions(
|
388
|
+
value=self.workspace,
|
389
|
+
table=WorkspaceSchema,
|
390
|
+
),
|
391
|
+
)
|
392
|
+
custom_filters.append(workspace_filter)
|
393
|
+
|
394
|
+
return custom_filters
|
395
|
+
|
267
396
|
def apply_filter(
|
268
397
|
self,
|
269
398
|
query: AnyQuery,
|
@@ -291,6 +420,44 @@ class WorkspaceScopedFilter(BaseFilter):
|
|
291
420
|
|
292
421
|
return query
|
293
422
|
|
423
|
+
def apply_sorting(
|
424
|
+
self,
|
425
|
+
query: AnyQuery,
|
426
|
+
table: Type["AnySchema"],
|
427
|
+
) -> AnyQuery:
|
428
|
+
"""Apply sorting to the query.
|
429
|
+
|
430
|
+
Args:
|
431
|
+
query: The query to which to apply the sorting.
|
432
|
+
table: The query table.
|
433
|
+
|
434
|
+
Returns:
|
435
|
+
The query with sorting applied.
|
436
|
+
"""
|
437
|
+
from sqlmodel import asc, desc
|
438
|
+
|
439
|
+
from zenml.enums import SorterOps
|
440
|
+
from zenml.zen_stores.schemas import WorkspaceSchema
|
441
|
+
|
442
|
+
sort_by, operand = self.sorting_params
|
443
|
+
|
444
|
+
if sort_by == "workspace":
|
445
|
+
column = WorkspaceSchema.name
|
446
|
+
|
447
|
+
query = query.join(
|
448
|
+
WorkspaceSchema,
|
449
|
+
getattr(table, "workspace_id") == WorkspaceSchema.id,
|
450
|
+
)
|
451
|
+
|
452
|
+
if operand == SorterOps.ASCENDING:
|
453
|
+
query = query.order_by(asc(column))
|
454
|
+
else:
|
455
|
+
query = query.order_by(desc(column))
|
456
|
+
|
457
|
+
return query
|
458
|
+
|
459
|
+
return super().apply_sorting(query=query, table=table)
|
460
|
+
|
294
461
|
|
295
462
|
class WorkspaceScopedTaggableFilter(WorkspaceScopedFilter):
|
296
463
|
"""Model to enable advanced scoping with workspace and tagging."""
|
@@ -304,6 +471,11 @@ class WorkspaceScopedTaggableFilter(WorkspaceScopedFilter):
|
|
304
471
|
"tag",
|
305
472
|
]
|
306
473
|
|
474
|
+
CUSTOM_SORTING_OPTIONS: ClassVar[List[str]] = [
|
475
|
+
*WorkspaceScopedFilter.CUSTOM_SORTING_OPTIONS,
|
476
|
+
"tag",
|
477
|
+
]
|
478
|
+
|
307
479
|
def apply_filter(
|
308
480
|
self,
|
309
481
|
query: AnyQuery,
|
@@ -330,15 +502,20 @@ class WorkspaceScopedTaggableFilter(WorkspaceScopedFilter):
|
|
330
502
|
|
331
503
|
return query
|
332
504
|
|
333
|
-
def get_custom_filters(
|
505
|
+
def get_custom_filters(
|
506
|
+
self, table: Type["AnySchema"]
|
507
|
+
) -> List["ColumnElement[bool]"]:
|
334
508
|
"""Get custom tag filters.
|
335
509
|
|
510
|
+
Args:
|
511
|
+
table: The query table.
|
512
|
+
|
336
513
|
Returns:
|
337
514
|
A list of custom filters.
|
338
515
|
"""
|
339
516
|
from zenml.zen_stores.schemas import TagSchema
|
340
517
|
|
341
|
-
custom_filters = super().get_custom_filters()
|
518
|
+
custom_filters = super().get_custom_filters(table)
|
342
519
|
if self.tag:
|
343
520
|
custom_filters.append(
|
344
521
|
self.generate_custom_query_conditions_for_column(
|
@@ -347,3 +524,79 @@ class WorkspaceScopedTaggableFilter(WorkspaceScopedFilter):
|
|
347
524
|
)
|
348
525
|
|
349
526
|
return custom_filters
|
527
|
+
|
528
|
+
def apply_sorting(
|
529
|
+
self,
|
530
|
+
query: AnyQuery,
|
531
|
+
table: Type["AnySchema"],
|
532
|
+
) -> AnyQuery:
|
533
|
+
"""Apply sorting to the query.
|
534
|
+
|
535
|
+
Args:
|
536
|
+
query: The query to which to apply the sorting.
|
537
|
+
table: The query table.
|
538
|
+
|
539
|
+
Returns:
|
540
|
+
The query with sorting applied.
|
541
|
+
"""
|
542
|
+
sort_by, operand = self.sorting_params
|
543
|
+
|
544
|
+
if sort_by == "tag":
|
545
|
+
from sqlmodel import and_, asc, desc, func
|
546
|
+
|
547
|
+
from zenml.enums import SorterOps, TaggableResourceTypes
|
548
|
+
from zenml.zen_stores.schemas import (
|
549
|
+
ArtifactSchema,
|
550
|
+
ArtifactVersionSchema,
|
551
|
+
ModelSchema,
|
552
|
+
ModelVersionSchema,
|
553
|
+
PipelineRunSchema,
|
554
|
+
PipelineSchema,
|
555
|
+
RunTemplateSchema,
|
556
|
+
TagResourceSchema,
|
557
|
+
TagSchema,
|
558
|
+
)
|
559
|
+
|
560
|
+
resource_type_mapping = {
|
561
|
+
ArtifactSchema: TaggableResourceTypes.ARTIFACT,
|
562
|
+
ArtifactVersionSchema: TaggableResourceTypes.ARTIFACT_VERSION,
|
563
|
+
ModelSchema: TaggableResourceTypes.MODEL,
|
564
|
+
ModelVersionSchema: TaggableResourceTypes.MODEL_VERSION,
|
565
|
+
PipelineSchema: TaggableResourceTypes.PIPELINE,
|
566
|
+
PipelineRunSchema: TaggableResourceTypes.PIPELINE_RUN,
|
567
|
+
RunTemplateSchema: TaggableResourceTypes.RUN_TEMPLATE,
|
568
|
+
}
|
569
|
+
|
570
|
+
query = (
|
571
|
+
query.outerjoin(
|
572
|
+
TagResourceSchema,
|
573
|
+
and_(
|
574
|
+
table.id == TagResourceSchema.resource_id,
|
575
|
+
TagResourceSchema.resource_type
|
576
|
+
== resource_type_mapping[table],
|
577
|
+
),
|
578
|
+
)
|
579
|
+
.outerjoin(TagSchema, TagResourceSchema.tag_id == TagSchema.id)
|
580
|
+
.group_by(table.id)
|
581
|
+
)
|
582
|
+
|
583
|
+
if operand == SorterOps.ASCENDING:
|
584
|
+
query = query.order_by(
|
585
|
+
asc(
|
586
|
+
func.group_concat(TagSchema.name, ",").label(
|
587
|
+
"tags_list"
|
588
|
+
)
|
589
|
+
)
|
590
|
+
)
|
591
|
+
else:
|
592
|
+
query = query.order_by(
|
593
|
+
desc(
|
594
|
+
func.group_concat(TagSchema.name, ",").label(
|
595
|
+
"tags_list"
|
596
|
+
)
|
597
|
+
)
|
598
|
+
)
|
599
|
+
|
600
|
+
return query
|
601
|
+
|
602
|
+
return super().apply_sorting(query=query, table=table)
|
@@ -20,6 +20,8 @@ from typing import (
|
|
20
20
|
Dict,
|
21
21
|
List,
|
22
22
|
Optional,
|
23
|
+
Type,
|
24
|
+
TypeVar,
|
23
25
|
Union,
|
24
26
|
)
|
25
27
|
from uuid import UUID
|
@@ -58,6 +60,10 @@ if TYPE_CHECKING:
|
|
58
60
|
)
|
59
61
|
from zenml.models.v2.core.pipeline_run import PipelineRunResponse
|
60
62
|
from zenml.models.v2.core.step_run import StepRunResponse
|
63
|
+
from zenml.zen_stores.schemas.base_schemas import BaseSchema
|
64
|
+
|
65
|
+
AnySchema = TypeVar("AnySchema", bound=BaseSchema)
|
66
|
+
|
61
67
|
|
62
68
|
logger = get_logger(__name__)
|
63
69
|
|
@@ -471,7 +477,6 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
471
477
|
"name",
|
472
478
|
"only_unused",
|
473
479
|
"has_custom_name",
|
474
|
-
"user",
|
475
480
|
"model",
|
476
481
|
"pipeline_run",
|
477
482
|
"model_version_id",
|
@@ -516,19 +521,10 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
516
521
|
description="Artifact store for this artifact",
|
517
522
|
union_mode="left_to_right",
|
518
523
|
)
|
519
|
-
workspace_id: Optional[Union[UUID, str]] = Field(
|
520
|
-
default=None,
|
521
|
-
description="Workspace for this artifact",
|
522
|
-
union_mode="left_to_right",
|
523
|
-
)
|
524
|
-
user_id: Optional[Union[UUID, str]] = Field(
|
525
|
-
default=None,
|
526
|
-
description="User that produced this artifact",
|
527
|
-
union_mode="left_to_right",
|
528
|
-
)
|
529
524
|
model_version_id: Optional[Union[UUID, str]] = Field(
|
530
525
|
default=None,
|
531
|
-
description="ID of the model version that is associated with this
|
526
|
+
description="ID of the model version that is associated with this "
|
527
|
+
"artifact version.",
|
532
528
|
union_mode="left_to_right",
|
533
529
|
)
|
534
530
|
only_unused: Optional[bool] = Field(
|
@@ -559,13 +555,18 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
559
555
|
|
560
556
|
model_config = ConfigDict(protected_namespaces=())
|
561
557
|
|
562
|
-
def get_custom_filters(
|
558
|
+
def get_custom_filters(
|
559
|
+
self, table: Type["AnySchema"]
|
560
|
+
) -> List[Union["ColumnElement[bool]"]]:
|
563
561
|
"""Get custom filters.
|
564
562
|
|
563
|
+
Args:
|
564
|
+
table: The query table.
|
565
|
+
|
565
566
|
Returns:
|
566
567
|
A list of custom filters.
|
567
568
|
"""
|
568
|
-
custom_filters = super().get_custom_filters()
|
569
|
+
custom_filters = super().get_custom_filters(table)
|
569
570
|
|
570
571
|
from sqlmodel import and_, or_, select
|
571
572
|
|
@@ -581,7 +582,6 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
581
582
|
StepRunInputArtifactSchema,
|
582
583
|
StepRunOutputArtifactSchema,
|
583
584
|
StepRunSchema,
|
584
|
-
UserSchema,
|
585
585
|
)
|
586
586
|
|
587
587
|
if self.name:
|
@@ -629,17 +629,6 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
|
|
629
629
|
)
|
630
630
|
custom_filters.append(custom_name_filter)
|
631
631
|
|
632
|
-
if self.user:
|
633
|
-
user_filter = and_(
|
634
|
-
ArtifactVersionSchema.user_id == UserSchema.id,
|
635
|
-
self.generate_name_or_id_query_conditions(
|
636
|
-
value=self.user,
|
637
|
-
table=UserSchema,
|
638
|
-
additional_columns=["full_name"],
|
639
|
-
),
|
640
|
-
)
|
641
|
-
custom_filters.append(user_filter)
|
642
|
-
|
643
632
|
if self.model:
|
644
633
|
model_filter = and_(
|
645
634
|
ArtifactVersionSchema.id
|
@@ -13,8 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing code repositories."""
|
15
15
|
|
16
|
-
from typing import Any, Dict, Optional
|
17
|
-
from uuid import UUID
|
16
|
+
from typing import Any, Dict, Optional
|
18
17
|
|
19
18
|
from pydantic import Field
|
20
19
|
|
@@ -189,13 +188,3 @@ class CodeRepositoryFilter(WorkspaceScopedFilter):
|
|
189
188
|
description="Name of the code repository.",
|
190
189
|
default=None,
|
191
190
|
)
|
192
|
-
workspace_id: Optional[Union[UUID, str]] = Field(
|
193
|
-
description="Workspace of the code repository.",
|
194
|
-
default=None,
|
195
|
-
union_mode="left_to_right",
|
196
|
-
)
|
197
|
-
user_id: Optional[Union[UUID, str]] = Field(
|
198
|
-
description="User that created the code repository.",
|
199
|
-
default=None,
|
200
|
-
union_mode="left_to_right",
|
201
|
-
)
|
@@ -21,6 +21,7 @@ from typing import (
|
|
21
21
|
List,
|
22
22
|
Optional,
|
23
23
|
Type,
|
24
|
+
TypeVar,
|
24
25
|
Union,
|
25
26
|
)
|
26
27
|
from uuid import UUID
|
@@ -42,9 +43,11 @@ from zenml.utils import secret_utils
|
|
42
43
|
|
43
44
|
if TYPE_CHECKING:
|
44
45
|
from sqlalchemy.sql.elements import ColumnElement
|
45
|
-
from sqlmodel import SQLModel
|
46
46
|
|
47
47
|
from zenml.models import FlavorResponse, ServiceConnectorResponse
|
48
|
+
from zenml.zen_stores.schemas.base_schemas import BaseSchema
|
49
|
+
|
50
|
+
AnySchema = TypeVar("AnySchema", bound=BaseSchema)
|
48
51
|
|
49
52
|
# ------------------ Base Model ------------------
|
50
53
|
|
@@ -356,7 +359,6 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
356
359
|
*WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
|
357
360
|
"scope_type",
|
358
361
|
"stack_id",
|
359
|
-
"user",
|
360
362
|
]
|
361
363
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
362
364
|
*WorkspaceScopedFilter.CLI_EXCLUDE_FIELDS,
|
@@ -366,7 +368,6 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
366
368
|
default=None,
|
367
369
|
description="The type to scope this query to.",
|
368
370
|
)
|
369
|
-
|
370
371
|
name: Optional[str] = Field(
|
371
372
|
default=None,
|
372
373
|
description="Name of the stack component",
|
@@ -379,16 +380,6 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
379
380
|
default=None,
|
380
381
|
description="Type of the stack component",
|
381
382
|
)
|
382
|
-
workspace_id: Optional[Union[UUID, str]] = Field(
|
383
|
-
default=None,
|
384
|
-
description="Workspace of the stack component",
|
385
|
-
union_mode="left_to_right",
|
386
|
-
)
|
387
|
-
user_id: Optional[Union[UUID, str]] = Field(
|
388
|
-
default=None,
|
389
|
-
description="User of the stack component",
|
390
|
-
union_mode="left_to_right",
|
391
|
-
)
|
392
383
|
connector_id: Optional[Union[UUID, str]] = Field(
|
393
384
|
default=None,
|
394
385
|
description="Connector linked to the stack component",
|
@@ -399,10 +390,6 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
399
390
|
description="Stack of the stack component",
|
400
391
|
union_mode="left_to_right",
|
401
392
|
)
|
402
|
-
user: Optional[Union[UUID, str]] = Field(
|
403
|
-
default=None,
|
404
|
-
description="Name/ID of the user that created the component.",
|
405
|
-
)
|
406
393
|
|
407
394
|
def set_scope_type(self, component_type: str) -> None:
|
408
395
|
"""Set the type of component on which to perform the filtering to scope the response.
|
@@ -413,7 +400,7 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
413
400
|
self.scope_type = component_type
|
414
401
|
|
415
402
|
def generate_filter(
|
416
|
-
self, table: Type["
|
403
|
+
self, table: Type["AnySchema"]
|
417
404
|
) -> Union["ColumnElement[bool]"]:
|
418
405
|
"""Generate the filter for the query.
|
419
406
|
|
@@ -449,31 +436,3 @@ class ComponentFilter(WorkspaceScopedFilter):
|
|
449
436
|
base_filter = operator(base_filter, stack_filter)
|
450
437
|
|
451
438
|
return base_filter
|
452
|
-
|
453
|
-
def get_custom_filters(self) -> List["ColumnElement[bool]"]:
|
454
|
-
"""Get custom filters.
|
455
|
-
|
456
|
-
Returns:
|
457
|
-
A list of custom filters.
|
458
|
-
"""
|
459
|
-
from sqlmodel import and_
|
460
|
-
|
461
|
-
from zenml.zen_stores.schemas import (
|
462
|
-
StackComponentSchema,
|
463
|
-
UserSchema,
|
464
|
-
)
|
465
|
-
|
466
|
-
custom_filters = super().get_custom_filters()
|
467
|
-
|
468
|
-
if self.user:
|
469
|
-
user_filter = and_(
|
470
|
-
StackComponentSchema.user_id == UserSchema.id,
|
471
|
-
self.generate_name_or_id_query_conditions(
|
472
|
-
value=self.user,
|
473
|
-
table=UserSchema,
|
474
|
-
additional_columns=["full_name"],
|
475
|
-
),
|
476
|
-
)
|
477
|
-
custom_filters.append(user_filter)
|
478
|
-
|
479
|
-
return custom_filters
|
zenml/models/v2/core/flavor.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing flavors."""
|
15
15
|
|
16
|
-
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional
|
16
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from pydantic import Field
|
@@ -428,13 +428,3 @@ class FlavorFilter(WorkspaceScopedFilter):
|
|
428
428
|
default=None,
|
429
429
|
description="Integration associated with the flavor",
|
430
430
|
)
|
431
|
-
workspace_id: Optional[Union[UUID, str]] = Field(
|
432
|
-
default=None,
|
433
|
-
description="Workspace of the stack",
|
434
|
-
union_mode="left_to_right",
|
435
|
-
)
|
436
|
-
user_id: Optional[Union[UUID, str]] = Field(
|
437
|
-
default=None,
|
438
|
-
description="User of the stack",
|
439
|
-
union_mode="left_to_right",
|
440
|
-
)
|
zenml/models/v2/core/model.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing models."""
|
15
15
|
|
16
|
-
from typing import TYPE_CHECKING,
|
16
|
+
from typing import TYPE_CHECKING, List, Optional
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from pydantic import BaseModel, Field
|
@@ -30,8 +30,6 @@ from zenml.models.v2.base.scoped import (
|
|
30
30
|
from zenml.utils.pagination_utils import depaginate
|
31
31
|
|
32
32
|
if TYPE_CHECKING:
|
33
|
-
from sqlalchemy.sql.elements import ColumnElement
|
34
|
-
|
35
33
|
from zenml.model.model import Model
|
36
34
|
from zenml.models.v2.core.tag import TagResponse
|
37
35
|
|
@@ -318,61 +316,7 @@ class ModelResponse(
|
|
318
316
|
class ModelFilter(WorkspaceScopedTaggableFilter):
|
319
317
|
"""Model to enable advanced filtering of all Workspaces."""
|
320
318
|
|
321
|
-
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
322
|
-
*WorkspaceScopedTaggableFilter.CLI_EXCLUDE_FIELDS,
|
323
|
-
"workspace_id",
|
324
|
-
"user_id",
|
325
|
-
]
|
326
|
-
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
327
|
-
*WorkspaceScopedTaggableFilter.FILTER_EXCLUDE_FIELDS,
|
328
|
-
"user",
|
329
|
-
]
|
330
|
-
|
331
319
|
name: Optional[str] = Field(
|
332
320
|
default=None,
|
333
321
|
description="Name of the Model",
|
334
322
|
)
|
335
|
-
workspace_id: Optional[Union[UUID, str]] = Field(
|
336
|
-
default=None,
|
337
|
-
description="Workspace of the Model",
|
338
|
-
union_mode="left_to_right",
|
339
|
-
)
|
340
|
-
user_id: Optional[Union[UUID, str]] = Field(
|
341
|
-
default=None,
|
342
|
-
description="User of the Model",
|
343
|
-
union_mode="left_to_right",
|
344
|
-
)
|
345
|
-
user: Optional[Union[UUID, str]] = Field(
|
346
|
-
default=None,
|
347
|
-
description="Name/ID of the user that created the model.",
|
348
|
-
)
|
349
|
-
|
350
|
-
def get_custom_filters(
|
351
|
-
self,
|
352
|
-
) -> List["ColumnElement[bool]"]:
|
353
|
-
"""Get custom filters.
|
354
|
-
|
355
|
-
Returns:
|
356
|
-
A list of custom filters.
|
357
|
-
"""
|
358
|
-
custom_filters = super().get_custom_filters()
|
359
|
-
|
360
|
-
from sqlmodel import and_
|
361
|
-
|
362
|
-
from zenml.zen_stores.schemas import (
|
363
|
-
ModelSchema,
|
364
|
-
UserSchema,
|
365
|
-
)
|
366
|
-
|
367
|
-
if self.user:
|
368
|
-
user_filter = and_(
|
369
|
-
ModelSchema.user_id == UserSchema.id,
|
370
|
-
self.generate_name_or_id_query_conditions(
|
371
|
-
value=self.user,
|
372
|
-
table=UserSchema,
|
373
|
-
additional_columns=["full_name"],
|
374
|
-
),
|
375
|
-
)
|
376
|
-
custom_filters.append(user_filter)
|
377
|
-
|
378
|
-
return custom_filters
|