zenml-nightly 0.70.0.dev20241125__py3-none-any.whl → 0.71.0.dev20241220__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. README.md +4 -4
  2. RELEASE_NOTES.md +112 -0
  3. zenml/VERSION +1 -1
  4. zenml/artifact_stores/base_artifact_store.py +2 -2
  5. zenml/artifacts/artifact_config.py +15 -6
  6. zenml/artifacts/utils.py +59 -32
  7. zenml/cli/__init__.py +22 -4
  8. zenml/cli/base.py +5 -5
  9. zenml/cli/login.py +26 -0
  10. zenml/cli/pipeline.py +111 -62
  11. zenml/cli/server.py +20 -20
  12. zenml/cli/service_connectors.py +3 -3
  13. zenml/cli/stack.py +0 -3
  14. zenml/cli/stack_components.py +0 -1
  15. zenml/cli/utils.py +0 -5
  16. zenml/client.py +62 -20
  17. zenml/config/compiler.py +12 -3
  18. zenml/config/pipeline_configurations.py +20 -0
  19. zenml/config/pipeline_run_configuration.py +1 -0
  20. zenml/config/secret_reference_mixin.py +1 -1
  21. zenml/config/server_config.py +4 -0
  22. zenml/config/step_configurations.py +21 -0
  23. zenml/constants.py +10 -0
  24. zenml/enums.py +1 -0
  25. zenml/image_builders/base_image_builder.py +5 -2
  26. zenml/image_builders/build_context.py +7 -16
  27. zenml/image_builders/local_image_builder.py +13 -3
  28. zenml/integrations/__init__.py +1 -0
  29. zenml/integrations/aws/__init__.py +3 -0
  30. zenml/integrations/aws/flavors/__init__.py +6 -0
  31. zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
  32. zenml/integrations/aws/image_builders/__init__.py +20 -0
  33. zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
  34. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +14 -6
  35. zenml/integrations/constants.py +1 -0
  36. zenml/integrations/feast/__init__.py +1 -1
  37. zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -9
  38. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
  39. zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +2 -1
  40. zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +11 -0
  41. zenml/integrations/kubernetes/orchestrators/kube_utils.py +46 -2
  42. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +13 -2
  43. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +3 -1
  44. zenml/integrations/kubernetes/orchestrators/manifest_utils.py +3 -2
  45. zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +3 -2
  46. zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +11 -0
  47. zenml/integrations/modal/__init__.py +46 -0
  48. zenml/integrations/modal/flavors/__init__.py +26 -0
  49. zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
  50. zenml/integrations/modal/step_operators/__init__.py +22 -0
  51. zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
  52. zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
  53. zenml/integrations/neptune/experiment_trackers/run_state.py +69 -53
  54. zenml/integrations/registry.py +2 -2
  55. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +12 -0
  56. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +13 -5
  57. zenml/io/filesystem.py +2 -2
  58. zenml/io/local_filesystem.py +3 -3
  59. zenml/materializers/built_in_materializer.py +18 -1
  60. zenml/materializers/structured_string_materializer.py +8 -3
  61. zenml/model/model.py +23 -101
  62. zenml/model/utils.py +21 -17
  63. zenml/models/__init__.py +6 -0
  64. zenml/models/v2/base/filter.py +26 -30
  65. zenml/models/v2/base/scoped.py +258 -5
  66. zenml/models/v2/core/artifact_version.py +21 -29
  67. zenml/models/v2/core/code_repository.py +1 -12
  68. zenml/models/v2/core/component.py +5 -68
  69. zenml/models/v2/core/flavor.py +1 -11
  70. zenml/models/v2/core/model.py +1 -57
  71. zenml/models/v2/core/model_version.py +11 -36
  72. zenml/models/v2/core/model_version_artifact.py +11 -3
  73. zenml/models/v2/core/model_version_pipeline_run.py +14 -3
  74. zenml/models/v2/core/pipeline.py +47 -55
  75. zenml/models/v2/core/pipeline_build.py +67 -12
  76. zenml/models/v2/core/pipeline_deployment.py +0 -10
  77. zenml/models/v2/core/pipeline_run.py +110 -32
  78. zenml/models/v2/core/run_metadata.py +30 -9
  79. zenml/models/v2/core/run_template.py +21 -29
  80. zenml/models/v2/core/schedule.py +0 -10
  81. zenml/models/v2/core/secret.py +0 -14
  82. zenml/models/v2/core/service.py +9 -16
  83. zenml/models/v2/core/service_connector.py +0 -11
  84. zenml/models/v2/core/stack.py +21 -30
  85. zenml/models/v2/core/step_run.py +24 -18
  86. zenml/models/v2/core/trigger.py +19 -3
  87. zenml/models/v2/misc/run_metadata.py +38 -0
  88. zenml/orchestrators/base_orchestrator.py +13 -1
  89. zenml/orchestrators/input_utils.py +19 -6
  90. zenml/orchestrators/output_utils.py +5 -1
  91. zenml/orchestrators/publish_utils.py +12 -5
  92. zenml/orchestrators/step_launcher.py +16 -16
  93. zenml/orchestrators/step_run_utils.py +18 -197
  94. zenml/orchestrators/step_runner.py +40 -3
  95. zenml/orchestrators/utils.py +79 -50
  96. zenml/pipelines/build_utils.py +12 -0
  97. zenml/pipelines/pipeline_decorator.py +4 -0
  98. zenml/pipelines/pipeline_definition.py +26 -8
  99. zenml/pipelines/run_utils.py +9 -5
  100. zenml/service_connectors/service_connector_utils.py +3 -9
  101. zenml/stack/stack_component.py +1 -1
  102. zenml/stack_deployments/aws_stack_deployment.py +22 -0
  103. zenml/steps/base_step.py +11 -1
  104. zenml/steps/entrypoint_function_utils.py +7 -3
  105. zenml/steps/step_decorator.py +4 -0
  106. zenml/steps/utils.py +23 -7
  107. zenml/types.py +4 -0
  108. zenml/utils/archivable.py +65 -36
  109. zenml/utils/code_utils.py +8 -4
  110. zenml/utils/docker_utils.py +9 -0
  111. zenml/utils/metadata_utils.py +186 -153
  112. zenml/utils/string_utils.py +41 -16
  113. zenml/utils/visualization_utils.py +4 -1
  114. zenml/zen_server/auth.py +9 -10
  115. zenml/zen_server/cloud_utils.py +3 -1
  116. zenml/zen_server/dashboard/assets/{404-NVXKFp-x.js → 404-Cqu3EDCm.js} +1 -1
  117. zenml/zen_server/dashboard/assets/{@reactflow-CK0KJUen.js → @reactflow-D2Y7BWwz.js} +1 -1
  118. zenml/zen_server/dashboard/assets/{AlertDialogDropdownItem-DezXKmDf.js → AlertDialogDropdownItem-BHd71pVS.js} +1 -1
  119. zenml/zen_server/dashboard/assets/{CodeSnippet-JzR8CEtw.js → CodeSnippet-DIonwetW.js} +1 -1
  120. zenml/zen_server/dashboard/assets/{CollapsibleCard-DQW_ktMO.js → CollapsibleCard-CDnC97pB.js} +1 -1
  121. zenml/zen_server/dashboard/assets/{Commands-DL2kwkRd.js → Commands-BVEXKAOj.js} +1 -1
  122. zenml/zen_server/dashboard/assets/{ComponentBadge-D_g62Wv8.js → ComponentBadge-CrRvovox.js} +1 -1
  123. zenml/zen_server/dashboard/assets/{CopyButton-LNcWaa14.js → CopyButton-B6wGAhQv.js} +1 -1
  124. zenml/zen_server/dashboard/assets/{CsvVizualization-DknpE5ej.js → CsvVizualization-CjcT7LMm.js} +5 -5
  125. zenml/zen_server/dashboard/assets/DeleteAlertDialog-D2ELtM2W.js +1 -0
  126. zenml/zen_server/dashboard/assets/{DialogItem-Bxf8FuAT.js → DialogItem-DXIMhBgU.js} +1 -1
  127. zenml/zen_server/dashboard/assets/{Error-DYflYyps.js → Error-B8uUfTpL.js} +1 -1
  128. zenml/zen_server/dashboard/assets/{ExecutionStatus-C7zyIQKZ.js → ExecutionStatus-ibAdY-dG.js} +1 -1
  129. zenml/zen_server/dashboard/assets/{Helpbox-oYSGpLqd.js → Helpbox-BfAfhKHw.js} +1 -1
  130. zenml/zen_server/dashboard/assets/{Infobox-Cx4xGoXR.js → Infobox-M_SMOu96.js} +1 -1
  131. zenml/zen_server/dashboard/assets/{InlineAvatar-DiGOWNKF.js → InlineAvatar-DBA0a0-a.js} +1 -1
  132. zenml/zen_server/dashboard/assets/{NestedCollapsible-DYbgyKxK.js → NestedCollapsible-DpgmEFKw.js} +1 -1
  133. zenml/zen_server/dashboard/assets/{Partials-03iZf8-N.js → Partials-D_ldD9if.js} +1 -1
  134. zenml/zen_server/dashboard/assets/{ProBadge-D_EB8HNo.js → ProBadge-DQbfFotM.js} +1 -1
  135. zenml/zen_server/dashboard/assets/{ProCta-DqNS4v3x.js → ProCta-Bcpb4rcY.js} +1 -1
  136. zenml/zen_server/dashboard/assets/{ProviderIcon-Bki2aw8w.js → ProviderIcon-BZpgPigN.js} +1 -1
  137. zenml/zen_server/dashboard/assets/{ProviderRadio-8f43sPD4.js → ProviderRadio-DWPnMuQ1.js} +1 -1
  138. zenml/zen_server/dashboard/assets/RunSelector-DgRGaAc6.js +1 -0
  139. zenml/zen_server/dashboard/assets/{RunsBody-07YEO7qI.js → RunsBody-KecfSkjY.js} +1 -1
  140. zenml/zen_server/dashboard/assets/{SearchField-lp1KgU4e.js → SearchField-n-ILHnaP.js} +1 -1
  141. zenml/zen_server/dashboard/assets/{SecretTooltip-CgnbyeOx.js → SecretTooltip-B8MrX5yu.js} +1 -1
  142. zenml/zen_server/dashboard/assets/{SetPassword-CpP418A2.js → SetPassword-B_IVq_wg.js} +1 -1
  143. zenml/zen_server/dashboard/assets/StackList-TWPBYnkF.js +1 -0
  144. zenml/zen_server/dashboard/assets/{Tabs-BktHkCJJ.js → Tabs-Rg857zmd.js} +1 -1
  145. zenml/zen_server/dashboard/assets/{Tick-BlMoIlJT.js → Tick-COg4A-xo.js} +1 -1
  146. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-Sc0A0pP-.js → UpdatePasswordSchemas-C6Aj3hm6.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{UsageReason-YYduL4fj.js → UsageReason-BTLbx7w4.js} +1 -1
  148. zenml/zen_server/dashboard/assets/{WizardFooter-dgmizSJC.js → WizardFooter-BCAj69Vj.js} +1 -1
  149. zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-D-c2G6lV.js → all-pipeline-runs-query-DMXkDrV2.js} +1 -1
  150. zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
  151. zenml/zen_server/dashboard/assets/{create-stack-DM_JPgef.js → create-stack-HfdbhLs4.js} +1 -1
  152. zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
  153. zenml/zen_server/dashboard/assets/delete-run-DZ4hIXff.js +1 -0
  154. zenml/zen_server/dashboard/assets/{form-schemas-K6FYKjwa.js → form-schemas-B0AVEd9b.js} +1 -1
  155. zenml/zen_server/dashboard/assets/{index-BAkC7FXi.js → index-DPqSWjug.js} +1 -1
  156. zenml/zen_server/dashboard/assets/{index-CEV4Cvaf.js → index-DScjfBRb.js} +1 -1
  157. zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
  158. zenml/zen_server/dashboard/assets/{index-CCOPpudF.js → index-FO-p0GU7.js} +5 -5
  159. zenml/zen_server/dashboard/assets/{index-B1mVPYxf.js → index-I3bKUGUj.js} +1 -1
  160. zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
  161. zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
  162. zenml/zen_server/dashboard/assets/{login-mutation-hf-lK87O.js → login-mutation-BQeo4wTY.js} +1 -1
  163. zenml/zen_server/dashboard/assets/{not-found-BGirLjU-.js → not-found-gAJ5aDdR.js} +1 -1
  164. zenml/zen_server/dashboard/assets/page-9Y9-gig0.js +1 -0
  165. zenml/zen_server/dashboard/assets/{page-DjRJCGb3.js → page-AUwiQ14W.js} +1 -1
  166. zenml/zen_server/dashboard/assets/page-B6XU7yYT.js +2 -0
  167. zenml/zen_server/dashboard/assets/{page-C00YAkaB.js → page-BKZYc2Zv.js} +1 -1
  168. zenml/zen_server/dashboard/assets/{page-CdMWnQak.js → page-BU9FG4sR.js} +1 -1
  169. zenml/zen_server/dashboard/assets/{page-D7S3aCbF.js → page-B_Apk3xg.js} +1 -1
  170. zenml/zen_server/dashboard/assets/{page-Djikxq_S.js → page-BdowiCbr.js} +1 -1
  171. zenml/zen_server/dashboard/assets/page-Bg8OjTRe.js +1 -0
  172. zenml/zen_server/dashboard/assets/page-BxL4qD4_.js +1 -0
  173. zenml/zen_server/dashboard/assets/{page-DakHVWXF.js → page-CWxT5K5J.js} +1 -1
  174. zenml/zen_server/dashboard/assets/page-CXuQufSe.js +1 -0
  175. zenml/zen_server/dashboard/assets/{page-DLC-bNBP.js → page-CcQr8CPP.js} +1 -1
  176. zenml/zen_server/dashboard/assets/{page-CD-DcWoy.js → page-Ce4Hrjnr.js} +1 -1
  177. zenml/zen_server/dashboard/assets/page-CiYxgZP_.js +1 -0
  178. zenml/zen_server/dashboard/assets/page-Cldq1mpe.js +1 -0
  179. zenml/zen_server/dashboard/assets/{page-BDigxVpo.js → page-D4wdonLm.js} +1 -1
  180. zenml/zen_server/dashboard/assets/{page-D6uU2ax4.js → page-D8ObrbH8.js} +1 -1
  181. zenml/zen_server/dashboard/assets/{page-DXSTpqRD.js → page-DFuAUGt4.js} +1 -1
  182. zenml/zen_server/dashboard/assets/{page-CbpvrsDL.js → page-DGazBpuP.js} +1 -1
  183. zenml/zen_server/dashboard/assets/{page-COXXJj1k.js → page-DO1UcqPX.js} +1 -1
  184. zenml/zen_server/dashboard/assets/page-DRYXdL5o.js +1 -0
  185. zenml/zen_server/dashboard/assets/{page-Df-Fw0aq.js → page-DYEquBC2.js} +1 -1
  186. zenml/zen_server/dashboard/assets/page-Dk32IeZm.js +1 -0
  187. zenml/zen_server/dashboard/assets/{page-yYC9OI-E.js → page-I3nKFGie.js} +1 -1
  188. zenml/zen_server/dashboard/assets/{page-6m6yHHlE.js → page-M0w-n6vn.js} +1 -1
  189. zenml/zen_server/dashboard/assets/{page-Vcxara9U.js → page-R5dx3xGF.js} +1 -1
  190. zenml/zen_server/dashboard/assets/{page-BR68V0V1.js → page-bT5pOvcB.js} +1 -1
  191. zenml/zen_server/dashboard/assets/page-hUqK889I.js +6 -0
  192. zenml/zen_server/dashboard/assets/{page-CjGdWY13.js → page-h_Stveon.js} +1 -1
  193. zenml/zen_server/dashboard/assets/{page-D01JhjQB.js → page-r8XK5vR7.js} +1 -1
  194. zenml/zen_server/dashboard/assets/page-u_-ZXBKb.js +1 -0
  195. zenml/zen_server/dashboard/assets/page-zaMqB_ao.js +1 -0
  196. zenml/zen_server/dashboard/assets/{persist-GjC8PZoC.js → persist-AppN1B0J.js} +1 -1
  197. zenml/zen_server/dashboard/assets/{persist-Coz7ZWvz.js → persist-DAUi_3za.js} +1 -1
  198. zenml/zen_server/dashboard/assets/service-BqqeXLEe.js +2 -0
  199. zenml/zen_server/dashboard/assets/{sharedSchema-CQb14VSr.js → sharedSchema-uXN9FLLk.js} +1 -1
  200. zenml/zen_server/dashboard/assets/{stack-detail-query-OPEW-cDJ.js → stack-detail-query-XfZBiBP2.js} +1 -1
  201. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-LwuQfHYn.js → update-server-settings-mutation-BWmgVJwA.js} +1 -1
  202. zenml/zen_server/dashboard/assets/{url-CkvKAnwF.js → url-BLwMbzES.js} +1 -1
  203. zenml/zen_server/dashboard/index.html +4 -4
  204. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  205. zenml/zen_server/deploy/helm/README.md +2 -2
  206. zenml/zen_server/rbac/endpoint_utils.py +6 -4
  207. zenml/zen_server/rbac/models.py +3 -2
  208. zenml/zen_server/rbac/rbac_sql_zen_store.py +173 -0
  209. zenml/zen_server/rbac/utils.py +4 -7
  210. zenml/zen_server/routers/auth_endpoints.py +22 -11
  211. zenml/zen_server/routers/steps_endpoints.py +7 -1
  212. zenml/zen_server/routers/users_endpoints.py +35 -37
  213. zenml/zen_server/routers/workspaces_endpoints.py +44 -55
  214. zenml/zen_server/template_execution/utils.py +4 -1
  215. zenml/zen_server/utils.py +4 -3
  216. zenml/zen_stores/base_zen_store.py +10 -2
  217. zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
  218. zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
  219. zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
  220. zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
  221. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
  222. zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +7 -6
  223. zenml/zen_stores/rest_zen_store.py +76 -43
  224. zenml/zen_stores/schemas/__init__.py +5 -1
  225. zenml/zen_stores/schemas/artifact_schemas.py +12 -11
  226. zenml/zen_stores/schemas/component_schemas.py +0 -3
  227. zenml/zen_stores/schemas/model_schemas.py +55 -17
  228. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
  229. zenml/zen_stores/schemas/pipeline_run_schemas.py +52 -18
  230. zenml/zen_stores/schemas/pipeline_schemas.py +5 -0
  231. zenml/zen_stores/schemas/run_metadata_schemas.py +66 -31
  232. zenml/zen_stores/schemas/step_run_schemas.py +40 -13
  233. zenml/zen_stores/schemas/utils.py +47 -3
  234. zenml/zen_stores/sql_zen_store.py +462 -134
  235. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/METADATA +5 -5
  236. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/RECORD +239 -217
  237. zenml/utils/cloud_utils.py +0 -40
  238. zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +0 -1
  239. zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +0 -1
  240. zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +0 -1
  241. zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +0 -1
  242. zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +0 -1
  243. zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +0 -1
  244. zenml/zen_server/dashboard/assets/page-BU7huvKw.js +0 -6
  245. zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +0 -1
  246. zenml/zen_server/dashboard/assets/page-CwxrFarU.js +0 -1
  247. zenml/zen_server/dashboard/assets/page-DfbXf_8s.js +0 -1
  248. zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +0 -3
  249. zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +0 -1
  250. zenml/zen_server/dashboard/assets/page-Xynx4btY.js +0 -14
  251. zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +0 -1
  252. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/LICENSE +0 -0
  253. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/WHEEL +0 -0
  254. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/entry_points.txt +0 -0
