zenml-nightly 0.68.1.dev20241106__py3-none-any.whl → 0.70.0.dev20241115__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 (232) 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/external_artifact.py +2 -1
  6. zenml/artifacts/utils.py +138 -79
  7. zenml/cli/base.py +4 -4
  8. zenml/cli/model.py +1 -6
  9. zenml/cli/stack.py +1 -0
  10. zenml/client.py +29 -74
  11. zenml/config/server_config.py +17 -1
  12. zenml/constants.py +2 -7
  13. zenml/data_validators/base_data_validator.py +2 -2
  14. zenml/enums.py +20 -4
  15. zenml/exceptions.py +4 -0
  16. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +20 -18
  17. zenml/integrations/azure/orchestrators/azureml_orchestrator.py +1 -1
  18. zenml/integrations/deepchecks/data_validators/deepchecks_data_validator.py +1 -1
  19. zenml/integrations/evidently/__init__.py +1 -1
  20. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
  21. zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +29 -9
  22. zenml/integrations/tensorboard/visualizers/tensorboard_visualizer.py +60 -54
  23. zenml/integrations/vllm/services/vllm_deployment.py +16 -7
  24. zenml/metadata/lazy_load.py +20 -7
  25. zenml/model/model.py +17 -64
  26. zenml/model/utils.py +5 -0
  27. zenml/models/__init__.py +0 -12
  28. zenml/models/v2/base/filter.py +121 -8
  29. zenml/models/v2/core/artifact_version.py +42 -7
  30. zenml/models/v2/core/model_version.py +26 -5
  31. zenml/models/v2/core/pipeline_run.py +25 -6
  32. zenml/models/v2/core/run_metadata.py +2 -217
  33. zenml/models/v2/core/step_run.py +62 -24
  34. zenml/orchestrators/base_orchestrator.py +12 -1
  35. zenml/orchestrators/input_utils.py +44 -19
  36. zenml/orchestrators/step_launcher.py +4 -3
  37. zenml/orchestrators/step_run_utils.py +19 -15
  38. zenml/orchestrators/step_runner.py +21 -13
  39. zenml/orchestrators/utils.py +45 -26
  40. zenml/stack_deployments/aws_stack_deployment.py +23 -6
  41. zenml/stack_deployments/azure_stack_deployment.py +28 -5
  42. zenml/stack_deployments/gcp_stack_deployment.py +25 -8
  43. zenml/stack_deployments/stack_deployment.py +3 -5
  44. zenml/steps/base_step.py +1 -1
  45. zenml/steps/entrypoint_function_utils.py +3 -5
  46. zenml/steps/step_context.py +3 -2
  47. zenml/steps/utils.py +13 -2
  48. zenml/utils/metadata_utils.py +335 -0
  49. zenml/zen_server/auth.py +221 -3
  50. zenml/zen_server/cache.py +208 -0
  51. zenml/zen_server/dashboard/assets/{404-DT4QRUqN.js → 404-NVXKFp-x.js} +1 -1
  52. zenml/zen_server/dashboard/assets/{@radix-DP6vWzyx.js → @radix-DeK6qiuw.js} +1 -1
  53. zenml/zen_server/dashboard/assets/{@react-router-BMhZulnd.js → @react-router-B3Z5rLr2.js} +1 -1
  54. zenml/zen_server/dashboard/assets/{@reactflow-8U9qNlMR.js → @reactflow-CK0KJUen.js} +2 -2
  55. zenml/zen_server/dashboard/assets/{@tanstack-BUCbhJyH.js → @tanstack-DT5WLu9C.js} +1 -1
  56. zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-DezXKmDf.js +1 -0
  57. zenml/zen_server/dashboard/assets/{CodeSnippet-CqybNv0k.js → CodeSnippet-JzR8CEtw.js} +2 -2
  58. zenml/zen_server/dashboard/assets/{CollapsibleCard-0r_8G2Lj.js → CollapsibleCard-DQW_ktMO.js} +1 -1
  59. zenml/zen_server/dashboard/assets/{Commands-BDjgBQKi.js → Commands-DL2kwkRd.js} +1 -1
  60. zenml/zen_server/dashboard/assets/ComponentBadge-D_g62Wv8.js +1 -0
  61. zenml/zen_server/dashboard/assets/{CopyButton-C745BrKi.js → CopyButton-LNcWaa14.js} +1 -1
  62. zenml/zen_server/dashboard/assets/{CsvVizualization-PpAq0CeZ.js → CsvVizualization-DknpE5ej.js} +5 -5
  63. zenml/zen_server/dashboard/assets/{DialogItem-DcVCZEew.js → DialogItem-Bxf8FuAT.js} +1 -1
  64. zenml/zen_server/dashboard/assets/{DisplayDate-BeXgUG_C.js → DisplayDate-CDMUcQHS.js} +1 -1
  65. zenml/zen_server/dashboard/assets/{EmptyState-DeK7H4pr.js → EmptyState-BzdlCwp3.js} +1 -1
  66. zenml/zen_server/dashboard/assets/{Error-BMlzibXj.js → Error-DYflYyps.js} +1 -1
  67. zenml/zen_server/dashboard/assets/ExecutionStatus-C7zyIQKZ.js +1 -0
  68. zenml/zen_server/dashboard/assets/{Helpbox-BLf40fLV.js → Helpbox-oYSGpLqd.js} +1 -1
  69. zenml/zen_server/dashboard/assets/{Infobox-BwisKifi.js → Infobox-Cx4xGoXR.js} +1 -1
  70. zenml/zen_server/dashboard/assets/{InlineAvatar-jEgodSgX.js → InlineAvatar-DiGOWNKF.js} +1 -1
  71. zenml/zen_server/dashboard/assets/{Lock-3lLt1ih0.js → Lock-CYYy18Mm.js} +1 -1
  72. zenml/zen_server/dashboard/assets/{MarkdownVisualization-8O9kTr-2.js → MarkdownVisualization-ylXaAxev.js} +1 -1
  73. zenml/zen_server/dashboard/assets/NestedCollapsible-DYbgyKxK.js +1 -0
  74. zenml/zen_server/dashboard/assets/{NumberBox-T9eELfLZ.js → NumberBox-Dtp3J6g5.js} +1 -1
  75. zenml/zen_server/dashboard/assets/Partials-03iZf8-N.js +1 -0
  76. zenml/zen_server/dashboard/assets/{PasswordChecker-CW0kqY0W.js → PasswordChecker-B0nadgh6.js} +1 -1
  77. zenml/zen_server/dashboard/assets/ProBadge-D_EB8HNo.js +1 -0
  78. zenml/zen_server/dashboard/assets/ProCta-DqNS4v3x.js +1 -0
  79. zenml/zen_server/dashboard/assets/ProviderIcon-Bki2aw8w.js +1 -0
  80. zenml/zen_server/dashboard/assets/{ProviderRadio-BROY1700.js → ProviderRadio-8f43sPD4.js} +1 -1
  81. zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +1 -0
  82. zenml/zen_server/dashboard/assets/RunsBody-07YEO7qI.js +1 -0
  83. zenml/zen_server/dashboard/assets/SearchField-lp1KgU4e.js +1 -0
  84. zenml/zen_server/dashboard/assets/{SecretTooltip-C_qByGWB.js → SecretTooltip-CgnbyeOx.js} +1 -1
  85. zenml/zen_server/dashboard/assets/{SetPassword-7pRB00El.js → SetPassword-CpP418A2.js} +1 -1
  86. zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +1 -0
  87. zenml/zen_server/dashboard/assets/Tabs-BktHkCJJ.js +1 -0
  88. zenml/zen_server/dashboard/assets/Tick-BlMoIlJT.js +1 -0
  89. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DckMEkFf.js → UpdatePasswordSchemas-Sc0A0pP-.js} +1 -1
  90. zenml/zen_server/dashboard/assets/{UsageReason-DVceN14P.js → UsageReason-YYduL4fj.js} +1 -1
  91. zenml/zen_server/dashboard/assets/{WizardFooter-CW0Cvd70.js → WizardFooter-dgmizSJC.js} +1 -1
  92. zenml/zen_server/dashboard/assets/all-pipeline-runs-query-D-c2G6lV.js +1 -0
  93. zenml/zen_server/dashboard/assets/check-DloQpStc.js +1 -0
  94. zenml/zen_server/dashboard/assets/{check-circle-Dwxliy1Z.js → check-circle-jNbX5-sR.js} +1 -1
  95. zenml/zen_server/dashboard/assets/{chevron-down-8wLBS5pQ.js → chevron-down-6JyMkfjR.js} +1 -1
  96. zenml/zen_server/dashboard/assets/{chevron-right-double-DoD8iXWM.js → chevron-right-double-D7ojK9Co.js} +1 -1
  97. zenml/zen_server/dashboard/assets/{code-browser-CZUQs3Wa.js → code-browser-CUFUIHfp.js} +1 -1
  98. zenml/zen_server/dashboard/assets/{copy-CaSMXwiU.js → copy-C8XQA2Ug.js} +1 -1
  99. zenml/zen_server/dashboard/assets/create-stack-DM_JPgef.js +1 -0
  100. zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +1 -0
  101. zenml/zen_server/dashboard/assets/{docker-BFNgg-z3.js → docker-BdA9vrnW.js} +1 -1
  102. zenml/zen_server/dashboard/assets/{dots-horizontal-DK5Duzx4.js → dots-horizontal-otGBOSDJ.js} +1 -1
  103. zenml/zen_server/dashboard/assets/{form-schemas-1AyOCx90.js → form-schemas-K6FYKjwa.js} +1 -1
  104. zenml/zen_server/dashboard/assets/{gcp-7M2Yf3ZK.js → gcp-CFtm4BA7.js} +1 -1
  105. zenml/zen_server/dashboard/assets/{help-Dam461dC.js → help-Cc9bBIJH.js} +1 -1
  106. zenml/zen_server/dashboard/assets/index-B1mVPYxf.js +1 -0
  107. zenml/zen_server/dashboard/assets/index-BAkC7FXi.js +1 -0
  108. zenml/zen_server/dashboard/assets/{index-QQb7wQEC.js → index-CCOPpudF.js} +8 -8
  109. zenml/zen_server/dashboard/assets/index-CEV4Cvaf.js +1 -0
  110. zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +1 -0
  111. zenml/zen_server/dashboard/assets/{index-BVJ8n2-j.js → index-Uu49AX48.js} +1 -1
  112. zenml/zen_server/dashboard/assets/{index.esm-cuVep_NJ.js → index.esm-Dy6Z9Ung.js} +1 -1
  113. zenml/zen_server/dashboard/assets/{kubernetes--g7r02Zu.js → kubernetes-B2wmAJ1d.js} +1 -1
  114. zenml/zen_server/dashboard/assets/{layout-DCSYN7-C.js → layout-BtHBmE4w.js} +1 -1
  115. zenml/zen_server/dashboard/assets/{link-external-CBEk6kEG.js → link-external-b9AXw_sW.js} +1 -1
  116. zenml/zen_server/dashboard/assets/{login-mutation-DTcAFP1l.js → login-mutation-hf-lK87O.js} +1 -1
  117. zenml/zen_server/dashboard/assets/{logs-D5bdJGur.js → logs-WMSM52RF.js} +1 -1
  118. zenml/zen_server/dashboard/assets/{not-found-Cc-JkRH2.js → not-found-BGirLjU-.js} +1 -1
  119. zenml/zen_server/dashboard/assets/{package-Cs35Szwh.js → package-C6uypY4h.js} +1 -1
  120. zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +1 -0
  121. zenml/zen_server/dashboard/assets/{page-DH_Z7iW1.js → page-6m6yHHlE.js} +1 -1
  122. zenml/zen_server/dashboard/assets/page-BDigxVpo.js +1 -0
  123. zenml/zen_server/dashboard/assets/page-BR68V0V1.js +1 -0
  124. zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +1 -0
  125. zenml/zen_server/dashboard/assets/{page-BQQKaabe.js → page-BU7huvKw.js} +3 -3
  126. zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +1 -0
  127. zenml/zen_server/dashboard/assets/page-C00YAkaB.js +1 -0
  128. zenml/zen_server/dashboard/assets/{page-N4qoPHKb.js → page-CD-DcWoy.js} +1 -1
  129. zenml/zen_server/dashboard/assets/page-COXXJj1k.js +1 -0
  130. zenml/zen_server/dashboard/assets/page-CbpvrsDL.js +1 -0
  131. zenml/zen_server/dashboard/assets/page-CdMWnQak.js +1 -0
  132. zenml/zen_server/dashboard/assets/{page-ClUVkl-O.js → page-CjGdWY13.js} +1 -1
  133. zenml/zen_server/dashboard/assets/page-CwxrFarU.js +1 -0
  134. zenml/zen_server/dashboard/assets/{page-DLixvR-7.js → page-D01JhjQB.js} +1 -1
  135. zenml/zen_server/dashboard/assets/page-D6uU2ax4.js +1 -0
  136. zenml/zen_server/dashboard/assets/page-D7S3aCbF.js +1 -0
  137. zenml/zen_server/dashboard/assets/{page-9yplj5JT.js → page-DLC-bNBP.js} +1 -1
  138. zenml/zen_server/dashboard/assets/page-DXSTpqRD.js +1 -0
  139. zenml/zen_server/dashboard/assets/{page-DzpVUZ8f.js → page-DakHVWXF.js} +1 -1
  140. zenml/zen_server/dashboard/assets/{page-DIOXwhiD.js → page-Df-Fw0aq.js} +1 -1
  141. zenml/zen_server/dashboard/assets/{page-B-y2XKIc.js → page-DfbXf_8s.js} +1 -1
  142. zenml/zen_server/dashboard/assets/page-DjRJCGb3.js +1 -0
  143. zenml/zen_server/dashboard/assets/{page-C0N5q3l7.js → page-Djikxq_S.js} +1 -1
  144. zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +3 -0
  145. zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +1 -0
  146. zenml/zen_server/dashboard/assets/page-Vcxara9U.js +1 -0
  147. zenml/zen_server/dashboard/assets/page-Xynx4btY.js +14 -0
  148. zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +1 -0
  149. zenml/zen_server/dashboard/assets/page-yYC9OI-E.js +1 -0
  150. zenml/zen_server/dashboard/assets/{persist-DNb5cdrU.js → persist-Coz7ZWvz.js} +1 -1
  151. zenml/zen_server/dashboard/assets/{persist-CP0JmYZ4.js → persist-GjC8PZoC.js} +1 -1
  152. zenml/zen_server/dashboard/assets/{plus-C9IxgN2M.js → plus-tf1V2hTJ.js} +1 -1
  153. zenml/zen_server/dashboard/assets/{refresh-BVu22P_C.js → refresh-BjOeWlEq.js} +1 -1
  154. zenml/zen_server/dashboard/assets/{rocket-CONEmRmB.js → rocket-DjT2cDvG.js} +1 -1
  155. zenml/zen_server/dashboard/assets/sharedSchema-CQb14VSr.js +14 -0
  156. zenml/zen_server/dashboard/assets/stack-detail-query-OPEW-cDJ.js +1 -0
  157. zenml/zen_server/dashboard/assets/{tick-circle-CM1ZScbQ.js → tick-circle-BEX_Tp4v.js} +1 -1
  158. zenml/zen_server/dashboard/assets/{trash-DkJHMOg7.js → trash-arLUMWMS.js} +1 -1
  159. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-DsU8cNVl.js → update-server-settings-mutation-LwuQfHYn.js} +1 -1
  160. zenml/zen_server/dashboard/assets/upgrade-form-CwRHBuXB.webp +0 -0
  161. zenml/zen_server/dashboard/assets/url-CkvKAnwF.js +1 -0
  162. zenml/zen_server/dashboard/assets/{zod-D89GC_vc.js → zod-BwEbpOxH.js} +1 -1
  163. zenml/zen_server/dashboard/index.html +7 -7
  164. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  165. zenml/zen_server/deploy/helm/README.md +2 -2
  166. zenml/zen_server/exceptions.py +2 -0
  167. zenml/zen_server/jwt.py +30 -13
  168. zenml/zen_server/rbac/endpoint_utils.py +43 -1
  169. zenml/zen_server/rbac/utils.py +0 -2
  170. zenml/zen_server/routers/artifact_version_endpoints.py +27 -1
  171. zenml/zen_server/routers/auth_endpoints.py +134 -102
  172. zenml/zen_server/routers/logs_endpoints.py +66 -0
  173. zenml/zen_server/routers/workspaces_endpoints.py +3 -4
  174. zenml/zen_server/template_execution/utils.py +14 -16
  175. zenml/zen_server/utils.py +27 -0
  176. zenml/zen_server/zen_server_api.py +6 -3
  177. zenml/zen_stores/migrations/versions/0.70.0_release.py +23 -0
  178. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +99 -0
  179. zenml/zen_stores/migrations/versions/904464ea4041_add_pipeline_model_run_unique_constraints.py +192 -0
  180. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +33 -0
  181. zenml/zen_stores/rest_zen_store.py +68 -64
  182. zenml/zen_stores/schemas/artifact_schemas.py +8 -1
  183. zenml/zen_stores/schemas/model_schemas.py +27 -3
  184. zenml/zen_stores/schemas/pipeline_run_schemas.py +6 -1
  185. zenml/zen_stores/schemas/pipeline_schemas.py +8 -2
  186. zenml/zen_stores/schemas/run_metadata_schemas.py +1 -48
  187. zenml/zen_stores/schemas/step_run_schemas.py +18 -10
  188. zenml/zen_stores/sql_zen_store.py +283 -219
  189. zenml/zen_stores/zen_store_interface.py +15 -42
  190. {zenml_nightly-0.68.1.dev20241106.dist-info → zenml_nightly-0.70.0.dev20241115.dist-info}/METADATA +2 -2
  191. {zenml_nightly-0.68.1.dev20241106.dist-info → zenml_nightly-0.70.0.dev20241115.dist-info}/RECORD +194 -179
  192. zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-C6N2rGrB.js +0 -1
  193. zenml/zen_server/dashboard/assets/ComponentBadge-DUiEYJHu.js +0 -1
  194. zenml/zen_server/dashboard/assets/ComponentFallbackDialog-BFoH5K4V.js +0 -1
  195. zenml/zen_server/dashboard/assets/ComponentIcon-CAIoUis2.js +0 -1
  196. zenml/zen_server/dashboard/assets/Partials-YPBB3V4q.js +0 -1
  197. zenml/zen_server/dashboard/assets/ProviderIcon-Bb3Xha5A.js +0 -1
  198. zenml/zen_server/dashboard/assets/RunSelector-DCiL3M1c.js +0 -1
  199. zenml/zen_server/dashboard/assets/SearchField-DfUiGFVd.js +0 -1
  200. zenml/zen_server/dashboard/assets/Tick-CykQFPj2.js +0 -1
  201. zenml/zen_server/dashboard/assets/cloud-only-B-s_HMDm.js +0 -1
  202. zenml/zen_server/dashboard/assets/codespaces-BitYDX9d.gif +0 -0
  203. zenml/zen_server/dashboard/assets/create-stack-CEmaPZ4c.js +0 -1
  204. zenml/zen_server/dashboard/assets/delete-run-D-LKbGyz.js +0 -1
  205. zenml/zen_server/dashboard/assets/index-Bpmj40BI.js +0 -1
  206. zenml/zen_server/dashboard/assets/index-CbU4Ln_E.css +0 -1
  207. zenml/zen_server/dashboard/assets/index-DKPhqP2B.js +0 -1
  208. zenml/zen_server/dashboard/assets/page-BBpOxVcY.js +0 -1
  209. zenml/zen_server/dashboard/assets/page-BRInM1Lg.js +0 -1
  210. zenml/zen_server/dashboard/assets/page-BjjlMk7s.js +0 -1
  211. zenml/zen_server/dashboard/assets/page-Bvd7YH2A.js +0 -1
  212. zenml/zen_server/dashboard/assets/page-CT3Nep8W.js +0 -1
  213. zenml/zen_server/dashboard/assets/page-C_f47pBf.js +0 -1
  214. zenml/zen_server/dashboard/assets/page-Cmv8C_yM.js +0 -3
  215. zenml/zen_server/dashboard/assets/page-CyN2bdWG.js +0 -1
  216. zenml/zen_server/dashboard/assets/page-CzzXH4fs.js +0 -1
  217. zenml/zen_server/dashboard/assets/page-DTlGjgnG.js +0 -1
  218. zenml/zen_server/dashboard/assets/page-Dbpl86h0.js +0 -1
  219. zenml/zen_server/dashboard/assets/page-Ddgy6kDS.js +0 -1
  220. zenml/zen_server/dashboard/assets/page-DtCAfBLy.js +0 -9
  221. zenml/zen_server/dashboard/assets/page-Dx16z7nA.js +0 -1
  222. zenml/zen_server/dashboard/assets/page-McUyYbo1.js +0 -1
  223. zenml/zen_server/dashboard/assets/page-T1P3RyAR.js +0 -1
  224. zenml/zen_server/dashboard/assets/page-bKaULTGG.js +0 -1
  225. zenml/zen_server/dashboard/assets/page-sbXUJy9t.js +0 -1
  226. zenml/zen_server/dashboard/assets/sharedSchema-TMLu-nYQ.js +0 -14
  227. zenml/zen_server/dashboard/assets/stack-detail-query-xmYxSsUY.js +0 -1
  228. zenml/zen_server/dashboard/assets/url-D5le3J4q.js +0 -1
  229. zenml/zen_server/routers/run_metadata_endpoints.py +0 -96
  230. {zenml_nightly-0.68.1.dev20241106.dist-info → zenml_nightly-0.70.0.dev20241115.dist-info}/LICENSE +0 -0
  231. {zenml_nightly-0.68.1.dev20241106.dist-info → zenml_nightly-0.70.0.dev20241115.dist-info}/WHEEL +0 -0
  232. {zenml_nightly-0.68.1.dev20241106.dist-info → zenml_nightly-0.70.0.dev20241115.dist-info}/entry_points.txt +0 -0
