zenml-nightly 0.58.2.dev20240623__py3-none-any.whl → 0.61.0.dev20240712__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 (249) hide show
  1. README.md +30 -9
  2. RELEASE_NOTES.md +240 -0
  3. zenml/VERSION +1 -1
  4. zenml/actions/base_action.py +177 -174
  5. zenml/actions/pipeline_run/pipeline_run_action.py +28 -23
  6. zenml/analytics/enums.py +3 -0
  7. zenml/artifact_stores/base_artifact_store.py +7 -1
  8. zenml/artifacts/utils.py +13 -10
  9. zenml/cli/__init__.py +28 -0
  10. zenml/cli/artifact.py +1 -2
  11. zenml/cli/integration.py +9 -8
  12. zenml/cli/server.py +6 -0
  13. zenml/cli/service_connectors.py +1 -0
  14. zenml/cli/stack.py +946 -39
  15. zenml/cli/stack_components.py +7 -0
  16. zenml/cli/text_utils.py +35 -1
  17. zenml/cli/utils.py +127 -10
  18. zenml/client.py +257 -72
  19. zenml/config/compiler.py +10 -9
  20. zenml/config/docker_settings.py +33 -14
  21. zenml/constants.py +11 -2
  22. zenml/container_registries/base_container_registry.py +1 -0
  23. zenml/enums.py +7 -0
  24. zenml/event_hub/base_event_hub.py +5 -5
  25. zenml/event_hub/event_hub.py +20 -14
  26. zenml/event_sources/base_event.py +0 -11
  27. zenml/event_sources/base_event_source.py +7 -0
  28. zenml/event_sources/webhooks/base_webhook_event_source.py +1 -4
  29. zenml/exceptions.py +4 -0
  30. zenml/hooks/hook_validators.py +2 -3
  31. zenml/integrations/aws/__init__.py +1 -0
  32. zenml/integrations/azure/__init__.py +1 -0
  33. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +3 -3
  34. zenml/integrations/deepchecks/__init__.py +1 -0
  35. zenml/integrations/discord/__init__.py +1 -0
  36. zenml/integrations/evidently/__init__.py +1 -0
  37. zenml/integrations/facets/__init__.py +1 -0
  38. zenml/integrations/feast/__init__.py +1 -0
  39. zenml/integrations/gcp/__init__.py +3 -1
  40. zenml/integrations/gcp/google_credentials_mixin.py +1 -1
  41. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
  42. zenml/integrations/huggingface/__init__.py +1 -0
  43. zenml/integrations/integration.py +24 -0
  44. zenml/integrations/kubeflow/__init__.py +3 -0
  45. zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
  46. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
  47. zenml/integrations/kubernetes/__init__.py +3 -1
  48. zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
  49. zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
  50. zenml/integrations/langchain/__init__.py +1 -0
  51. zenml/integrations/mlflow/__init__.py +4 -2
  52. zenml/integrations/neural_prophet/__init__.py +1 -0
  53. zenml/integrations/polars/__init__.py +1 -0
  54. zenml/integrations/prodigy/__init__.py +1 -0
  55. zenml/integrations/pycaret/__init__.py +6 -0
  56. zenml/integrations/registry.py +37 -0
  57. zenml/integrations/s3/artifact_stores/s3_artifact_store.py +93 -9
  58. zenml/integrations/seldon/__init__.py +1 -0
  59. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
  60. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
  61. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
  62. zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
  63. zenml/integrations/skypilot_aws/__init__.py +2 -1
  64. zenml/integrations/skypilot_azure/__init__.py +1 -1
  65. zenml/integrations/skypilot_gcp/__init__.py +1 -1
  66. zenml/integrations/skypilot_lambda/__init__.py +1 -1
  67. zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
  68. zenml/integrations/slack/__init__.py +1 -0
  69. zenml/integrations/tekton/__init__.py +1 -0
  70. zenml/integrations/tensorboard/__init__.py +0 -1
  71. zenml/integrations/tensorflow/__init__.py +18 -6
  72. zenml/integrations/wandb/__init__.py +1 -0
  73. zenml/logging/step_logging.py +54 -51
  74. zenml/models/__init__.py +28 -0
  75. zenml/models/v2/core/action.py +276 -0
  76. zenml/models/v2/core/component.py +18 -0
  77. zenml/models/v2/core/model.py +1 -2
  78. zenml/models/v2/core/service_connector.py +17 -0
  79. zenml/models/v2/core/stack.py +31 -0
  80. zenml/models/v2/core/trigger.py +182 -141
  81. zenml/models/v2/misc/full_stack.py +97 -0
  82. zenml/models/v2/misc/stack_deployment.py +86 -0
  83. zenml/new/pipelines/pipeline.py +14 -4
  84. zenml/new/pipelines/pipeline_decorator.py +1 -2
  85. zenml/new/pipelines/run_utils.py +1 -12
  86. zenml/new/steps/step_decorator.py +2 -3
  87. zenml/orchestrators/input_utils.py +3 -6
  88. zenml/pipelines/base_pipeline.py +0 -2
  89. zenml/pipelines/pipeline_decorator.py +1 -2
  90. zenml/stack/stack.py +3 -6
  91. zenml/stack/stack_component.py +4 -0
  92. zenml/stack_deployments/__init__.py +14 -0
  93. zenml/stack_deployments/aws_stack_deployment.py +254 -0
  94. zenml/stack_deployments/gcp_stack_deployment.py +260 -0
  95. zenml/stack_deployments/stack_deployment.py +208 -0
  96. zenml/stack_deployments/utils.py +44 -0
  97. zenml/steps/base_step.py +1 -2
  98. zenml/steps/step_decorator.py +1 -2
  99. zenml/types.py +10 -1
  100. zenml/utils/function_utils.py +1 -1
  101. zenml/utils/pagination_utils.py +7 -5
  102. zenml/utils/pipeline_docker_image_builder.py +117 -73
  103. zenml/utils/pydantic_utils.py +6 -5
  104. zenml/zen_server/cloud_utils.py +18 -3
  105. zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
  106. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
  107. zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
  108. zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
  109. zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
  110. zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
  111. zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
  112. zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
  113. zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
  114. zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
  115. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
  116. zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
  117. zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
  118. zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
  119. zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
  120. zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
  121. zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
  122. zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
  123. zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
  124. zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
  125. zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
  126. zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
  127. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
  128. zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
  129. zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
  130. zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
  131. zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
  132. zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
  133. zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
  134. zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
  135. zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
  136. zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
  137. zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
  138. zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
  139. zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
  140. zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
  141. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
  142. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
  143. zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
  144. zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
  145. zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
  146. zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
  147. zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
  148. zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
  149. zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
  150. zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
  151. zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
  152. zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
  153. zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
  154. zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
  155. zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
  156. zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
  157. zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
  158. zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
  159. zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
  160. zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
  161. zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
  162. zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
  163. zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
  164. zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
  165. zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
  166. zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
  167. zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
  168. zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
  169. zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
  170. zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
  171. zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
  172. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
  173. zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
  174. zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
  175. zenml/zen_server/dashboard/index.html +7 -7
  176. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  177. zenml/zen_server/dashboard_legacy/index.html +1 -1
  178. zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
  179. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  180. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
  181. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.chunk.js.map} +1 -1
  182. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  183. zenml/zen_server/deploy/helm/README.md +2 -2
  184. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
  185. zenml/zen_server/pipeline_deployment/utils.py +57 -44
  186. zenml/zen_server/rbac/models.py +1 -0
  187. zenml/zen_server/rbac/utils.py +22 -1
  188. zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
  189. zenml/zen_server/routers/actions_endpoints.py +324 -0
  190. zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
  191. zenml/zen_server/routers/triggers_endpoints.py +30 -158
  192. zenml/zen_server/routers/workspaces_endpoints.py +64 -0
  193. zenml/zen_server/zen_server_api.py +4 -0
  194. zenml/zen_stores/migrations/utils.py +1 -1
  195. zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
  196. zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
  197. zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
  198. zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
  199. zenml/zen_stores/rest_zen_store.py +248 -8
  200. zenml/zen_stores/schemas/__init__.py +2 -0
  201. zenml/zen_stores/schemas/action_schemas.py +192 -0
  202. zenml/zen_stores/schemas/stack_schemas.py +10 -0
  203. zenml/zen_stores/schemas/step_run_schemas.py +27 -11
  204. zenml/zen_stores/schemas/trigger_schemas.py +43 -50
  205. zenml/zen_stores/schemas/user_schemas.py +10 -2
  206. zenml/zen_stores/schemas/workspace_schemas.py +5 -0
  207. zenml/zen_stores/sql_zen_store.py +540 -36
  208. zenml/zen_stores/zen_store_interface.py +165 -0
  209. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +33 -11
  210. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +213 -193
  211. zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
  212. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
  213. zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
  214. zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
  215. zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
  216. zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
  217. zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
  218. zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
  219. zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
  220. zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
  221. zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
  222. zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
  223. zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
  224. zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
  225. zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
  226. zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
  227. zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
  228. zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
  229. zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
  230. zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
  231. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
  232. zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
  233. zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
  234. zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
  235. zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
  236. zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
  237. zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
  238. zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
  239. zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
  240. zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
  241. zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
  242. zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
  243. zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
  244. zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
  245. zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
  246. zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
  247. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
  248. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
  249. {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
@@ -145,61 +145,64 @@ def fetch_logs(
145
145
  )
146
146
 
147
147
  artifact_store = _load_artifact_store(artifact_store_id, zen_store)
148
- if not artifact_store.isdir(logs_uri):
149
- return _read_file(logs_uri, offset, length)
150
- else:
151
- files = artifact_store.listdir(logs_uri)
152
- if len(files) == 1:
153
- return _read_file(
154
- os.path.join(logs_uri, str(files[0])), offset, length
155
- )
148
+ try:
149
+ if not artifact_store.isdir(logs_uri):
150
+ return _read_file(logs_uri, offset, length)
156
151
  else:
157
- is_negative_offset = offset < 0
158
- files.sort(reverse=is_negative_offset)
159
-
160
- # search for the first file we need to read
161
- latest_file_id = 0
162
- for i, file in enumerate(files):
163
- file_size: int = artifact_store.size(
164
- os.path.join(logs_uri, str(file))
165
- ) # type: ignore[assignment]
166
-
167
- if is_negative_offset:
168
- if file_size >= -offset:
169
- latest_file_id = -(i + 1)
170
- break
152
+ files = artifact_store.listdir(logs_uri)
153
+ if len(files) == 1:
154
+ return _read_file(
155
+ os.path.join(logs_uri, str(files[0])), offset, length
156
+ )
157
+ else:
158
+ is_negative_offset = offset < 0
159
+ files.sort(reverse=is_negative_offset)
160
+
161
+ # search for the first file we need to read
162
+ latest_file_id = 0
163
+ for i, file in enumerate(files):
164
+ file_size: int = artifact_store.size(
165
+ os.path.join(logs_uri, str(file))
166
+ ) # type: ignore[assignment]
167
+
168
+ if is_negative_offset:
169
+ if file_size >= -offset:
170
+ latest_file_id = -(i + 1)
171
+ break
172
+ else:
173
+ offset += file_size
171
174
  else:
172
- offset += file_size
173
- else:
174
- if file_size > offset:
175
- latest_file_id = i
175
+ if file_size > offset:
176
+ latest_file_id = i
177
+ break
178
+ else:
179
+ offset -= file_size
180
+
181
+ # read the files according to pre-filtering
182
+ files.sort()
183
+ ret = []
184
+ for file in files[latest_file_id:]:
185
+ ret.append(
186
+ _read_file(
187
+ os.path.join(logs_uri, str(file)),
188
+ offset,
189
+ length,
190
+ )
191
+ )
192
+ offset = 0
193
+ length -= len(ret[-1])
194
+ if length <= 0:
195
+ # stop further reading, if the whole length is already read
176
196
  break
177
- else:
178
- offset -= file_size
179
-
180
- # read the files according to pre-filtering
181
- files.sort()
182
- ret = []
183
- for file in files[latest_file_id:]:
184
- ret.append(
185
- _read_file(
186
- os.path.join(logs_uri, str(file)),
187
- offset,
188
- length,
197
+
198
+ if not ret:
199
+ raise DoesNotExistException(
200
+ f"Folder '{logs_uri}' is empty in artifact store "
201
+ f"'{artifact_store.name}'."
189
202
  )
190
- )
191
- offset = 0
192
- length -= len(ret[-1])
193
- if length <= 0:
194
- # stop further reading, if the whole length is already read
195
- break
196
-
197
- if not ret:
198
- raise DoesNotExistException(
199
- f"Folder '{logs_uri}' is empty in artifact store "
200
- f"'{artifact_store.name}'."
201
- )
202
- return "".join(ret)
203
+ return "".join(ret)
204
+ finally:
205
+ artifact_store.cleanup()
203
206
 
204
207
 
205
208
  class StepLogsStorage:
zenml/models/__init__.py CHANGED
@@ -51,6 +51,15 @@ from zenml.models.v2.base.filter import (
51
51
  from zenml.models.v2.base.page import Page
52
52
 
53
53
  # V2 Core
54
+ from zenml.models.v2.core.action import (
55
+ ActionFilter,
56
+ ActionRequest,
57
+ ActionResponse,
58
+ ActionResponseBody,
59
+ ActionResponseMetadata,
60
+ ActionResponseResources,
61
+ ActionUpdate,
62
+ )
54
63
  from zenml.models.v2.core.action_flavor import (
55
64
  ActionFlavorResponse,
56
65
  ActionFlavorResponseBody,
@@ -318,6 +327,7 @@ from zenml.models.v2.misc.service_connector_type import (
318
327
  ResourceTypeModel,
319
328
  )
320
329
  from zenml.models.v2.misc.server_models import ServerDatabaseType, ServerModel
330
+ from zenml.models.v2.misc.full_stack import FullStackRequest
321
331
  from zenml.models.v2.core.trigger import (
322
332
  TriggerRequest,
323
333
  TriggerFilter,
@@ -377,10 +387,16 @@ from zenml.models.v2.core.server_settings import (
377
387
  ServerSettingsResponseMetadata,
378
388
  ServerSettingsUpdate,
379
389
  )
390
+ from zenml.models.v2.misc.stack_deployment import (
391
+ DeployedStack,
392
+ StackDeploymentConfig,
393
+ StackDeploymentInfo,
394
+ )
380
395
 
381
396
  # ----------------------------- Forward References -----------------------------
382
397
 
383
398
  # V2
399
+ ActionResponseResources.model_rebuild()
384
400
  APIKeyResponseBody.model_rebuild()
385
401
  ArtifactVersionRequest.model_rebuild()
386
402
  ArtifactVersionResponseBody.model_rebuild()
@@ -395,6 +411,7 @@ EventSourceResponseMetadata.model_rebuild()
395
411
  EventSourceResponseResources.model_rebuild()
396
412
  FlavorResponseBody.model_rebuild()
397
413
  FlavorResponseMetadata.model_rebuild()
414
+ FullStackRequest.model_rebuild()
398
415
  LazyArtifactVersionResponse.model_rebuild()
399
416
  LazyRunMetadataResponse.model_rebuild()
400
417
  ModelResponseBody.model_rebuild()
@@ -470,6 +487,13 @@ __all__ = [
470
487
  "UUIDFilter",
471
488
  "Page",
472
489
  # V2 Core
490
+ "ActionFilter",
491
+ "ActionRequest",
492
+ "ActionResponse",
493
+ "ActionResponseBody",
494
+ "ActionResponseMetadata",
495
+ "ActionResponseResources",
496
+ "ActionUpdate",
473
497
  "ActionFlavorResponse",
474
498
  "ActionFlavorResponseBody",
475
499
  "ActionFlavorResponseMetadata",
@@ -684,11 +708,13 @@ __all__ = [
684
708
  "WorkspaceResponseMetadata",
685
709
  # V2 Misc
686
710
  "AuthenticationMethodModel",
711
+ "DeployedStack",
687
712
  "ServiceConnectorResourcesModel",
688
713
  "ServiceConnectorTypeModel",
689
714
  "ServiceConnectorTypedResourcesModel",
690
715
  "ServiceConnectorRequirements",
691
716
  "ResourceTypeModel",
717
+ "FullStackRequest",
692
718
  "UserAuthModel",
693
719
  "ExternalUserModel",
694
720
  "BuildItem",
@@ -701,6 +727,8 @@ __all__ = [
701
727
  "ServerModel",
702
728
  "ServerDatabaseType",
703
729
  "ServerDeploymentType",
730
+ "StackDeploymentConfig",
731
+ "StackDeploymentInfo",
704
732
  "OAuthDeviceAuthorizationRequest",
705
733
  "OAuthDeviceAuthorizationResponse",
706
734
  "OAuthDeviceTokenRequest",
@@ -0,0 +1,276 @@
1
+ # Copyright (c) ZenML GmbH 2024. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Collection of all models concerning actions."""
15
+
16
+ import copy
17
+ from typing import (
18
+ TYPE_CHECKING,
19
+ Any,
20
+ Dict,
21
+ Optional,
22
+ TypeVar,
23
+ )
24
+ from uuid import UUID
25
+
26
+ from pydantic import Field
27
+
28
+ from zenml.constants import STR_FIELD_MAX_LENGTH
29
+ from zenml.enums import PluginSubType
30
+ from zenml.models.v2.base.base import BaseUpdate
31
+ from zenml.models.v2.base.scoped import (
32
+ WorkspaceScopedFilter,
33
+ WorkspaceScopedRequest,
34
+ WorkspaceScopedResponse,
35
+ WorkspaceScopedResponseBody,
36
+ WorkspaceScopedResponseMetadata,
37
+ WorkspaceScopedResponseResources,
38
+ )
39
+ from zenml.models.v2.core.user import UserResponse
40
+
41
+ if TYPE_CHECKING:
42
+ from zenml.zen_stores.schemas import BaseSchema
43
+
44
+ AnySchema = TypeVar("AnySchema", bound=BaseSchema)
45
+
46
+
47
+ # ------------------ Request Model ------------------
48
+
49
+
50
+ class ActionRequest(WorkspaceScopedRequest):
51
+ """Model for creating a new action."""
52
+
53
+ name: str = Field(
54
+ title="The name of the action.", max_length=STR_FIELD_MAX_LENGTH
55
+ )
56
+ description: str = Field(
57
+ default="",
58
+ title="The description of the action",
59
+ max_length=STR_FIELD_MAX_LENGTH,
60
+ )
61
+ flavor: str = Field(
62
+ title="The flavor of the action.",
63
+ max_length=STR_FIELD_MAX_LENGTH,
64
+ )
65
+ plugin_subtype: PluginSubType = Field(
66
+ title="The subtype of the action.",
67
+ max_length=STR_FIELD_MAX_LENGTH,
68
+ )
69
+ configuration: Dict[str, Any] = Field(
70
+ title="The configuration for the action.",
71
+ )
72
+ service_account_id: UUID = Field(
73
+ title="The service account that is used to execute the action.",
74
+ )
75
+ auth_window: Optional[int] = Field(
76
+ default=None,
77
+ title="The time window in minutes for which the service account is "
78
+ "authorized to execute the action. Set this to 0 to authorize the "
79
+ "service account indefinitely (not recommended). If not set, a "
80
+ "default value defined for each individual action type is used.",
81
+ )
82
+
83
+
84
+ # ------------------ Update Model ------------------
85
+
86
+
87
+ class ActionUpdate(BaseUpdate):
88
+ """Update model for actions."""
89
+
90
+ name: Optional[str] = Field(
91
+ default=None,
92
+ title="The new name for the action.",
93
+ max_length=STR_FIELD_MAX_LENGTH,
94
+ )
95
+ description: Optional[str] = Field(
96
+ default=None,
97
+ title="The new description for the action.",
98
+ max_length=STR_FIELD_MAX_LENGTH,
99
+ )
100
+ configuration: Optional[Dict[str, Any]] = Field(
101
+ default=None,
102
+ title="The configuration for the action.",
103
+ )
104
+ service_account_id: Optional[UUID] = Field(
105
+ default=None,
106
+ title="The service account that is used to execute the action.",
107
+ )
108
+ auth_window: Optional[int] = Field(
109
+ default=None,
110
+ title="The time window in minutes for which the service account is "
111
+ "authorized to execute the action. Set this to 0 to authorize the "
112
+ "service account indefinitely (not recommended). If not set, a "
113
+ "default value defined for each individual action type is used.",
114
+ )
115
+
116
+ @classmethod
117
+ def from_response(cls, response: "ActionResponse") -> "ActionUpdate":
118
+ """Create an update model from a response model.
119
+
120
+ Args:
121
+ response: The response model to create the update model from.
122
+
123
+ Returns:
124
+ The update model.
125
+ """
126
+ return ActionUpdate(
127
+ configuration=copy.deepcopy(response.configuration),
128
+ )
129
+
130
+
131
+ # ------------------ Response Model ------------------
132
+
133
+
134
+ class ActionResponseBody(WorkspaceScopedResponseBody):
135
+ """Response body for actions."""
136
+
137
+ flavor: str = Field(
138
+ title="The flavor of the action.",
139
+ max_length=STR_FIELD_MAX_LENGTH,
140
+ )
141
+ plugin_subtype: PluginSubType = Field(
142
+ title="The subtype of the action.",
143
+ max_length=STR_FIELD_MAX_LENGTH,
144
+ )
145
+
146
+
147
+ class ActionResponseMetadata(WorkspaceScopedResponseMetadata):
148
+ """Response metadata for actions."""
149
+
150
+ description: str = Field(
151
+ default="",
152
+ title="The description of the action.",
153
+ max_length=STR_FIELD_MAX_LENGTH,
154
+ )
155
+ configuration: Dict[str, Any] = Field(
156
+ title="The configuration for the action.",
157
+ )
158
+ auth_window: int = Field(
159
+ title="The time window in minutes for which the service account is "
160
+ "authorized to execute the action."
161
+ )
162
+
163
+
164
+ class ActionResponseResources(WorkspaceScopedResponseResources):
165
+ """Class for all resource models associated with the action entity."""
166
+
167
+ service_account: UserResponse = Field(
168
+ title="The service account that is used to execute the action.",
169
+ )
170
+
171
+
172
+ class ActionResponse(
173
+ WorkspaceScopedResponse[
174
+ ActionResponseBody, ActionResponseMetadata, ActionResponseResources
175
+ ]
176
+ ):
177
+ """Response model for actions."""
178
+
179
+ name: str = Field(
180
+ title="The name of the action.",
181
+ max_length=STR_FIELD_MAX_LENGTH,
182
+ )
183
+
184
+ def get_hydrated_version(self) -> "ActionResponse":
185
+ """Get the hydrated version of this action.
186
+
187
+ Returns:
188
+ An instance of the same entity with the metadata field attached.
189
+ """
190
+ from zenml.client import Client
191
+
192
+ return Client().zen_store.get_action(self.id)
193
+
194
+ # Body and metadata properties
195
+ @property
196
+ def flavor(self) -> str:
197
+ """The `flavor` property.
198
+
199
+ Returns:
200
+ the value of the property.
201
+ """
202
+ return self.get_body().flavor
203
+
204
+ @property
205
+ def plugin_subtype(self) -> PluginSubType:
206
+ """The `plugin_subtype` property.
207
+
208
+ Returns:
209
+ the value of the property.
210
+ """
211
+ return self.get_body().plugin_subtype
212
+
213
+ @property
214
+ def description(self) -> str:
215
+ """The `description` property.
216
+
217
+ Returns:
218
+ the value of the property.
219
+ """
220
+ return self.get_metadata().description
221
+
222
+ @property
223
+ def auth_window(self) -> int:
224
+ """The `auth_window` property.
225
+
226
+ Returns:
227
+ the value of the property.
228
+ """
229
+ return self.get_metadata().auth_window
230
+
231
+ @property
232
+ def configuration(self) -> Dict[str, Any]:
233
+ """The `configuration` property.
234
+
235
+ Returns:
236
+ the value of the property.
237
+ """
238
+ return self.get_metadata().configuration
239
+
240
+ def set_configuration(self, configuration: Dict[str, Any]) -> None:
241
+ """Set the `configuration` property.
242
+
243
+ Args:
244
+ configuration: The value to set.
245
+ """
246
+ self.get_metadata().configuration = configuration
247
+
248
+ # Resource properties
249
+ @property
250
+ def service_account(self) -> "UserResponse":
251
+ """The `service_account` property.
252
+
253
+ Returns:
254
+ the value of the property.
255
+ """
256
+ return self.get_resources().service_account
257
+
258
+
259
+ # ------------------ Filter Model ------------------
260
+
261
+
262
+ class ActionFilter(WorkspaceScopedFilter):
263
+ """Model to enable advanced filtering of all actions."""
264
+
265
+ name: Optional[str] = Field(
266
+ default=None,
267
+ description="Name of the action.",
268
+ )
269
+ flavor: Optional[str] = Field(
270
+ default=None,
271
+ title="The flavor of the action.",
272
+ )
273
+ plugin_subtype: Optional[str] = Field(
274
+ default=None,
275
+ title="The subtype of the action.",
276
+ )
@@ -238,6 +238,24 @@ class ComponentResponse(
238
238
  max_length=STR_FIELD_MAX_LENGTH,
239
239
  )
240
240
 
241
+ def get_analytics_metadata(self) -> Dict[str, Any]:
242
+ """Add the component labels to analytics metadata.
243
+
244
+ Returns:
245
+ Dict of analytics metadata.
246
+ """
247
+ metadata = super().get_analytics_metadata()
248
+
249
+ if self.labels is not None:
250
+ metadata.update(
251
+ {
252
+ label[6:]: value
253
+ for label, value in self.labels.items()
254
+ if label.startswith("zenml:")
255
+ }
256
+ )
257
+ return metadata
258
+
241
259
  def get_hydrated_version(self) -> "ComponentResponse":
242
260
  """Get the hydrated version of this component.
243
261
 
@@ -13,7 +13,6 @@
13
13
  # permissions and limitations under the License.
14
14
  """Models representing models."""
15
15
 
16
- from functools import partial
17
16
  from typing import TYPE_CHECKING, ClassVar, List, Optional, Union
18
17
  from uuid import UUID
19
18
 
@@ -303,7 +302,7 @@ class ModelResponse(
303
302
 
304
303
  client = Client()
305
304
  model_versions = depaginate(
306
- partial(client.list_model_versions, model_name_or_id=self.id)
305
+ client.list_model_versions, model_name_or_id=self.id
307
306
  )
308
307
  return [
309
308
  mv.to_model_class(suppress_class_validation_warnings=True)
@@ -493,6 +493,23 @@ class ServiceConnectorResponse(
493
493
  max_length=STR_FIELD_MAX_LENGTH,
494
494
  )
495
495
 
496
+ def get_analytics_metadata(self) -> Dict[str, Any]:
497
+ """Add the service connector labels to analytics metadata.
498
+
499
+ Returns:
500
+ Dict of analytics metadata.
501
+ """
502
+ metadata = super().get_analytics_metadata()
503
+
504
+ metadata.update(
505
+ {
506
+ label[6:]: value
507
+ for label, value in self.labels.items()
508
+ if label.startswith("zenml:")
509
+ }
510
+ )
511
+ return metadata
512
+
496
513
  def get_hydrated_version(self) -> "ServiceConnectorResponse":
497
514
  """Get the hydrated version of this service connector.
498
515
 
@@ -36,6 +36,7 @@ from zenml.models.v2.core.component import ComponentResponse
36
36
  if TYPE_CHECKING:
37
37
  from sqlalchemy.sql.elements import ColumnElement
38
38
 
39
+
39
40
  # ------------------ Request Model ------------------
40
41
 
41
42
 
@@ -59,6 +60,10 @@ class StackRequest(WorkspaceScopedRequest):
59
60
  title="A mapping of stack component types to the actual"
60
61
  "instances of components of this type.",
61
62
  )
63
+ labels: Optional[Dict[str, Any]] = Field(
64
+ default=None,
65
+ title="The stack labels.",
66
+ )
62
67
 
63
68
  @property
64
69
  def is_valid(self) -> bool:
@@ -109,6 +114,10 @@ class StackUpdate(BaseUpdate):
109
114
  "instances of components of this type.",
110
115
  default=None,
111
116
  )
117
+ labels: Optional[Dict[str, Any]] = Field(
118
+ default=None,
119
+ title="The stack labels.",
120
+ )
112
121
 
113
122
 
114
123
  # ------------------ Response Model ------------------
@@ -134,6 +143,10 @@ class StackResponseMetadata(WorkspaceScopedResponseMetadata):
134
143
  default=None,
135
144
  title="The path to the stack spec used for mlstacks deployments.",
136
145
  )
146
+ labels: Optional[Dict[str, Any]] = Field(
147
+ default=None,
148
+ title="The stack labels.",
149
+ )
137
150
 
138
151
 
139
152
  class StackResponseResources(WorkspaceScopedResponseResources):
@@ -214,6 +227,15 @@ class StackResponse(
214
227
  """
215
228
  metadata = super().get_analytics_metadata()
216
229
  metadata.update({ct: c[0].flavor for ct, c in self.components.items()})
230
+
231
+ if self.labels is not None:
232
+ metadata.update(
233
+ {
234
+ label[6:]: value
235
+ for label, value in self.labels.items()
236
+ if label.startswith("zenml:")
237
+ }
238
+ )
217
239
  return metadata
218
240
 
219
241
  @property
@@ -243,6 +265,15 @@ class StackResponse(
243
265
  """
244
266
  return self.get_metadata().components
245
267
 
268
+ @property
269
+ def labels(self) -> Optional[Dict[str, Any]]:
270
+ """The `labels` property.
271
+
272
+ Returns:
273
+ the value of the property.
274
+ """
275
+ return self.get_metadata().labels
276
+
246
277
 
247
278
  # ------------------ Filter Model ------------------
248
279