@@ -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(BaseFilter):
327
+ class WorkspaceScopedFilter(UserScopedFilter):
244
328
  """Model to enable advanced scoping with workspace."""
245
329
 
246
330
  FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
247
- *BaseFilter.FILTER_EXCLUDE_FIELDS,
331
+ *UserScopedFilter.FILTER_EXCLUDE_FIELDS,
332
+ "workspace",
248
333
  "scope_workspace",
249
334
  ]
250
335
  CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
251
- *BaseFilter.CLI_EXCLUDE_FIELDS,
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(self) -> List["ColumnElement[bool]"]:
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 artifact version.",
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(self) -> List[Union["ColumnElement[bool]"]]:
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
 
@@ -576,11 +577,11 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
576
577
  ModelVersionArtifactSchema,
577
578
  ModelVersionSchema,
578
579
  PipelineRunSchema,
580
+ RunMetadataResourceSchema,
579
581
  RunMetadataSchema,
580
582
  StepRunInputArtifactSchema,
581
583
  StepRunOutputArtifactSchema,
582
584
  StepRunSchema,
583
- UserSchema,
584
585
  )
585
586
 
586
587
  if self.name:
@@ -628,17 +629,6 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
628
629
  )
629
630
  custom_filters.append(custom_name_filter)
630
631
 
