zenml-nightly 0.68.1.dev20241112__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.
Files changed (186) hide show
  1. README.md +1 -1
  2. RELEASE_NOTES.md +77 -0
  3. zenml/VERSION +1 -1
  4. zenml/__init__.py +2 -0
  5. zenml/artifacts/utils.py +5 -1
  6. zenml/client.py +6 -1
  7. zenml/config/server_config.py +17 -1
  8. zenml/constants.py +1 -7
  9. zenml/enums.py +8 -0
  10. zenml/model/utils.py +5 -0
  11. zenml/models/v2/base/filter.py +121 -8
  12. zenml/models/v2/core/artifact_version.py +23 -0
  13. zenml/models/v2/core/model_version.py +23 -0
  14. zenml/models/v2/core/pipeline_run.py +22 -1
  15. zenml/models/v2/core/step_run.py +22 -0
  16. zenml/orchestrators/base_orchestrator.py +12 -1
  17. zenml/orchestrators/step_launcher.py +2 -1
  18. zenml/orchestrators/utils.py +45 -26
  19. zenml/steps/utils.py +5 -0
  20. zenml/utils/metadata_utils.py +335 -0
  21. zenml/zen_server/auth.py +221 -3
  22. zenml/zen_server/cache.py +208 -0
  23. zenml/zen_server/dashboard/assets/{404-DT4QRUqN.js → 404-NVXKFp-x.js} +1 -1
  24. zenml/zen_server/dashboard/assets/{@radix-DP6vWzyx.js → @radix-DeK6qiuw.js} +1 -1
  25. zenml/zen_server/dashboard/assets/{@react-router-BMhZulnd.js → @react-router-B3Z5rLr2.js} +1 -1
  26. zenml/zen_server/dashboard/assets/{@reactflow-8U9qNlMR.js → @reactflow-CK0KJUen.js} +2 -2
  27. zenml/zen_server/dashboard/assets/{@tanstack-BUCbhJyH.js → @tanstack-DT5WLu9C.js} +1 -1
  28. zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-DezXKmDf.js +1 -0
  29. zenml/zen_server/dashboard/assets/{CodeSnippet-CqybNv0k.js → CodeSnippet-JzR8CEtw.js} +2 -2
  30. zenml/zen_server/dashboard/assets/{CollapsibleCard-0r_8G2Lj.js → CollapsibleCard-DQW_ktMO.js} +1 -1
  31. zenml/zen_server/dashboard/assets/{Commands-BDjgBQKi.js → Commands-DL2kwkRd.js} +1 -1
  32. zenml/zen_server/dashboard/assets/ComponentBadge-D_g62Wv8.js +1 -0
  33. zenml/zen_server/dashboard/assets/{CopyButton-C745BrKi.js → CopyButton-LNcWaa14.js} +1 -1
  34. zenml/zen_server/dashboard/assets/{CsvVizualization-PpAq0CeZ.js → CsvVizualization-DknpE5ej.js} +5 -5
  35. zenml/zen_server/dashboard/assets/{DialogItem-DcVCZEew.js → DialogItem-Bxf8FuAT.js} +1 -1
  36. zenml/zen_server/dashboard/assets/{DisplayDate-BeXgUG_C.js → DisplayDate-CDMUcQHS.js} +1 -1
  37. zenml/zen_server/dashboard/assets/{EmptyState-DeK7H4pr.js → EmptyState-BzdlCwp3.js} +1 -1
  38. zenml/zen_server/dashboard/assets/{Error-BMlzibXj.js → Error-DYflYyps.js} +1 -1
  39. zenml/zen_server/dashboard/assets/ExecutionStatus-C7zyIQKZ.js +1 -0
  40. zenml/zen_server/dashboard/assets/{Helpbox-BLf40fLV.js → Helpbox-oYSGpLqd.js} +1 -1
  41. zenml/zen_server/dashboard/assets/{Infobox-BwisKifi.js → Infobox-Cx4xGoXR.js} +1 -1
  42. zenml/zen_server/dashboard/assets/{InlineAvatar-jEgodSgX.js → InlineAvatar-DiGOWNKF.js} +1 -1
  43. zenml/zen_server/dashboard/assets/{Lock-3lLt1ih0.js → Lock-CYYy18Mm.js} +1 -1
  44. zenml/zen_server/dashboard/assets/{MarkdownVisualization-8O9kTr-2.js → MarkdownVisualization-ylXaAxev.js} +1 -1
  45. zenml/zen_server/dashboard/assets/NestedCollapsible-DYbgyKxK.js +1 -0
  46. zenml/zen_server/dashboard/assets/{NumberBox-T9eELfLZ.js → NumberBox-Dtp3J6g5.js} +1 -1
  47. zenml/zen_server/dashboard/assets/Partials-03iZf8-N.js +1 -0
  48. zenml/zen_server/dashboard/assets/{PasswordChecker-CW0kqY0W.js → PasswordChecker-B0nadgh6.js} +1 -1
  49. zenml/zen_server/dashboard/assets/ProBadge-D_EB8HNo.js +1 -0
  50. zenml/zen_server/dashboard/assets/ProCta-DqNS4v3x.js +1 -0
  51. zenml/zen_server/dashboard/assets/ProviderIcon-Bki2aw8w.js +1 -0
  52. zenml/zen_server/dashboard/assets/{ProviderRadio-BROY1700.js → ProviderRadio-8f43sPD4.js} +1 -1
  53. zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +1 -0
  54. zenml/zen_server/dashboard/assets/RunsBody-07YEO7qI.js +1 -0
  55. zenml/zen_server/dashboard/assets/SearchField-lp1KgU4e.js +1 -0
  56. zenml/zen_server/dashboard/assets/{SecretTooltip-C_qByGWB.js → SecretTooltip-CgnbyeOx.js} +1 -1
  57. zenml/zen_server/dashboard/assets/{SetPassword-7pRB00El.js → SetPassword-CpP418A2.js} +1 -1
  58. zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +1 -0
  59. zenml/zen_server/dashboard/assets/Tabs-BktHkCJJ.js +1 -0
  60. zenml/zen_server/dashboard/assets/Tick-BlMoIlJT.js +1 -0
  61. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DckMEkFf.js → UpdatePasswordSchemas-Sc0A0pP-.js} +1 -1
  62. zenml/zen_server/dashboard/assets/{UsageReason-DVceN14P.js → UsageReason-YYduL4fj.js} +1 -1
  63. zenml/zen_server/dashboard/assets/{WizardFooter-CW0Cvd70.js → WizardFooter-dgmizSJC.js} +1 -1
  64. zenml/zen_server/dashboard/assets/all-pipeline-runs-query-D-c2G6lV.js +1 -0
  65. zenml/zen_server/dashboard/assets/check-DloQpStc.js +1 -0
  66. zenml/zen_server/dashboard/assets/{check-circle-Dwxliy1Z.js → check-circle-jNbX5-sR.js} +1 -1
  67. zenml/zen_server/dashboard/assets/{chevron-down-8wLBS5pQ.js → chevron-down-6JyMkfjR.js} +1 -1
  68. zenml/zen_server/dashboard/assets/{chevron-right-double-DoD8iXWM.js → chevron-right-double-D7ojK9Co.js} +1 -1
  69. zenml/zen_server/dashboard/assets/{code-browser-CZUQs3Wa.js → code-browser-CUFUIHfp.js} +1 -1
  70. zenml/zen_server/dashboard/assets/{copy-CaSMXwiU.js → copy-C8XQA2Ug.js} +1 -1
  71. zenml/zen_server/dashboard/assets/create-stack-DM_JPgef.js +1 -0
  72. zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +1 -0
  73. zenml/zen_server/dashboard/assets/{docker-BFNgg-z3.js → docker-BdA9vrnW.js} +1 -1
  74. zenml/zen_server/dashboard/assets/{dots-horizontal-DK5Duzx4.js → dots-horizontal-otGBOSDJ.js} +1 -1
  75. zenml/zen_server/dashboard/assets/{form-schemas-1AyOCx90.js → form-schemas-K6FYKjwa.js} +1 -1
  76. zenml/zen_server/dashboard/assets/{gcp-7M2Yf3ZK.js → gcp-CFtm4BA7.js} +1 -1
  77. zenml/zen_server/dashboard/assets/{help-Dam461dC.js → help-Cc9bBIJH.js} +1 -1
  78. zenml/zen_server/dashboard/assets/index-B1mVPYxf.js +1 -0
  79. zenml/zen_server/dashboard/assets/index-BAkC7FXi.js +1 -0
  80. zenml/zen_server/dashboard/assets/{index-QQb7wQEC.js → index-CCOPpudF.js} +8 -8
  81. zenml/zen_server/dashboard/assets/index-CEV4Cvaf.js +1 -0
  82. zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +1 -0
  83. zenml/zen_server/dashboard/assets/{index-BVJ8n2-j.js → index-Uu49AX48.js} +1 -1
  84. zenml/zen_server/dashboard/assets/{index.esm-cuVep_NJ.js → index.esm-Dy6Z9Ung.js} +1 -1
  85. zenml/zen_server/dashboard/assets/{kubernetes--g7r02Zu.js → kubernetes-B2wmAJ1d.js} +1 -1
  86. zenml/zen_server/dashboard/assets/{layout-DCSYN7-C.js → layout-BtHBmE4w.js} +1 -1
  87. zenml/zen_server/dashboard/assets/{link-external-CBEk6kEG.js → link-external-b9AXw_sW.js} +1 -1
  88. zenml/zen_server/dashboard/assets/{login-mutation-DTcAFP1l.js → login-mutation-hf-lK87O.js} +1 -1
  89. zenml/zen_server/dashboard/assets/{logs-D5bdJGur.js → logs-WMSM52RF.js} +1 -1
  90. zenml/zen_server/dashboard/assets/{not-found-Cc-JkRH2.js → not-found-BGirLjU-.js} +1 -1
  91. zenml/zen_server/dashboard/assets/{package-Cs35Szwh.js → package-C6uypY4h.js} +1 -1
  92. zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +1 -0
  93. zenml/zen_server/dashboard/assets/{page-DH_Z7iW1.js → page-6m6yHHlE.js} +1 -1
  94. zenml/zen_server/dashboard/assets/page-BDigxVpo.js +1 -0
  95. zenml/zen_server/dashboard/assets/page-BR68V0V1.js +1 -0
  96. zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +1 -0
  97. zenml/zen_server/dashboard/assets/{page-BQQKaabe.js → page-BU7huvKw.js} +3 -3
  98. zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +1 -0
  99. zenml/zen_server/dashboard/assets/page-C00YAkaB.js +1 -0
  100. zenml/zen_server/dashboard/assets/{page-N4qoPHKb.js → page-CD-DcWoy.js} +1 -1
  101. zenml/zen_server/dashboard/assets/page-COXXJj1k.js +1 -0
  102. zenml/zen_server/dashboard/assets/page-CbpvrsDL.js +1 -0
  103. zenml/zen_server/dashboard/assets/page-CdMWnQak.js +1 -0
  104. zenml/zen_server/dashboard/assets/{page-ClUVkl-O.js → page-CjGdWY13.js} +1 -1
  105. zenml/zen_server/dashboard/assets/page-CwxrFarU.js +1 -0
  106. zenml/zen_server/dashboard/assets/{page-DLixvR-7.js → page-D01JhjQB.js} +1 -1
  107. zenml/zen_server/dashboard/assets/page-D6uU2ax4.js +1 -0
  108. zenml/zen_server/dashboard/assets/page-D7S3aCbF.js +1 -0
  109. zenml/zen_server/dashboard/assets/{page-9yplj5JT.js → page-DLC-bNBP.js} +1 -1
  110. zenml/zen_server/dashboard/assets/page-DXSTpqRD.js +1 -0
  111. zenml/zen_server/dashboard/assets/{page-DzpVUZ8f.js → page-DakHVWXF.js} +1 -1
  112. zenml/zen_server/dashboard/assets/{page-DIOXwhiD.js → page-Df-Fw0aq.js} +1 -1
  113. zenml/zen_server/dashboard/assets/{page-B-y2XKIc.js → page-DfbXf_8s.js} +1 -1
  114. zenml/zen_server/dashboard/assets/page-DjRJCGb3.js +1 -0
  115. zenml/zen_server/dashboard/assets/{page-C0N5q3l7.js → page-Djikxq_S.js} +1 -1
  116. zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +3 -0
  117. zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +1 -0
  118. zenml/zen_server/dashboard/assets/page-Vcxara9U.js +1 -0
  119. zenml/zen_server/dashboard/assets/page-Xynx4btY.js +14 -0
  120. zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +1 -0
  121. zenml/zen_server/dashboard/assets/page-yYC9OI-E.js +1 -0
  122. zenml/zen_server/dashboard/assets/{persist-DNb5cdrU.js → persist-Coz7ZWvz.js} +1 -1
  123. zenml/zen_server/dashboard/assets/{persist-CP0JmYZ4.js → persist-GjC8PZoC.js} +1 -1
  124. zenml/zen_server/dashboard/assets/{plus-C9IxgN2M.js → plus-tf1V2hTJ.js} +1 -1
  125. zenml/zen_server/dashboard/assets/{refresh-BVu22P_C.js → refresh-BjOeWlEq.js} +1 -1
  126. zenml/zen_server/dashboard/assets/{rocket-CONEmRmB.js → rocket-DjT2cDvG.js} +1 -1
  127. zenml/zen_server/dashboard/assets/sharedSchema-CQb14VSr.js +14 -0
  128. zenml/zen_server/dashboard/assets/stack-detail-query-OPEW-cDJ.js +1 -0
  129. zenml/zen_server/dashboard/assets/{tick-circle-CM1ZScbQ.js → tick-circle-BEX_Tp4v.js} +1 -1
  130. zenml/zen_server/dashboard/assets/{trash-DkJHMOg7.js → trash-arLUMWMS.js} +1 -1
  131. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-DsU8cNVl.js → update-server-settings-mutation-LwuQfHYn.js} +1 -1
  132. zenml/zen_server/dashboard/assets/upgrade-form-CwRHBuXB.webp +0 -0
  133. zenml/zen_server/dashboard/assets/url-CkvKAnwF.js +1 -0
  134. zenml/zen_server/dashboard/assets/{zod-D89GC_vc.js → zod-BwEbpOxH.js} +1 -1
  135. zenml/zen_server/dashboard/index.html +7 -7
  136. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  137. zenml/zen_server/deploy/helm/README.md +2 -2
  138. zenml/zen_server/jwt.py +30 -13
  139. zenml/zen_server/routers/auth_endpoints.py +134 -102
  140. zenml/zen_server/template_execution/utils.py +14 -16
  141. zenml/zen_server/utils.py +27 -0
  142. zenml/zen_server/zen_server_api.py +4 -1
  143. zenml/zen_stores/migrations/versions/0.70.0_release.py +23 -0
  144. zenml/zen_stores/rest_zen_store.py +13 -10
  145. {zenml_nightly-0.68.1.dev20241112.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/METADATA +2 -2
  146. {zenml_nightly-0.68.1.dev20241112.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/RECORD +149 -137
  147. zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-C6N2rGrB.js +0 -1
  148. zenml/zen_server/dashboard/assets/ComponentBadge-DUiEYJHu.js +0 -1
  149. zenml/zen_server/dashboard/assets/ComponentFallbackDialog-BFoH5K4V.js +0 -1
  150. zenml/zen_server/dashboard/assets/ComponentIcon-CAIoUis2.js +0 -1
  151. zenml/zen_server/dashboard/assets/Partials-YPBB3V4q.js +0 -1
  152. zenml/zen_server/dashboard/assets/ProviderIcon-Bb3Xha5A.js +0 -1
  153. zenml/zen_server/dashboard/assets/RunSelector-DCiL3M1c.js +0 -1
  154. zenml/zen_server/dashboard/assets/SearchField-DfUiGFVd.js +0 -1
  155. zenml/zen_server/dashboard/assets/Tick-CykQFPj2.js +0 -1
  156. zenml/zen_server/dashboard/assets/cloud-only-B-s_HMDm.js +0 -1
  157. zenml/zen_server/dashboard/assets/codespaces-BitYDX9d.gif +0 -0
  158. zenml/zen_server/dashboard/assets/create-stack-CEmaPZ4c.js +0 -1
  159. zenml/zen_server/dashboard/assets/delete-run-D-LKbGyz.js +0 -1
  160. zenml/zen_server/dashboard/assets/index-Bpmj40BI.js +0 -1
  161. zenml/zen_server/dashboard/assets/index-CbU4Ln_E.css +0 -1
  162. zenml/zen_server/dashboard/assets/index-DKPhqP2B.js +0 -1
  163. zenml/zen_server/dashboard/assets/page-BBpOxVcY.js +0 -1
  164. zenml/zen_server/dashboard/assets/page-BRInM1Lg.js +0 -1
  165. zenml/zen_server/dashboard/assets/page-BjjlMk7s.js +0 -1
  166. zenml/zen_server/dashboard/assets/page-Bvd7YH2A.js +0 -1
  167. zenml/zen_server/dashboard/assets/page-CT3Nep8W.js +0 -1
  168. zenml/zen_server/dashboard/assets/page-C_f47pBf.js +0 -1
  169. zenml/zen_server/dashboard/assets/page-Cmv8C_yM.js +0 -3
  170. zenml/zen_server/dashboard/assets/page-CyN2bdWG.js +0 -1
  171. zenml/zen_server/dashboard/assets/page-CzzXH4fs.js +0 -1
  172. zenml/zen_server/dashboard/assets/page-DTlGjgnG.js +0 -1
  173. zenml/zen_server/dashboard/assets/page-Dbpl86h0.js +0 -1
  174. zenml/zen_server/dashboard/assets/page-Ddgy6kDS.js +0 -1
  175. zenml/zen_server/dashboard/assets/page-DtCAfBLy.js +0 -9
  176. zenml/zen_server/dashboard/assets/page-Dx16z7nA.js +0 -1
  177. zenml/zen_server/dashboard/assets/page-McUyYbo1.js +0 -1
  178. zenml/zen_server/dashboard/assets/page-T1P3RyAR.js +0 -1
  179. zenml/zen_server/dashboard/assets/page-bKaULTGG.js +0 -1
  180. zenml/zen_server/dashboard/assets/page-sbXUJy9t.js +0 -1
  181. zenml/zen_server/dashboard/assets/sharedSchema-TMLu-nYQ.js +0 -14
  182. zenml/zen_server/dashboard/assets/stack-detail-query-xmYxSsUY.js +0 -1
  183. zenml/zen_server/dashboard/assets/url-D5le3J4q.js +0 -1
  184. {zenml_nightly-0.68.1.dev20241112.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/LICENSE +0 -0
  185. {zenml_nightly-0.68.1.dev20241112.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/WHEEL +0 -0
  186. {zenml_nightly-0.68.1.dev20241112.dist-info → zenml_nightly-0.70.0.dev20241114.dist-info}/entry_points.txt +0 -0
README.md CHANGED
@@ -333,7 +333,7 @@ the Apache License Version 2.0.
333
333
  <a href="https://github.com/zenml-io/zenml-projects">Projects Showcase</a>
334
334
  <br />
335
335
  <br />
336
- 🎉 Version 0.68.1 is out. Check out the release notes
336
+ 🎉 Version 0.70.0 is out. Check out the release notes
337
337
  <a href="https://github.com/zenml-io/zenml/releases">here</a>.
338
338
  <br />
339
339
  🖥️ Download our VS Code Extension <a href="https://marketplace.visualstudio.com/items?itemName=ZenML.zenml-vscode">here</a>.
RELEASE_NOTES.md CHANGED
@@ -1,5 +1,82 @@
1
1
  <!-- markdown-link-check-disable -->
2
2
 
3
+ # 0.70.0
4
+
5
+ The **ZenML 0.70.0** release includes a significant number of database schema changes and migrations, which means upgrading to this version will require extra caution. As always, please make sure to make a copy of your production database before upgrading.
6
+
7
+ ## Key Changes
8
+
9
+ * **Artifact Versioning Improvements**: The handling of artifact versions has been improved, including the API improvements like the ability to batch artifact version requests to improve the execution times and more types for the step input/output artifacts, including multiple versions of the same artifact (e.g. model checkpoints), to improve the UX using ZenML UI or while working directly with the API.
10
+ * **Scalability Enhancements**: Various scalability improvements have been made, such as reducing unnecessary server requests and incrementing artifact versions server-side. These enhancements are expected to provide significant speed and scale improvements for ZenML users.
11
+ * **Metadata management**: Now, all the metadata-creating functions are gathered under one method called `log_metadata`. It is possible to call this method with different inputs to log run metadata for artifact versions, model versions, steps, and runs.
12
+ * **The oneof filtering**: This allows to filter entities using a new operator called `oneof`. You can use this with IDs (UUID type) or tags (or other string-typed attributes) like this `PipelineRunFilter(tag='oneof:["cats", "dogs"]')`.
13
+ * **Documentation Improvements**: The ZenML documentation has been restructured and expanded, including the addition of new sections on [finetuning](https://docs.zenml.io/user-guide/llmops-guide/finetuning-llms) and [LLM/ML engineering](https://docs.zenml.io/user-guide/llmops-guide/evaluation) resources.
14
+ * **Bug Fixes**: This release includes several bug fixes, including issues with in-process main module source loading, and more.
15
+
16
+ ## Caution: Make sure to back up your data before upgrading!
17
+ While this release brings many valuable improvements, the database schema changes and migrations pose a potential risk to users. It is strongly recommended that users:
18
+
19
+ * **Test the upgrade on a non-production environment**: Before upgrading a production system, test the upgrade process in a non-production environment to identify and address any issues.
20
+ * **Back up your data**: Ensure that you have a reliable backup of your ZenML data before attempting the upgrade.
21
+
22
+ ## What's Changed
23
+ * Optimizing the CI workflows by @bcdurak in https://github.com/zenml-io/zenml/pull/3145
24
+ * Adding 0.68.0 to the migration tests by @bcdurak in https://github.com/zenml-io/zenml/pull/3144
25
+ * Move step durations to body by @schustmi in https://github.com/zenml-io/zenml/pull/3046
26
+ * Docs on ZenML setup by @strickvl in https://github.com/zenml-io/zenml/pull/3100
27
+ * Remove wrongly set Model.was_created_in_this_run attribute by @schustmi in https://github.com/zenml-io/zenml/pull/3129
28
+ * Allow specifying run tags in pipeline configuration by @schustmi in https://github.com/zenml-io/zenml/pull/3130
29
+ * Fix materializer type compatibility check during loading by @schustmi in https://github.com/zenml-io/zenml/pull/3105
30
+ * [docs] Add icons to headers in docs by @wjayesh in https://github.com/zenml-io/zenml/pull/3149
31
+ * fix icons and remove redundant file by @wjayesh in https://github.com/zenml-io/zenml/pull/3150
32
+ * Merge 0.68.1 release into develop by @schustmi in https://github.com/zenml-io/zenml/pull/3153
33
+ * Allow filtering pipeline runs by stack component by @schustmi in https://github.com/zenml-io/zenml/pull/3142
34
+ * Allow artifact response as step input by @schustmi in https://github.com/zenml-io/zenml/pull/3134
35
+ * Filter component by user name by @schustmi in https://github.com/zenml-io/zenml/pull/3126
36
+ * [docs] Restructure how-to section to make it more readable by @wjayesh in https://github.com/zenml-io/zenml/pull/3147
37
+ * ZenML Pro web login implementation by @stefannica in https://github.com/zenml-io/zenml/pull/3141
38
+ * Scalability improvements: Reduce misc/hydration server requests by @schustmi in https://github.com/zenml-io/zenml/pull/3093
39
+ * Fix in-process main module source loading by @schustmi in https://github.com/zenml-io/zenml/pull/3119
40
+ * Catch assertion in GH library by @schustmi in https://github.com/zenml-io/zenml/pull/3160
41
+ * Enable cache precomputation for run templates by @schustmi in https://github.com/zenml-io/zenml/pull/3156
42
+ * Add LLM and ML engineering books to README by @htahir1 in https://github.com/zenml-io/zenml/pull/3159
43
+ * Add helper method to quickly create run template from pipeline by @schustmi in https://github.com/zenml-io/zenml/pull/3155
44
+ * Add CLI command to export stack requirements by @schustmi in https://github.com/zenml-io/zenml/pull/3158
45
+ * Scalability improvements: Increment artifact version server side by @schustmi in https://github.com/zenml-io/zenml/pull/3095
46
+ * Update OpenAI integration by @safoinme in https://github.com/zenml-io/zenml/pull/3163
47
+ * Remove deprecated torch version constraint by @safoinme in https://github.com/zenml-io/zenml/pull/3166
48
+ * vLLM model deployer by @dudeperf3ct in https://github.com/zenml-io/zenml/pull/3032
49
+ * Don't initialize client during flavor sync by @schustmi in https://github.com/zenml-io/zenml/pull/3168
50
+ * Cleanup materializer temporary directories after step execution by @schustmi in https://github.com/zenml-io/zenml/pull/3162
51
+ * Fix langchain in API docs by @avishniakov in https://github.com/zenml-io/zenml/pull/3171
52
+ * Finetuning guide by @strickvl in https://github.com/zenml-io/zenml/pull/3157
53
+ * Fix mypy issue vllm evidently by @safoinme in https://github.com/zenml-io/zenml/pull/3169
54
+ * Add artifact version batch request by @schustmi in https://github.com/zenml-io/zenml/pull/3164
55
+ * Add missing section links by @strickvl in https://github.com/zenml-io/zenml/pull/3172
56
+ * Fix uvloop mypy by @avishniakov in https://github.com/zenml-io/zenml/pull/3174
57
+ * Multiple output versions for a step outputs by @avishniakov in https://github.com/zenml-io/zenml/pull/3072
58
+ * Simplify Metadata handling by @AlexejPenner in https://github.com/zenml-io/zenml/pull/3096
59
+ * assign value to component_name in preset stack registration by @hirekk in https://github.com/zenml-io/zenml/pull/3178
60
+ * Updating the template versions with `zenml login` by @bcdurak in https://github.com/zenml-io/zenml/pull/3177
61
+ * Better input artifacts typing by @avishniakov in https://github.com/zenml-io/zenml/pull/3099
62
+ * Refactor environment setup and caching by @safoinme in https://github.com/zenml-io/zenml/pull/3077
63
+ * Fix spelling errors by @safoinme in https://github.com/zenml-io/zenml/pull/3181
64
+ * Prevent some race conditions by @schustmi in https://github.com/zenml-io/zenml/pull/3167
65
+ * Update stack deployments with latest features by @stefannica in https://github.com/zenml-io/zenml/pull/3183
66
+ * Terraform best practices by @htahir1 in https://github.com/zenml-io/zenml/pull/3131
67
+ * Fix sagemaker pipeline URLs by @stefannica in https://github.com/zenml-io/zenml/pull/3176
68
+ * Fix lightning orchestrator for multi-step pipelines by @wjayesh in https://github.com/zenml-io/zenml/pull/3170
69
+ * Port bugfixes from #2497 by @avishniakov in https://github.com/zenml-io/zenml/pull/3179
70
+ * Removing the `enable_cache` from the config files by @bcdurak in https://github.com/zenml-io/zenml/pull/3184
71
+ * Don't pass tags to step config by @schustmi in https://github.com/zenml-io/zenml/pull/3186
72
+ * New `log_metadata` function, new `oneof` filtering, additional `run_metadata` filtering by @bcdurak in https://github.com/zenml-io/zenml/pull/3182
73
+
74
+ ## New Contributors
75
+ * @hirekk made their first contribution in https://github.com/zenml-io/zenml/pull/3178
76
+
77
+ **Full Changelog**: https://github.com/zenml-io/zenml/compare/0.68.1...0.70.0
78
+
79
+
3
80
  # 0.68.1
4
81
 
5
82
  Fixes an issue with some partially cached pipelines running on remote orchestrators.
zenml/VERSION CHANGED
@@ -1 +1 @@
1
- 0.68.1.dev20241112
1
+ 0.70.0.dev20241114
zenml/__init__.py CHANGED
@@ -48,6 +48,7 @@ from zenml.model.model import Model
48
48
  from zenml.pipelines import get_pipeline_context, pipeline
49
49
  from zenml.steps import step, get_step_context
50
50
  from zenml.steps.utils import log_step_metadata
51
+ from zenml.utils.metadata_utils import log_metadata
51
52
  from zenml.entrypoints import entrypoint
52
53
 
53
54
  __all__ = [
@@ -56,6 +57,7 @@ __all__ = [
56
57
  "get_pipeline_context",
57
58
  "get_step_context",
58
59
  "load_artifact",
60
+ "log_metadata",
59
61
  "log_artifact_metadata",
60
62
  "log_model_metadata",
61
63
  "log_step_metadata",
zenml/artifacts/utils.py CHANGED
@@ -408,7 +408,7 @@ def log_artifact_metadata(
408
408
  not provided, when being called inside a step that produces an
409
409
  artifact named `artifact_name`, the metadata will be associated to
410
410
  the corresponding newly created artifact. Or, if not provided when
411
- being called outside of a step, or in a step that does not produce
411
+ being called outside a step, or in a step that does not produce
412
412
  any artifact named `artifact_name`, the metadata will be associated
413
413
  to the latest version of that artifact.
414
414
 
@@ -417,6 +417,10 @@ def log_artifact_metadata(
417
417
  called inside a step with a single output, or, if neither an
418
418
  artifact nor an output with the given name exists.
419
419
  """
420
+ logger.warning(
421
+ "The `log_artifact_metadata` function is deprecated and will soon be "
422
+ "removed. Please use `log_metadata` instead."
423
+ )
420
424
  try:
421
425
  step_context = get_step_context()
422
426
  in_step_outputs = (artifact_name in step_context._outputs) or (
zenml/client.py CHANGED
@@ -3796,6 +3796,7 @@ class Client(metaclass=ClientMetaClass):
3796
3796
  templatable: Optional[bool] = None,
3797
3797
  tag: Optional[str] = None,
3798
3798
  user: Optional[Union[UUID, str]] = None,
3799
+ run_metadata: Optional[Dict[str, str]] = None,
3799
3800
  pipeline: Optional[Union[UUID, str]] = None,
3800
3801
  code_repository: Optional[Union[UUID, str]] = None,
3801
3802
  model: Optional[Union[UUID, str]] = None,
@@ -3835,6 +3836,7 @@ class Client(metaclass=ClientMetaClass):
3835
3836
  templatable: If the runs should be templatable or not.
3836
3837
  tag: Tag to filter by.
3837
3838
  user: The name/ID of the user to filter by.
3839
+ run_metadata: The run_metadata of the run to filter by.
3838
3840
  pipeline: The name/ID of the pipeline to filter by.
3839
3841
  code_repository: Filter by code repository name/ID.
3840
3842
  model: Filter by model name/ID.
@@ -3874,6 +3876,7 @@ class Client(metaclass=ClientMetaClass):
3874
3876
  tag=tag,
3875
3877
  unlisted=unlisted,
3876
3878
  user=user,
3879
+ run_metadata=run_metadata,
3877
3880
  pipeline=pipeline,
3878
3881
  code_repository=code_repository,
3879
3882
  stack=stack,
@@ -4194,7 +4197,7 @@ class Client(metaclass=ClientMetaClass):
4194
4197
  ),
4195
4198
  )
4196
4199
  except RuntimeError:
4197
- pass # Cannot link to step run if called outside of a step
4200
+ pass # Cannot link to step run if called outside a step
4198
4201
  return artifact
4199
4202
 
4200
4203
  def list_artifact_versions(
@@ -4222,6 +4225,7 @@ class Client(metaclass=ClientMetaClass):
4222
4225
  user: Optional[Union[UUID, str]] = None,
4223
4226
  model: Optional[Union[UUID, str]] = None,
4224
4227
  pipeline_run: Optional[Union[UUID, str]] = None,
4228
+ run_metadata: Optional[Dict[str, str]] = None,
4225
4229
  tag: Optional[str] = None,
4226
4230
  hydrate: bool = False,
4227
4231
  ) -> Page[ArtifactVersionResponse]:
@@ -4253,6 +4257,7 @@ class Client(metaclass=ClientMetaClass):
4253
4257
  user: Filter by user name or ID.
4254
4258
  model: Filter by model name or ID.
4255
4259
  pipeline_run: Filter by pipeline run name or ID.
4260
+ run_metadata: Filter by run metadata.
4256
4261
  hydrate: Flag deciding whether to hydrate the output model(s)
4257
4262
  by including metadata fields in the response.
4258
4263
 
@@ -19,13 +19,14 @@ from secrets import token_hex
19
19
  from typing import Any, Dict, List, Optional, Union
20
20
  from uuid import UUID
21
21
 
22
- from pydantic import BaseModel, ConfigDict, Field, model_validator
22
+ from pydantic import BaseModel, ConfigDict, Field, PositiveInt, model_validator
23
23
 
24
24
  from zenml.constants import (
25
25
  DEFAULT_ZENML_JWT_TOKEN_ALGORITHM,
26
26
  DEFAULT_ZENML_JWT_TOKEN_LEEWAY,
27
27
  DEFAULT_ZENML_SERVER_DEVICE_AUTH_POLLING,
28
28
  DEFAULT_ZENML_SERVER_DEVICE_AUTH_TIMEOUT,
29
+ DEFAULT_ZENML_SERVER_GENERIC_API_TOKEN_LIFETIME,
29
30
  DEFAULT_ZENML_SERVER_LOGIN_RATE_LIMIT_DAY,
30
31
  DEFAULT_ZENML_SERVER_LOGIN_RATE_LIMIT_MINUTE,
31
32
  DEFAULT_ZENML_SERVER_MAX_DEVICE_AUTH_ATTEMPTS,
@@ -119,6 +120,8 @@ class ServerConfiguration(BaseModel):
119
120
  time of the JWT tokens issued to clients after they have
120
121
  authenticated with the ZenML server using an OAuth 2.0 device
121
122
  that has been marked as trusted.
123
+ generic_api_token_lifetime: The lifetime in seconds that generic
124
+ short-lived API tokens issued for automation purposes are valid.
122
125
  external_login_url: The login URL of an external authenticator service
123
126
  to use with the `EXTERNAL` authentication scheme.
124
127
  external_user_info_url: The user info URL of an external authenticator
@@ -230,6 +233,12 @@ class ServerConfiguration(BaseModel):
230
233
  deployment.
231
234
  max_request_body_size_in_bytes: The maximum size of the request body in
232
235
  bytes. If not specified, the default value of 256 Kb will be used.
236
+ memcache_max_capacity: The maximum number of entries that the memory
237
+ cache can hold. If not specified, the default value of 1000 will be
238
+ used.
239
+ memcache_default_expiry: The default expiry time in seconds for cache
240
+ entries. If not specified, the default value of 30 seconds will be
241
+ used.
233
242
  """
234
243
 
235
244
  deployment_type: ServerDeploymentType = ServerDeploymentType.OTHER
@@ -257,6 +266,10 @@ class ServerConfiguration(BaseModel):
257
266
  device_expiration_minutes: Optional[int] = None
258
267
  trusted_device_expiration_minutes: Optional[int] = None
259
268
 
269
+ generic_api_token_lifetime: PositiveInt = (
270
+ DEFAULT_ZENML_SERVER_GENERIC_API_TOKEN_LIFETIME
271
+ )
272
+
260
273
  external_login_url: Optional[str] = None
261
274
  external_user_info_url: Optional[str] = None
262
275
  external_cookie_name: Optional[str] = None
@@ -321,6 +334,9 @@ class ServerConfiguration(BaseModel):
321
334
  DEFAULT_ZENML_SERVER_MAX_REQUEST_BODY_SIZE_IN_BYTES
322
335
  )
323
336
 
337
+ memcache_max_capacity: int = 1000
338
+ memcache_default_expiry: int = 30
339
+
324
340
  _deployment_id: Optional[UUID] = None
325
341
 
326
342
  @model_validator(mode="before")
zenml/constants.py CHANGED
@@ -167,9 +167,6 @@ ENV_ZENML_SERVER = "ZENML_SERVER"
167
167
  ENV_ZENML_ENFORCE_TYPE_ANNOTATIONS = "ZENML_ENFORCE_TYPE_ANNOTATIONS"
168
168
  ENV_ZENML_ENABLE_IMPLICIT_AUTH_METHODS = "ZENML_ENABLE_IMPLICIT_AUTH_METHODS"
169
169
  ENV_ZENML_DISABLE_STEP_LOGS_STORAGE = "ZENML_DISABLE_STEP_LOGS_STORAGE"
170
- ENV_ZENML_PIPELINE_API_TOKEN_EXPIRES_MINUTES = (
171
- "ZENML_PIPELINE_API_TOKEN_EXPIRES_MINUTES"
172
- )
173
170
  ENV_ZENML_IGNORE_FAILURE_HOOK = "ZENML_IGNORE_FAILURE_HOOK"
174
171
  ENV_ZENML_CUSTOM_SOURCE_ROOT = "ZENML_CUSTOM_SOURCE_ROOT"
175
172
  ENV_ZENML_WHEEL_PACKAGE_NAME = "ZENML_WHEEL_PACKAGE_NAME"
@@ -270,6 +267,7 @@ ZENML_API_KEY_PREFIX = "ZENKEY_"
270
267
  DEFAULT_ZENML_SERVER_PIPELINE_RUN_AUTH_WINDOW = 60 * 48 # 48 hours
271
268
  DEFAULT_ZENML_SERVER_LOGIN_RATE_LIMIT_MINUTE = 5
272
269
  DEFAULT_ZENML_SERVER_LOGIN_RATE_LIMIT_DAY = 1000
270
+ DEFAULT_ZENML_SERVER_GENERIC_API_TOKEN_LIFETIME = 60 * 60 # 1 hour
273
271
 
274
272
  DEFAULT_ZENML_SERVER_SECURE_HEADERS_HSTS = (
275
273
  "max-age=63072000; includeSubdomains"
@@ -410,10 +408,6 @@ MODEL_METADATA_YAML_FILE_NAME = "model_metadata.yaml"
410
408
 
411
409
  # orchestrator constants
412
410
  ORCHESTRATOR_DOCKER_IMAGE_KEY = "orchestrator"
413
- PIPELINE_API_TOKEN_EXPIRES_MINUTES = handle_int_env_var(
414
- ENV_ZENML_PIPELINE_API_TOKEN_EXPIRES_MINUTES,
415
- default=60 * 24, # 24 hours
416
- )
417
411
 
418
412
  # Secret constants
419
413
  SECRET_VALUES = "values"
zenml/enums.py CHANGED
@@ -245,6 +245,13 @@ class OAuthDeviceStatus(StrEnum):
245
245
  LOCKED = "locked"
246
246
 
247
247
 
248
+ class APITokenType(StrEnum):
249
+ """The API token type."""
250
+
251
+ GENERIC = "generic"
252
+ WORKLOAD = "workload"
253
+
254
+
248
255
  class GenericFilterOps(StrEnum):
249
256
  """Ops for all filters for string values on list methods."""
250
257
 
@@ -253,6 +260,7 @@ class GenericFilterOps(StrEnum):
253
260
  CONTAINS = "contains"
254
261
  STARTSWITH = "startswith"
255
262
  ENDSWITH = "endswith"
263
+ ONEOF = "oneof"
256
264
  GTE = "gte"
257
265
  GT = "gt"
258
266
  LTE = "lte"
zenml/model/utils.py CHANGED
@@ -56,6 +56,11 @@ def log_model_metadata(
56
56
  ValueError: If no model name/version is provided and the function is not
57
57
  called inside a step with configured `model` in decorator.
58
58
  """
59
+ logger.warning(
60
+ "The `log_model_metadata` function is deprecated and will soon be "
61
+ "removed. Please use `log_metadata` instead."
62
+ )
63
+
59
64
  if model_name and model_version:
60
65
  from zenml import Model
61
66
 
@@ -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 StrFilter(
837
- operation=GenericFilterOps(operator),
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} might "
845
- "not be supported for filtering. Defaulting to a string filter."
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
- # Cast the value to string for further comparisons.
1036
- value = str(value)
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(