@@ -87,41 +87,44 @@ class TensorboardVisualizer:
87
87
  *args: Additional arguments.
88
88
  **kwargs: Additional keyword arguments.
89
89
  """
90
- for _, artifact_view in object.outputs.items():
91
- # filter out anything but model artifacts
92
- if artifact_view.type == ArtifactType.MODEL:
93
- logdir = os.path.dirname(artifact_view.uri)
94
-
95
- # first check if a TensorBoard server is already running for
96
- # the same logdir location and use that one
97
- running_server = self.find_running_tensorboard_server(logdir)
98
- if running_server:
99
- self.visualize_tensorboard(running_server.port, height)
100
- return
101
-
102
- if sys.platform == "win32":
103
- # Daemon service functionality is currently not supported
104
- # on Windows
105
- print(
106
- "You can run:\n"
107
- f"[italic green] tensorboard --logdir {logdir}"
108
- "[/italic green]\n"
109
- "...to visualize the TensorBoard logs for your trained model."
90
+ for output in object.outputs.values():
91
+ for artifact_view in output:
92
+ # filter out anything but model artifacts
93
+ if artifact_view.type == ArtifactType.MODEL:
94
+ logdir = os.path.dirname(artifact_view.uri)
95
+
96
+ # first check if a TensorBoard server is already running for
97
+ # the same logdir location and use that one
98
+ running_server = self.find_running_tensorboard_server(
99
+ logdir
110
100
  )
111
- else:
112
- # start a new TensorBoard server
113
- service = TensorboardService(
114
- TensorboardServiceConfig(
115
- logdir=logdir,
116
- name=f"zenml-tensorboard-{logdir}",
101
+ if running_server:
102
+ self.visualize_tensorboard(running_server.port, height)
103
+ return
104
+
105
+ if sys.platform == "win32":
106
+ # Daemon service functionality is currently not supported
107
+ # on Windows
108
+ print(
109
+ "You can run:\n"
110
+ f"[italic green] tensorboard --logdir {logdir}"
111
+ "[/italic green]\n"
112
+ "...to visualize the TensorBoard logs for your trained model."
117
113
  )
118
- )
119
- service.start(timeout=60)
120
- if service.endpoint.status.port:
121
- self.visualize_tensorboard(
122
- service.endpoint.status.port, height
114
+ else:
115
+ # start a new TensorBoard server
116
+ service = TensorboardService(
117
+ TensorboardServiceConfig(
118
+ logdir=logdir,
119
+ name=f"zenml-tensorboard-{logdir}",
120
+ )
123
121
  )
124
- return
122
+ service.start(timeout=60)
123
+ if service.endpoint.status.port:
124
+ self.visualize_tensorboard(
125
+ service.endpoint.status.port, height
126
+ )
127
+ return
125
128
 
126
129
  def visualize_tensorboard(
127
130
  self,
@@ -154,31 +157,34 @@ class TensorboardVisualizer:
154
157
  Args:
155
158
  object: StepRunResponseModel fetched from get_step().
156
159
  """