631
- if self.user:
632
- user_filter = and_(
633
- ArtifactVersionSchema.user_id == UserSchema.id,
634
- self.generate_name_or_id_query_conditions(
635
- value=self.user,
636
- table=UserSchema,
637
- additional_columns=["full_name"],
638
- ),
639
- )
640
- custom_filters.append(user_filter)
641
-
642
632
  if self.model:
643
633
  model_filter = and_(
644
634
  ArtifactVersionSchema.id
@@ -679,10 +669,12 @@ class ArtifactVersionFilter(WorkspaceScopedTaggableFilter):
679
669
 
680
670
  for key, value in self.run_metadata.items():
681
671
  additional_filter = and_(
682
- RunMetadataSchema.resource_id == ArtifactVersionSchema.id,
683
- RunMetadataSchema.resource_type
672
+ RunMetadataResourceSchema.resource_id
673
+ == ArtifactVersionSchema.id,
674
+ RunMetadataResourceSchema.resource_type
684
675
  == MetadataResourceTypes.ARTIFACT_VERSION,
685
- RunMetadataSchema.key == key,
676
+ RunMetadataResourceSchema.run_metadata_id
677
+ == RunMetadataSchema.id,
686
678
  self.generate_custom_query_conditions_for_column(
687
679
  value=value,
688
680
  table=RunMetadataSchema,
@@ -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, Union
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
 
@@ -81,11 +84,6 @@ class ComponentBase(BaseModel):
81
84
  title="The stack component labels.",
82
85
  )
83
86
 
84
- component_spec_path: Optional[str] = Field(
85
- default=None,
86
- title="The path to the component spec used for mlstacks deployments.",
87
- )
88
-
89
87
 
90
88
  # ------------------ Request Model ------------------
91
89
 
@@ -155,10 +153,6 @@ class ComponentUpdate(BaseUpdate):
155
153
  title="The stack component labels.",
156
154
  default=None,
157
155
  )
158
- component_spec_path: Optional[str] = Field(
159
- title="The path to the component spec used for mlstacks deployments.",
160
- default=None,
161
- )
162
156
  connector: Optional[UUID] = Field(
163
157
  title="The service connector linked to this stack component.",
164
158
  default=None,
@@ -201,10 +195,6 @@ class ComponentResponseMetadata(WorkspaceScopedResponseMetadata):
201
195
  default=None,
202
196
  title="The stack component labels.",
203
197
  )
204
- component_spec_path: Optional[str] = Field(
205
- default=None,
206
- title="The path to the component spec used for mlstacks deployments.",
207
- )
208
198
  connector_resource_id: Optional[str] = Field(
209
199
  default=None,
210
200
  description="The ID of a specific resource instance to "
@@ -325,15 +315,6 @@ class ComponentResponse(
325
315
  """
326
316
  return self.get_metadata().labels
327
317
 
328
- @property
329
- def component_spec_path(self) -> Optional[str]:
330
- """The `component_spec_path` property.
331
-
332
- Returns:
333
- the value of the property.
334
- """
335
- return self.get_metadata().component_spec_path
336
-
337
318
  @property
338
319
  def connector_resource_id(self) -> Optional[str]:
339
320
  """The `connector_resource_id` property.
@@ -378,7 +359,6 @@ class ComponentFilter(WorkspaceScopedFilter):
378
359
  *WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
379
360
  "scope_type",
380
361
  "stack_id",
381
- "user",
382
362
  ]
383
363
  CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
384
364
  *WorkspaceScopedFilter.CLI_EXCLUDE_FIELDS,
@@ -388,7 +368,6 @@ class ComponentFilter(WorkspaceScopedFilter):
388
368
  default=None,
389
369
  description="The type to scope this query to.",
390
370
  )
391
-
392
371
  name: Optional[str] = Field(
393
372
  default=None,
394
373
  description="Name of the stack component",
@@ -401,16 +380,6 @@ class ComponentFilter(WorkspaceScopedFilter):
401
380
  default=None,
402
381
  description="Type of the stack component",
403
382
  )
404
- workspace_id: Optional[Union[UUID, str]] = Field(
405
- default=None,
406
- description="Workspace of the stack component",
407
- union_mode="left_to_right",
408
- )
409
- user_id: Optional[Union[UUID, str]] = Field(
410
- default=None,
411
- description="User of the stack component",
412
- union_mode="left_to_right",
413
- )
414
383
  connector_id: Optional[Union[UUID, str]] = Field(
415
384
  default=None,
416
385
  description="Connector linked to the stack component",
@@ -421,10 +390,6 @@ class ComponentFilter(WorkspaceScopedFilter):
421
390
  description="Stack of the stack component",
422
391
  union_mode="left_to_right",
423
392
  )
424
- user: Optional[Union[UUID, str]] = Field(
425
- default=None,
426
- description="Name/ID of the user that created the component.",
427
- )
428
393
 
429
394
  def set_scope_type(self, component_type: str) -> None:
430
395
  """Set the type of component on which to perform the filtering to scope the response.
@@ -435,7 +400,7 @@ class ComponentFilter(WorkspaceScopedFilter):
435
400
  self.scope_type = component_type
436
401
 
437
402
  def generate_filter(
438
- self, table: Type["SQLModel"]
403
+ self, table: Type["AnySchema"]
439
404
  ) -> Union["ColumnElement[bool]"]:
440
405
  """Generate the filter for the query.
441
406
 
@@ -471,31 +436,3 @@ class ComponentFilter(WorkspaceScopedFilter):
471
436
  base_filter = operator(base_filter, stack_filter)
472
437
 
473
438
  return base_filter
474
-
475
- def get_custom_filters(self) -> List["ColumnElement[bool]"]:
476
- """Get custom filters.
477
-
478
- Returns:
479
- A list of custom filters.
480
- """
481
- from sqlmodel import and_
482
-
483
- from zenml.zen_stores.schemas import (
484
- StackComponentSchema,
485
- UserSchema,
486
- )
487
-
488
- custom_filters = super().get_custom_filters()
489
-
490
- if self.user:
491
- user_filter = and_(
492
- StackComponentSchema.user_id == UserSchema.id,
493
- self.generate_name_or_id_query_conditions(
494
- value=self.user,
495
- table=UserSchema,
496
- additional_columns=["full_name"],
497
- ),
498
- )
499
- custom_filters.append(user_filter)
500
-
501
- return custom_filters
@@ -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, Union
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
- )