157
- for _, artifact_view in object.outputs.items():
158
- # filter out anything but model artifacts
159
- if artifact_view.type == ArtifactType.MODEL:
160
- logdir = os.path.dirname(artifact_view.uri)
161
-
162
- # first check if a TensorBoard server is already running for
163
- # the same logdir location and use that one
164
- running_server = self.find_running_tensorboard_server(logdir)
165
- if not running_server:
166
- return
160
+ for output in object.outputs.values():
161
+ for artifact_view in output:
162
+ # filter out anything but model artifacts
163
+ if artifact_view.type == ArtifactType.MODEL:
164
+ logdir = os.path.dirname(artifact_view.uri)
165
+
166
+ # first check if a TensorBoard server is already running for
167
+ # the same logdir location and use that one
168
+ running_server = self.find_running_tensorboard_server(
169
+ logdir
170
+ )
171
+ if not running_server:
172
+ return
167
173
 
168
- logger.debug(
169
- "Stopping tensorboard server with PID '%d' ...",
170
- running_server.pid,
171
- )
172
- try:
173
- p = psutil.Process(running_server.pid)
174
- except psutil.Error:
175
- logger.error(
176
- "Could not find process for PID '%d' ...",
174
+ logger.debug(
175
+ "Stopping tensorboard server with PID '%d' ...",
177
176
  running_server.pid,
178
177
  )
179
- continue
180
- p.kill()
181
- return
178
+ try:
179
+ p = psutil.Process(running_server.pid)
180
+ except psutil.Error:
181
+ logger.error(
182
+ "Could not find process for PID '%d' ...",
183
+ running_server.pid,
184
+ )
185
+ continue
186
+ p.kill()
187
+ return
182
188
 
183
189
 
184
190
  def get_step(pipeline_name: str, step_name: str) -> "StepRunResponse":
@@ -13,6 +13,7 @@
13
13
  # permissions and limitations under the License.
14
14
  """Implementation of the vLLM Inference Server Service."""
15
15
 
16
+ import argparse
16
17
  import os
17
18
  from typing import Any, List, Optional, Union
18
19
 
@@ -137,15 +138,23 @@ class VLLMDeploymentService(LocalDaemonService, BaseDeploymentService):
137
138
  self.endpoint.prepare_for_start()
138
139
 
139
140
  import uvloop
140
- from vllm.entrypoints.openai.api_server import run_server
141
- from vllm.entrypoints.openai.cli_args import make_arg_parser
142
- from vllm.utils import FlexibleArgumentParser
141
+ from vllm.entrypoints.openai.api_server import (
142
+ run_server,
143
+ )
144
+ from vllm.entrypoints.openai.cli_args import (
145
+ make_arg_parser,
146
+ )
147
+ from vllm.utils import (
148
+ FlexibleArgumentParser,
149
+ )
143
150
 
144
151
  try:
145
- parser = make_arg_parser(FlexibleArgumentParser())
146
- args = parser.parse_args()
152
+ parser: argparse.ArgumentParser = make_arg_parser(
153
+ FlexibleArgumentParser()
154
+ )
155
+ args: argparse.Namespace = parser.parse_args()
147
156
  # Override port with the available port
148
- self.config.port = self.endpoint.status.port
157
+ self.config.port = self.endpoint.status.port or self.config.port
149
158
  # Update the arguments in place
150
159
  args.__dict__.update(self.config.model_dump())
151
160
  uvloop.run(run_server(args=args))
@@ -161,7 +170,7 @@ class VLLMDeploymentService(LocalDaemonService, BaseDeploymentService):
161
170
  """
162
171
  if not self.is_running:
163
172
  return None
164
- return self.endpoint.prediction_url_path
173
+ return self.endpoint.prediction_url
165
174
 
166
175
  def predict(self, data: "Any") -> "Any":
167
176
  """Make a prediction using the service.
@@ -13,10 +13,25 @@
13
13
  # permissions and limitations under the License.
14
14
  """Run Metadata Lazy Loader definition."""
15
15
 
16
- from typing import TYPE_CHECKING, Optional
16
+ from typing import Optional
17
17
 
18
- if TYPE_CHECKING:
19
- from zenml.models import RunMetadataResponse
18
+ from pydantic import BaseModel
19
+
20
+ from zenml.metadata.metadata_types import MetadataType
21
+
22
+
23
+ class LazyRunMetadataResponse(BaseModel):
24
+ """Lazy run metadata response.
25
+
26
+ Used if the run metadata is accessed from the model in
27
+ a pipeline context available only during pipeline compilation.
28
+ """
29
+
30
+ lazy_load_artifact_name: Optional[str] = None
31
+ lazy_load_artifact_version: Optional[str] = None
32
+ lazy_load_metadata_name: Optional[str] = None
33
+ lazy_load_model_name: str
34
+ lazy_load_model_version: Optional[str] = None
20
35
 
21
36
 
22
37
  class RunMetadataLazyGetter:
@@ -47,7 +62,7 @@ class RunMetadataLazyGetter:
47
62
  self._lazy_load_artifact_name = _lazy_load_artifact_name
48
63
  self._lazy_load_artifact_version = _lazy_load_artifact_version
49
64
 
50
- def __getitem__(self, key: str) -> "RunMetadataResponse":
65
+ def __getitem__(self, key: str) -> MetadataType:
51
66
  """Get the metadata for the given key.
52
67
 
53
68
  Args:
@@ -56,9 +71,7 @@ class RunMetadataLazyGetter:
56
71
  Returns:
57
72
  The metadata lazy loader wrapper for the given key.
58
73
  """
59
- from zenml.models.v2.core.run_metadata import LazyRunMetadataResponse
60
-
61
- return LazyRunMetadataResponse(
74
+ return LazyRunMetadataResponse( # type: ignore[return-value]
62
75
  lazy_load_model_name=self._lazy_load_model_name,
63
76
  lazy_load_model_version=self._lazy_load_model_version,
64
77
  lazy_load_artifact_name=self._lazy_load_artifact_name,
zenml/model/model.py CHANGED
@@ -14,7 +14,6 @@
14
14
  """Model user facing interface to pass into pipeline or step."""
15
15
 
16
16
  import datetime
17
- import time
18
17
  from typing import (
19
18
  TYPE_CHECKING,
20
19
  Any,
@@ -28,7 +27,6 @@ from uuid import UUID
28
27
 
29
28
  from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, model_validator
30
29
 
31
- from zenml.constants import MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
32
30
  from zenml.enums import MetadataResourceTypes, ModelStages
33
31
  from zenml.exceptions import EntityExistsError
34
32
  from zenml.logger import get_logger
@@ -43,7 +41,6 @@ if TYPE_CHECKING:
43
41
  ModelResponse,
44
42
  ModelVersionResponse,
45
43
  PipelineRunResponse,
46
- RunMetadataResponse,
47
44
  StepRunResponse,
48
45
  )
49
46
 
@@ -349,7 +346,7 @@ class Model(BaseModel):
349
346
  )
350
347
 
351
348
  @property
352
- def run_metadata(self) -> Dict[str, "RunMetadataResponse"]:
349
+ def run_metadata(self) -> Dict[str, "MetadataType"]:
353
350
  """Get model version run metadata.
354
351
 
355
352
  Returns:
@@ -528,14 +525,6 @@ class Model(BaseModel):
528
525
  data["suppress_class_validation_warnings"] = True
529
526
  return data
530
527
 
531
- def _validate_config_in_runtime(self) -> "ModelVersionResponse":
532
- """Validate that config doesn't conflict with runtime environment.
533
-
534
- Returns:
535
- The model version based on configuration.
536
- """
537
- return self._get_or_create_model_version()
538
-
539
528
  def _get_or_create_model(self) -> "ModelResponse":
540
529
  """This method should get or create a model from Model Control Plane.
541
530
 
@@ -679,16 +668,6 @@ class Model(BaseModel):
679
668
  if isinstance(self.version, str):
680
669
  self.version = format_name_template(self.version)
681
670
 
682
- zenml_client = Client()
683
- model_version_request = ModelVersionRequest(
684
- user=zenml_client.active_user.id,
685
- workspace=zenml_client.active_workspace.id,
686
- name=str(self.version) if self.version else None,
687
- description=self.description,
688
- model=model.id,
689
- tags=self.tags,
690
- )
691
- mv_request = ModelVersionRequest.model_validate(model_version_request)
692
671
  try:
693
672
  if self.version or self.model_version_id:
694
673
  model_version = self._get_model_version()
@@ -718,60 +697,34 @@ class Model(BaseModel):
718
697
  " as an example. You can explore model versions using "
719
698
  f"`zenml model version list -n {self.name}` CLI command."
720
699
  )
721
- retries_made = 0
722
- for i in range(MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION):
723
- try:
724
- model_version = (
725
- zenml_client.zen_store.create_model_version(
726
- model_version=mv_request
727
- )
728
- )
729
- break
730
- except EntityExistsError as e:
731
- if i == MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION - 1:
732
- raise RuntimeError(
733
- f"Failed to create model version "
734
- f"`{self.version if self.version else 'new'}` "
735
- f"in model `{self.name}`. Retried {retries_made} times. "
736
- "This could be driven by exceptionally high concurrency of "
737
- "pipeline runs. Please, reach out to us on ZenML Slack for support."
738
- ) from e
739
- # smoothed exponential back-off, it will go as 0.2, 0.3,
740
- # 0.45, 0.68, 1.01, 1.52, 2.28, 3.42, 5.13, 7.69, ...
741
- sleep = 0.2 * 1.5**i
742
- logger.debug(
743
- f"Failed to create new model version for "
744
- f"model `{self.name}`. Retrying in {sleep}..."
745
- )
746
- time.sleep(sleep)
747
- retries_made += 1
748
- self.version = model_version.name
700
+
701
+ client = Client()
702
+ model_version_request = ModelVersionRequest(
703
+ user=client.active_user.id,
704
+ workspace=client.active_workspace.id,
705
+ name=str(self.version) if self.version else None,
706
+ description=self.description,
707
+ model=model.id,
708
+ tags=self.tags,
709
+ )
710
+ model_version = client.zen_store.create_model_version(
711
+ model_version=model_version_request
712
+ )
713
+
749
714
  self._created_model_version = True
750
715
 
751
716
  logger.info(
752
717
  "Created new model version `%s` for model `%s`.",
753
- self.version,
718
+ model_version.name,
754
719
  self.name,
755
720
  )
756
721
 
722
+ self.version = model_version.name
757
723
  self.model_version_id = model_version.id
758
724
  self._model_id = model_version.model.id
759
725
  self._number = model_version.number
760
726
  return model_version
761
727
 
762
- def _merge(self, model: "Model") -> None:
763
- self.license = self.license or model.license
764
- self.description = self.description or model.description
765
- self.audience = self.audience or model.audience
766
- self.use_cases = self.use_cases or model.use_cases
767
- self.limitations = self.limitations or model.limitations
768
- self.trade_offs = self.trade_offs or model.trade_offs
769
- self.ethics = self.ethics or model.ethics
770
- if model.tags is not None:
771
- self.tags = list(
772
- {t for t in self.tags or []}.union(set(model.tags))
773
- )
774
-
775
728
  def __hash__(self) -> int:
776
729
  """Get hash of the `Model`.
777
730
 
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
 
zenml/models/__init__.py CHANGED
@@ -239,12 +239,7 @@ from zenml.models.v2.core.run_template import (
239
239
  )
240
240
  from zenml.models.v2.base.base_plugin_flavor import BasePluginFlavorResponse
241
241
  from zenml.models.v2.core.run_metadata import (
242
- LazyRunMetadataResponse,
243
242
  RunMetadataRequest,
244
- RunMetadataFilter,
245
- RunMetadataResponse,
246
- RunMetadataResponseBody,
247
- RunMetadataResponseMetadata,
248
243
  )
249
244
  from zenml.models.v2.core.schedule import (
250
245
  ScheduleRequest,
@@ -418,7 +413,6 @@ EventSourceResponseResources.model_rebuild()
418
413
  FlavorResponseBody.model_rebuild()
419
414
  FlavorResponseMetadata.model_rebuild()
420
415
  LazyArtifactVersionResponse.model_rebuild()
421
- LazyRunMetadataResponse.model_rebuild()
422
416
  ModelResponseBody.model_rebuild()
423
417
  ModelResponseMetadata.model_rebuild()
424
418
  ModelVersionResponseBody.model_rebuild()
@@ -444,8 +438,6 @@ RunTemplateResponseBody.model_rebuild()
444
438
  RunTemplateResponseMetadata.model_rebuild()
445
439
  RunTemplateResponseResources.model_rebuild()
446
440
  RunTemplateResponseBody.model_rebuild()
447
- RunMetadataResponseBody.model_rebuild()
448
- RunMetadataResponseMetadata.model_rebuild()
449
441
  ScheduleResponseBody.model_rebuild()
450
442
  ScheduleResponseMetadata.model_rebuild()
451
443
  SecretResponseBody.model_rebuild()
@@ -637,10 +629,6 @@ __all__ = [
637
629
  "RunTemplateResponseResources",
638
630
  "RunTemplateFilter",
639
631
  "RunMetadataRequest",
640
- "RunMetadataFilter",
641
- "RunMetadataResponse",
642
- "RunMetadataResponseBody",
643
- "RunMetadataResponseMetadata",
644
632
  "ScheduleRequest",
645
633
  "ScheduleUpdate",
646
634
  "ScheduleFilter",
@@ -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