zenml-nightly 0.58.2.dev20240626__py3-none-any.whl → 0.62.0.dev20240726__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 (266) hide show
  1. README.md +31 -10
  2. RELEASE_NOTES.md +280 -0
  3. zenml/VERSION +1 -1
  4. zenml/__init__.py +2 -0
  5. zenml/analytics/enums.py +3 -0
  6. zenml/cli/__init__.py +28 -0
  7. zenml/cli/artifact.py +1 -2
  8. zenml/cli/integration.py +9 -8
  9. zenml/cli/server.py +6 -0
  10. zenml/cli/stack.py +812 -39
  11. zenml/cli/stack_components.py +9 -0
  12. zenml/cli/text_utils.py +35 -1
  13. zenml/cli/utils.py +127 -10
  14. zenml/client.py +23 -14
  15. zenml/config/docker_settings.py +8 -5
  16. zenml/constants.py +13 -1
  17. zenml/container_registries/base_container_registry.py +1 -0
  18. zenml/enums.py +23 -0
  19. zenml/event_hub/event_hub.py +5 -8
  20. zenml/integrations/__init__.py +1 -0
  21. zenml/integrations/aws/__init__.py +1 -0
  22. zenml/integrations/azure/__init__.py +3 -2
  23. zenml/integrations/constants.py +1 -0
  24. zenml/integrations/databricks/__init__.py +52 -0
  25. zenml/integrations/databricks/flavors/__init__.py +30 -0
  26. zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
  27. zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +147 -0
  28. zenml/integrations/databricks/model_deployers/__init__.py +20 -0
  29. zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
  30. zenml/integrations/databricks/orchestrators/__init__.py +20 -0
  31. zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +497 -0
  32. zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
  33. zenml/integrations/databricks/services/__init__.py +19 -0
  34. zenml/integrations/databricks/services/databricks_deployment.py +407 -0
  35. zenml/integrations/databricks/utils/__init__.py +14 -0
  36. zenml/integrations/databricks/utils/databricks_utils.py +87 -0
  37. zenml/integrations/deepchecks/__init__.py +1 -0
  38. zenml/integrations/discord/__init__.py +1 -0
  39. zenml/integrations/evidently/__init__.py +1 -0
  40. zenml/integrations/facets/__init__.py +1 -0
  41. zenml/integrations/feast/__init__.py +1 -0
  42. zenml/integrations/gcp/__init__.py +3 -1
  43. zenml/integrations/gcp/google_credentials_mixin.py +1 -1
  44. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
  45. zenml/integrations/great_expectations/data_validators/ge_data_validator.py +12 -8
  46. zenml/integrations/huggingface/__init__.py +1 -0
  47. zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +88 -3
  48. zenml/integrations/huggingface/steps/accelerate_runner.py +1 -7
  49. zenml/integrations/integration.py +24 -0
  50. zenml/integrations/kubeflow/__init__.py +3 -0
  51. zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
  52. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
  53. zenml/integrations/kubernetes/__init__.py +3 -1
  54. zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
  55. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +1 -13
  56. zenml/integrations/kubernetes/orchestrators/manifest_utils.py +22 -4
  57. zenml/integrations/kubernetes/pod_settings.py +4 -0
  58. zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
  59. zenml/integrations/langchain/__init__.py +1 -0
  60. zenml/integrations/lightgbm/__init__.py +1 -0
  61. zenml/integrations/mlflow/__init__.py +4 -2
  62. zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +6 -2
  63. zenml/integrations/mlflow/services/mlflow_deployment.py +1 -1
  64. zenml/integrations/neural_prophet/__init__.py +1 -0
  65. zenml/integrations/polars/__init__.py +1 -0
  66. zenml/integrations/prodigy/__init__.py +1 -0
  67. zenml/integrations/pycaret/__init__.py +6 -0
  68. zenml/integrations/registry.py +37 -0
  69. zenml/integrations/s3/artifact_stores/s3_artifact_store.py +17 -6
  70. zenml/integrations/seldon/__init__.py +1 -0
  71. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
  72. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
  73. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
  74. zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
  75. zenml/integrations/skypilot_aws/__init__.py +2 -1
  76. zenml/integrations/skypilot_azure/__init__.py +1 -3
  77. zenml/integrations/skypilot_gcp/__init__.py +1 -1
  78. zenml/integrations/skypilot_lambda/__init__.py +1 -1
  79. zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
  80. zenml/integrations/slack/__init__.py +1 -0
  81. zenml/integrations/tekton/__init__.py +1 -0
  82. zenml/integrations/tensorboard/__init__.py +0 -1
  83. zenml/integrations/tensorflow/__init__.py +18 -6
  84. zenml/integrations/wandb/__init__.py +1 -0
  85. zenml/logging/step_logging.py +34 -35
  86. zenml/materializers/built_in_materializer.py +1 -1
  87. zenml/materializers/cloudpickle_materializer.py +1 -1
  88. zenml/model/model.py +1 -1
  89. zenml/models/__init__.py +11 -0
  90. zenml/models/v2/core/component.py +47 -0
  91. zenml/models/v2/core/model.py +1 -2
  92. zenml/models/v2/core/server_settings.py +0 -20
  93. zenml/models/v2/core/service_connector.py +17 -0
  94. zenml/models/v2/core/stack.py +31 -0
  95. zenml/models/v2/misc/full_stack.py +129 -0
  96. zenml/models/v2/misc/stack_deployment.py +91 -0
  97. zenml/new/pipelines/pipeline.py +1 -1
  98. zenml/new/pipelines/run_utils.py +1 -1
  99. zenml/orchestrators/__init__.py +4 -0
  100. zenml/orchestrators/input_utils.py +3 -6
  101. zenml/orchestrators/step_launcher.py +1 -0
  102. zenml/orchestrators/wheeled_orchestrator.py +147 -0
  103. zenml/service_connectors/service_connector_utils.py +408 -0
  104. zenml/stack/stack.py +3 -6
  105. zenml/stack_deployments/__init__.py +14 -0
  106. zenml/stack_deployments/aws_stack_deployment.py +254 -0
  107. zenml/stack_deployments/azure_stack_deployment.py +179 -0
  108. zenml/stack_deployments/gcp_stack_deployment.py +269 -0
  109. zenml/stack_deployments/stack_deployment.py +218 -0
  110. zenml/stack_deployments/utils.py +48 -0
  111. zenml/steps/base_step.py +7 -5
  112. zenml/utils/function_utils.py +2 -2
  113. zenml/utils/pagination_utils.py +7 -5
  114. zenml/utils/pipeline_docker_image_builder.py +105 -68
  115. zenml/utils/pydantic_utils.py +6 -5
  116. zenml/utils/source_utils.py +4 -1
  117. zenml/zen_server/cloud_utils.py +18 -3
  118. zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-B_YdvmwS.js} +1 -1
  119. zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
  120. zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
  121. zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-l_1hUr1S.js} +2 -2
  122. zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
  123. zenml/zen_server/dashboard/assets/AwarenessChannel-CFg5iX4Z.js +1 -0
  124. zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-Dvkx_82E.js} +2 -2
  125. zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +1 -0
  126. zenml/zen_server/dashboard/assets/Commands-DoN1xrEq.js +1 -0
  127. zenml/zen_server/dashboard/assets/CopyButton-Cr7xYEPb.js +2 -0
  128. zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-Ck-nZ43m.js} +7 -7
  129. zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
  130. zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
  131. zenml/zen_server/dashboard/assets/Error-kLtljEOM.js +1 -0
  132. zenml/zen_server/dashboard/assets/ExecutionStatus-DguLLgTK.js +1 -0
  133. zenml/zen_server/dashboard/assets/Helpbox-BXUMP21n.js +1 -0
  134. zenml/zen_server/dashboard/assets/Infobox-DSt0O-dm.js +1 -0
  135. zenml/zen_server/dashboard/assets/InlineAvatar-xsrsIGE-.js +1 -0
  136. zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
  137. zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +1 -0
  138. zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
  139. zenml/zen_server/dashboard/assets/SetPassword-BXGTWiwj.js +1 -0
  140. zenml/zen_server/dashboard/assets/SuccessStep-DZC60t0x.js +1 -0
  141. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DGvwFWO1.js} +1 -1
  142. zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
  143. zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
  144. zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-CZBOf6JM.js} +1 -1
  145. zenml/zen_server/dashboard/assets/cloud-only-C_yFCAkP.js +1 -0
  146. zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
  148. zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
  149. zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
  150. zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
  151. zenml/zen_server/dashboard/assets/index-BczVOqUf.js +55 -0
  152. zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +1 -0
  153. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
  154. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
  155. zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-CrHrndTI.js} +1 -1
  156. zenml/zen_server/dashboard/assets/logs-D8k8BVFf.js +1 -0
  157. zenml/zen_server/dashboard/assets/not-found-DYa4pC-C.js +1 -0
  158. zenml/zen_server/dashboard/assets/package-B3fWP-Dh.js +1 -0
  159. zenml/zen_server/dashboard/assets/page-1h_sD1jz.js +1 -0
  160. zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-1iL8aMqs.js} +1 -1
  161. zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-2grKx_MY.js} +1 -1
  162. zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +1 -0
  163. zenml/zen_server/dashboard/assets/page-8a4UMKXZ.js +1 -0
  164. zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-B6h3iaHJ.js} +1 -1
  165. zenml/zen_server/dashboard/assets/page-BDns21Iz.js +1 -0
  166. zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-BhgCDInH.js} +2 -2
  167. zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-Bi-wtWiO.js} +2 -2
  168. zenml/zen_server/dashboard/assets/page-BkeAAYwp.js +1 -0
  169. zenml/zen_server/dashboard/assets/page-BkuQDIf-.js +1 -0
  170. zenml/zen_server/dashboard/assets/page-BnaevhnB.js +1 -0
  171. zenml/zen_server/dashboard/assets/page-Bq0YxkLV.js +1 -0
  172. zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +2 -0
  173. zenml/zen_server/dashboard/assets/page-C6-UGEbH.js +1 -0
  174. zenml/zen_server/dashboard/assets/page-CCNRIt_f.js +1 -0
  175. zenml/zen_server/dashboard/assets/page-CHNxpz3n.js +1 -0
  176. zenml/zen_server/dashboard/assets/page-DgorQFqi.js +1 -0
  177. zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +1 -0
  178. zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-MFQyIJd3.js} +1 -1
  179. zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +1 -0
  180. zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +9 -0
  181. zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-uA5prJGY.js} +1 -1
  182. zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +1 -0
  183. zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
  184. zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +1 -0
  185. zenml/zen_server/dashboard/assets/stack-detail-query-Cficsl6d.js +1 -0
  186. zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
  187. zenml/zen_server/dashboard/assets/update-server-settings-mutation-7d8xi1tS.js +1 -0
  188. zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-D7mAQGUM.js} +1 -1
  189. zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
  190. zenml/zen_server/dashboard/index.html +7 -7
  191. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  192. zenml/zen_server/dashboard_legacy/index.html +1 -1
  193. zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.12246c7548e71e2c4438e496360de80c.js} +4 -4
  194. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  195. zenml/zen_server/dashboard_legacy/static/js/main.3b27024b.chunk.js +2 -0
  196. zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.3b27024b.chunk.js.map} +1 -1
  197. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  198. zenml/zen_server/deploy/helm/README.md +2 -2
  199. zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
  200. zenml/zen_server/pipeline_deployment/utils.py +57 -44
  201. zenml/zen_server/rbac/utils.py +10 -2
  202. zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
  203. zenml/zen_server/routers/devices_endpoints.py +4 -1
  204. zenml/zen_server/routers/server_endpoints.py +29 -2
  205. zenml/zen_server/routers/service_connectors_endpoints.py +57 -0
  206. zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
  207. zenml/zen_server/routers/steps_endpoints.py +2 -1
  208. zenml/zen_server/routers/workspaces_endpoints.py +64 -0
  209. zenml/zen_server/zen_server_api.py +2 -0
  210. zenml/zen_stores/migrations/utils.py +1 -1
  211. zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
  212. zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
  213. zenml/zen_stores/migrations/versions/0.62.0_release.py +23 -0
  214. zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
  215. zenml/zen_stores/migrations/versions/b4fca5241eea_migrate_onboarding_state.py +167 -0
  216. zenml/zen_stores/rest_zen_store.py +149 -4
  217. zenml/zen_stores/schemas/component_schemas.py +14 -0
  218. zenml/zen_stores/schemas/server_settings_schemas.py +23 -11
  219. zenml/zen_stores/schemas/stack_schemas.py +10 -0
  220. zenml/zen_stores/schemas/step_run_schemas.py +27 -11
  221. zenml/zen_stores/sql_zen_store.py +450 -6
  222. zenml/zen_stores/zen_store_interface.py +80 -0
  223. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/METADATA +35 -13
  224. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/RECORD +227 -191
  225. zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
  226. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
  227. zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
  228. zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
  229. zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
  230. zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
  231. zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
  232. zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
  233. zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
  234. zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
  235. zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
  236. zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
  237. zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
  238. zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
  239. zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
  240. zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
  241. zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
  242. zenml/zen_server/dashboard/assets/chevron-down-zcvCWmyP.js +0 -1
  243. zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
  244. zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
  245. zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
  246. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
  247. zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
  248. zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
  249. zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
  250. zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
  251. zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
  252. zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
  253. zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
  254. zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
  255. zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
  256. zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
  257. zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
  258. zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
  259. zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
  260. zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
  261. zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
  262. zenml/zen_server/dashboard/assets/update-server-settings-mutation-0Wgz8pUE.js +0 -1
  263. zenml/zen_server/dashboard_legacy/static/js/main.ac2f17d0.chunk.js +0 -2
  264. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/LICENSE +0 -0
  265. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/WHEEL +0 -0
  266. {zenml_nightly-0.58.2.dev20240626.dist-info → zenml_nightly-0.62.0.dev20240726.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,269 @@
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
+ """Functionality to deploy a ZenML stack to GCP."""
15
+
16
+ import re
17
+ from typing import ClassVar, Dict, List
18
+
19
+ from zenml.enums import StackDeploymentProvider
20
+ from zenml.models import StackDeploymentConfig
21
+ from zenml.stack_deployments.stack_deployment import ZenMLCloudStackDeployment
22
+
23
+ GCP_DEPLOYMENT_TYPE = "deployment-manager"
24
+
25
+
26
+ class GCPZenMLCloudStackDeployment(ZenMLCloudStackDeployment):
27
+ """GCP ZenML Cloud Stack Deployment."""
28
+
29
+ provider: ClassVar[StackDeploymentProvider] = StackDeploymentProvider.GCP
30
+ deployment: ClassVar[str] = GCP_DEPLOYMENT_TYPE
31
+
32
+ @classmethod
33
+ def description(cls) -> str:
34
+ """Return a description of the ZenML Cloud Stack Deployment.
35
+
36
+ This will be displayed when the user is prompted to deploy
37
+ the ZenML stack.
38
+
39
+ Returns:
40
+ A MarkDown description of the ZenML Cloud Stack Deployment.
41
+ """
42
+ return """
43
+ Provision and register a basic GCP ZenML stack authenticated and connected to
44
+ all the necessary cloud infrastructure resources required to run pipelines in
45
+ GCP.
46
+ """
47
+
48
+ @classmethod
49
+ def instructions(cls) -> str:
50
+ """Return instructions on how to deploy the ZenML stack to the specified cloud provider.
51
+
52
+ This will be displayed before the user is prompted to deploy the ZenML
53
+ stack.
54
+
55
+ Returns:
56
+ MarkDown instructions on how to deploy the ZenML stack to the
57
+ specified cloud provider.
58
+ """
59
+ return """
60
+ You will be redirected to a GCP Cloud Shell console in your browser where you'll
61
+ be asked to log into your GCP project and then create a Deployment Manager
62
+ deployment to provision the necessary cloud resources for ZenML.
63
+
64
+ **NOTE**: The Deployment Manager deployment will create the following new
65
+ resources in your GCP project. Please ensure you have the necessary permissions
66
+ and are aware of any potential costs:
67
+
68
+ - A GCS bucket registered as a [ZenML artifact store](https://docs.zenml.io/stack-components/artifact-stores/gcp).
69
+ - A Google Artifact Registry registered as a [ZenML container registry](https://docs.zenml.io/stack-components/container-registries/gcp).
70
+ - Vertex AI registered as a [ZenML orchestrator](https://docs.zenml.io/stack-components/orchestrators/vertex).
71
+ - GCP Cloud Build registered as a [ZenML image builder](https://docs.zenml.io/stack-components/image-builders/gcp).
72
+ - A GCP Service Account with the minimum necessary permissions to access the
73
+ above resources.
74
+ - An GCP Service Account access key used to give access to ZenML to connect to
75
+ the above resources through a [ZenML service connector](https://docs.zenml.io/how-to/auth-management/gcp-service-connector).
76
+
77
+ The Deployment Manager deployment will automatically create a GCP Service
78
+ Account secret key and will share it with ZenML to give it permission to access
79
+ the resources created by the stack. You can revoke these permissions at any time
80
+ by deleting the Deployment Manager deployment in the GCP Cloud Console.
81
+
82
+ **Estimated costs**
83
+
84
+ A small training job would cost around: $0.60
85
+
86
+ These are rough estimates and actual costs may vary based on your usage and specific GCP pricing.
87
+ Some services may be eligible for the GCP Free Tier. Use [the GCP Pricing Calculator](https://cloud.google.com/products/calculator)
88
+ for a detailed estimate based on your usage.
89
+
90
+ ⚠️ **The Cloud Shell session will warn you that the ZenML GitHub repository is
91
+ untrusted. We recommend that you review [the contents of the repository](https://github.com/zenml-io/zenml/tree/main/infra/gcp)
92
+ and then check the `Trust repo` checkbox to proceed with the deployment,
93
+ otherwise the Cloud Shell session will not be authenticated to access your
94
+ GCP projects. You will also get a chance to review the scripts that will be
95
+ executed in the Cloud Shell session before proceeding.**
96
+
97
+ 💡 **After the Deployment Manager deployment is complete, you can close the Cloud
98
+ Shell session and return to the CLI to view details about the associated ZenML
99
+ stack automatically registered with ZenML.**
100
+ """
101
+
102
+ @classmethod
103
+ def post_deploy_instructions(cls) -> str:
104
+ """Return instructions on what to do after the deployment is complete.
105
+
106
+ This will be displayed after the deployment is complete.
107
+
108
+ Returns:
109
+ MarkDown instructions on what to do after the deployment is
110
+ complete.
111
+ """
112
+ return """
113
+ The ZenML stack has been successfully deployed and registered. You can delete
114
+ the Deployment Manager deployment at any time to revoke ZenML's access to your
115
+ GCP project and to clean up the resources created by the stack by using
116
+ [the GCP Cloud Console](https://console.cloud.google.com/dm/deployments).
117
+ """
118
+
119
+ @classmethod
120
+ def integrations(cls) -> List[str]:
121
+ """Return the ZenML integrations required for the stack.
122
+
123
+ Returns:
124
+ The list of ZenML integrations that need to be installed for the
125
+ stack to be usable.
126
+ """
127
+ return [
128
+ "gcp",
129
+ ]
130
+
131
+ @classmethod
132
+ def permissions(cls) -> Dict[str, List[str]]:
133
+ """Return the permissions granted to ZenML to access the cloud resources.
134
+
135
+ Returns:
136
+ The permissions granted to ZenML to access the cloud resources, as
137
+ a dictionary grouping permissions by resource.
138
+ """
139
+ return {
140
+ "GCS Bucket": [
141
+ "roles/storage.objectUser",
142
+ ],
143
+ "GCP Artifact Registry": [
144
+ "roles/artifactregistry.createOnPushWriter",
145
+ ],
146
+ "Vertex AI (Client)": [
147
+ "roles/aiplatform.user",
148
+ ],
149
+ "Vertex AI (Jobs)": [
150
+ "roles/aiplatform.serviceAgent",
151
+ ],
152
+ "Cloud Build (Client)": [
153
+ "roles/cloudbuild.builds.editor",
154
+ ],
155
+ }
156
+
157
+ @classmethod
158
+ def locations(cls) -> Dict[str, str]:
159
+ """Return the locations where the ZenML stack can be deployed.
160
+
161
+ Returns:
162
+ The regions where the ZenML stack can be deployed as a map of region
163
+ names to region descriptions.
164
+ """
165
+ # Return a list of all possible GCP regions
166
+
167
+ # Based on the AWS regions listed at
168
+ # https://cloud.google.com/about/locations
169
+ return {
170
+ "Africa (Johannesburg)": "africa-south1",
171
+ "Asia Pacific (Taiwan)": "asia-east1",
172
+ "Asia Pacific (Hong Kong)": "asia-east2",
173
+ "Asia Pacific (Tokyo)": "asia-northeast1",
174
+ "Asia Pacific (Osaka)": "asia-northeast2",
175
+ "Asia Pacific (Seoul)": "asia-northeast3",
176
+ "Asia Pacific (Mumbai)": "asia-south1",
177
+ "Asia Pacific (Delhi)": "asia-south2",
178
+ "Asia Pacific (Singapore)": "asia-southeast1",
179
+ "Asia Pacific (Jakarta)": "asia-southeast2",
180
+ "Australia (Sydney)": "australia-southeast1",
181
+ "Australia (Melbourne)": "australia-southeast2",
182
+ "Europe (Belgium)": "europe-west1",
183
+ "Europe (London)": "europe-west2",
184
+ "Europe (Frankfurt)": "europe-west3",
185
+ "Europe (Netherlands)": "europe-west4",
186
+ "Europe (Zurich)": "europe-west6",
187
+ "Europe (Milan)": "europe-west8",
188
+ "Europe (Paris)": "europe-west9",
189
+ "Europe (Berlin)": "europe-west10",
190
+ "Europe (Turin)": "europe-west12",
191
+ "Europe (Warsaw)": "europe-central2",
192
+ "Europe (Finland)": "europe-north1",
193
+ "Europe (Madrid)": "europe-southwest1",
194
+ "Middle East (Doha)": "me-central1",
195
+ "Middle East (Dubai)": "me-central2",
196
+ "Middle East (Tel Aviv)": "me-west1",
197
+ "North America (Montreal)": "northamerica-northeast1",
198
+ "North America (Toronto)": "northamerica-northeast2",
199
+ "South America (Sao Paulo)": "southamerica-east1",
200
+ "South America (Santiago)": "southamerica-west1",
201
+ "US Central (Iowa)": "us-central1",
202
+ "US East (South Carolina)": "us-east1",
203
+ "US East (Northern Virginia)": "us-east4",
204
+ "US East (Columbus)": "us-east5",
205
+ "US South (Dallas)": "us-south1",
206
+ "US West (Oregon)": "us-west1",
207
+ "US West (Los Angeles)": "us-west2",
208
+ "US West (Salt Lake City)": "us-west3",
209
+ "US West (Las Vegas)": "us-west4",
210
+ }
211
+
212
+ @classmethod
213
+ def skypilot_default_regions(cls) -> Dict[str, str]:
214
+ """Returns the regions supported by default for the Skypilot.
215
+
216
+ Returns:
217
+ The regions supported by default for the Skypilot.
218
+ """
219
+ matcher = re.compile(r"us-.*")
220
+ return {k: v for k, v in cls.locations().items() if matcher.match(v)}
221
+
222
+ def get_deployment_config(
223
+ self,
224
+ ) -> StackDeploymentConfig:
225
+ """Return the configuration to deploy the ZenML stack to the specified cloud provider.
226
+
227
+ The configuration should include:
228
+
229
+ * a cloud provider console URL where the user will be redirected to
230
+ deploy the ZenML stack. The URL should include as many pre-filled
231
+ URL query parameters as possible.
232
+ * a textual description of the URL
233
+ * some deployment providers may require additional configuration
234
+ parameters to be passed to the cloud provider in addition to the
235
+ deployment URL query parameters. Where that is the case, this method
236
+ should also return a string that the user can copy and paste into the
237
+ cloud provider console to deploy the ZenML stack (e.g. a set of
238
+ environment variables, or YAML configuration snippet etc.).
239
+
240
+ Returns:
241
+ The configuration to deploy the ZenML stack to the specified cloud
242
+ provider.
243
+ """
244
+ params = dict(
245
+ cloudshell_git_repo="https://github.com/zenml-io/zenml",
246
+ cloudshell_workspace="infra/gcp",
247
+ cloudshell_open_in_editor="gcp-gar-gcs-vertex.jinja,gcp-gar-gcs-vertex-deploy.sh",
248
+ cloudshell_tutorial="gcp-gar-gcs-vertex.md",
249
+ ephemeral="true",
250
+ )
251
+ # Encode the parameters as URL query parameters
252
+ query_params = "&".join([f"{k}={v}" for k, v in params.items()])
253
+ url = (
254
+ f"https://shell.cloud.google.com/cloudshell/editor?{query_params}"
255
+ )
256
+
257
+ config = f"""
258
+ ### BEGIN CONFIGURATION ###
259
+ ZENML_STACK_NAME={self.stack_name}
260
+ ZENML_STACK_REGION={self.location or "europe-west3"}
261
+ ZENML_SERVER_URL={self.zenml_server_url}
262
+ ZENML_SERVER_API_TOKEN={self.zenml_server_api_token}
263
+ ### END CONFIGURATION ###"""
264
+
265
+ return StackDeploymentConfig(
266
+ deployment_url=url,
267
+ deployment_url_text="GCP Cloud Shell Console",
268
+ configuration=config,
269
+ )
@@ -0,0 +1,218 @@
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
+ """Functionality to deploy a ZenML stack to a cloud provider."""
15
+
16
+ import datetime
17
+ from abc import abstractmethod
18
+ from typing import ClassVar, Dict, List, Optional
19
+
20
+ from pydantic import BaseModel
21
+
22
+ from zenml.client import Client
23
+ from zenml.enums import StackComponentType, StackDeploymentProvider
24
+ from zenml.models import (
25
+ DeployedStack,
26
+ StackDeploymentConfig,
27
+ StackDeploymentInfo,
28
+ )
29
+
30
+
31
+ class ZenMLCloudStackDeployment(BaseModel):
32
+ """ZenML Cloud Stack CLI Deployment base class."""
33
+
34
+ provider: ClassVar[StackDeploymentProvider]
35
+ deployment: ClassVar[str]
36
+ stack_name: str
37
+ zenml_server_url: str
38
+ zenml_server_api_token: str
39
+ location: Optional[str] = None
40
+
41
+ @classmethod
42
+ @abstractmethod
43
+ def description(cls) -> str:
44
+ """Return a description of the ZenML Cloud Stack Deployment.
45
+
46
+ This will be displayed when the user is prompted to deploy
47
+ the ZenML stack.
48
+
49
+ Returns:
50
+ A MarkDown description of the ZenML Cloud Stack Deployment.
51
+ """
52
+
53
+ @classmethod
54
+ @abstractmethod
55
+ def instructions(cls) -> str:
56
+ """Return instructions on how to deploy the ZenML stack to the specified cloud provider.
57
+
58
+ This will be displayed before the user is prompted to deploy the ZenML
59
+ stack.
60
+
61
+ Returns:
62
+ MarkDown instructions on how to deploy the ZenML stack to the
63
+ specified cloud provider.
64
+ """
65
+
66
+ @classmethod
67
+ @abstractmethod
68
+ def post_deploy_instructions(cls) -> str:
69
+ """Return instructions on what to do after the deployment is complete.
70
+
71
+ This will be displayed after the deployment is complete.
72
+
73
+ Returns:
74
+ MarkDown instructions on what to do after the deployment is
75
+ complete.
76
+ """
77
+
78
+ @classmethod
79
+ @abstractmethod
80
+ def integrations(cls) -> List[str]:
81
+ """Return the ZenML integrations required for the stack.
82
+
83
+ Returns:
84
+ The list of ZenML integrations that need to be installed for the
85
+ stack to be usable.
86
+ """
87
+
88
+ @classmethod
89
+ @abstractmethod
90
+ def permissions(cls) -> Dict[str, List[str]]:
91
+ """Return the permissions granted to ZenML to access the cloud resources.
92
+
93
+ Returns:
94
+ The permissions granted to ZenML to access the cloud resources, as
95
+ a dictionary grouping permissions by resource.
96
+ """
97
+
98
+ @classmethod
99
+ @abstractmethod
100
+ def locations(cls) -> Dict[str, str]:
101
+ """Return the locations where the ZenML stack can be deployed.
102
+
103
+ Returns:
104
+ The regions where the ZenML stack can be deployed as a map of region
105
+ names to region descriptions.
106
+ """
107
+
108
+ @classmethod
109
+ def skypilot_default_regions(cls) -> Dict[str, str]:
110
+ """Returns the regions supported by default for the Skypilot.
111
+
112
+ Returns:
113
+ The regions supported by default for the Skypilot.
114
+ """
115
+ return cls.locations()
116
+
117
+ @classmethod
118
+ def get_deployment_info(cls) -> StackDeploymentInfo:
119
+ """Return information about the ZenML Cloud Stack Deployment.
120
+
121
+ Returns:
122
+ Information about the ZenML Cloud Stack Deployment.
123
+ """
124
+ return StackDeploymentInfo(
125
+ provider=cls.provider,
126
+ description=cls.description(),
127
+ instructions=cls.instructions(),
128
+ post_deploy_instructions=cls.post_deploy_instructions(),
129
+ integrations=cls.integrations(),
130
+ permissions=cls.permissions(),
131
+ locations=cls.locations(),
132
+ skypilot_default_regions=cls.skypilot_default_regions(),
133
+ )
134
+
135
+ @abstractmethod
136
+ def get_deployment_config(
137
+ self,
138
+ ) -> StackDeploymentConfig:
139
+ """Return the configuration to deploy the ZenML stack to the specified cloud provider.
140
+
141
+ The configuration should include:
142
+
143
+ * a cloud provider console URL where the user will be redirected to
144
+ deploy the ZenML stack. The URL should include as many pre-filled
145
+ URL query parameters as possible.
146
+ * a textual description of the URL
147
+ * some deployment providers may require additional configuration
148
+ parameters to be passed to the cloud provider in addition to the
149
+ deployment URL query parameters. Where that is the case, this method
150
+ should also return a string that the user can copy and paste into the
151
+ cloud provider console to deploy the ZenML stack (e.g. a set of
152
+ environment variables, or YAML configuration snippet etc.).
153
+
154
+ Returns:
155
+ The configuration to deploy the ZenML stack to the specified cloud
156
+ provider.
157
+ """
158
+
159
+ def get_stack(
160
+ self, date_start: Optional[datetime.datetime] = None
161
+ ) -> Optional[DeployedStack]:
162
+ """Return the ZenML stack that was deployed and registered.
163
+
164
+ This method is called to retrieve a ZenML stack matching the deployment
165
+ provider.
166
+
167
+ Args:
168
+ date_start: The date when the deployment started.
169
+
170
+ Returns:
171
+ The ZenML stack that was deployed and registered or None if a
172
+ matching stack was not found.
173
+ """
174
+ client = Client()
175
+
176
+ # It's difficult to find a stack that matches the CloudFormation
177
+ # deployment 100% because the user can change the stack name before they
178
+ # deploy the stack in GCP.
179
+ #
180
+ # We try to find a full GCP stack that matches the deployment provider
181
+ # that was registered after this deployment was created.
182
+
183
+ # Get all stacks created after the start date
184
+ stacks = client.list_stacks(
185
+ created=f"gt:{str(date_start.replace(microsecond=0))}"
186
+ if date_start
187
+ else None,
188
+ sort_by="desc:created",
189
+ size=50,
190
+ )
191
+
192
+ if not stacks.items:
193
+ return None
194
+
195
+ # Find a stack that best matches the deployment provider
196
+ for stack in stacks.items:
197
+ if not stack.labels:
198
+ continue
199
+
200
+ if stack.labels.get("zenml:provider") != self.provider.value:
201
+ continue
202
+
203
+ if stack.labels.get("zenml:deployment") != self.deployment:
204
+ continue
205
+
206
+ artifact_store = stack.components[
207
+ StackComponentType.ARTIFACT_STORE
208
+ ][0]
209
+
210
+ if not artifact_store.connector:
211
+ continue
212
+
213
+ return DeployedStack(
214
+ stack=stack,
215
+ service_connector=artifact_store.connector,
216
+ )
217
+
218
+ return None
@@ -0,0 +1,48 @@
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
+ """Functionality to deploy a ZenML stack to a cloud provider."""
15
+
16
+ from typing import Type
17
+
18
+ from zenml.enums import StackDeploymentProvider
19
+ from zenml.stack_deployments.aws_stack_deployment import (
20
+ AWSZenMLCloudStackDeployment,
21
+ )
22
+ from zenml.stack_deployments.azure_stack_deployment import (
23
+ AZUREZenMLCloudStackDeployment,
24
+ )
25
+ from zenml.stack_deployments.gcp_stack_deployment import (
26
+ GCPZenMLCloudStackDeployment,
27
+ )
28
+ from zenml.stack_deployments.stack_deployment import ZenMLCloudStackDeployment
29
+
30
+ STACK_DEPLOYMENT_PROVIDERS = {
31
+ StackDeploymentProvider.AWS: AWSZenMLCloudStackDeployment,
32
+ StackDeploymentProvider.GCP: GCPZenMLCloudStackDeployment,
33
+ StackDeploymentProvider.AZURE: AZUREZenMLCloudStackDeployment,
34
+ }
35
+
36
+
37
+ def get_stack_deployment_class(
38
+ provider: StackDeploymentProvider,
39
+ ) -> Type[ZenMLCloudStackDeployment]:
40
+ """Get the ZenML Cloud Stack Deployment class for the specified provider.
41
+
42
+ Args:
43
+ provider: The stack deployment provider.
44
+
45
+ Returns:
46
+ The ZenML Cloud Stack Deployment class for the specified provider.
47
+ """
48
+ return STACK_DEPLOYMENT_PROVIDERS[provider]
zenml/steps/base_step.py CHANGED
@@ -479,7 +479,7 @@ class BaseStep(metaclass=BaseStepMeta):
479
479
  bound_args = signature.bind_partial(*args, **kwargs)
480
480
  except TypeError as e:
481
481
  raise StepInterfaceError(
482
- f"Wrong arguments when calling step `{self.name}`: {e}"
482
+ f"Wrong arguments when calling step '{self.name}': {e}"
483
483
  ) from e
484
484
 
485
485
  artifacts = {}
@@ -980,7 +980,7 @@ class BaseStep(metaclass=BaseStepMeta):
980
980
  )
981
981
  if conflicting_parameters:
982
982
  is_plural = "s" if len(conflicting_parameters) > 1 else ""
983
- msg = f"Configured parameter{is_plural} for the step `{self.name}` conflict{'' if not is_plural else 's'} with parameter{is_plural} passed in runtime:\n"
983
+ msg = f"Configured parameter{is_plural} for the step '{self.name}' conflict{'' if not is_plural else 's'} with parameter{is_plural} passed in runtime:\n"
984
984
  for key, values in conflicting_parameters.items():
985
985
  msg += (
986
986
  f"`{key}`: config=`{values[0]}` | runtime=`{values[1]}`\n"
@@ -1023,7 +1023,7 @@ To avoid this consider setting step parameters only in one place (config or code
1023
1023
  if output_name not in allowed_output_names:
1024
1024
  raise StepInterfaceError(
1025
1025
  f"Got unexpected materializers for non-existent "
1026
- f"output '{output_name}' in step `{self.name}`. "
1026
+ f"output '{output_name}' in step '{self.name}'. "
1027
1027
  f"Only materializers for the outputs "
1028
1028
  f"{allowed_output_names} of this step can"
1029
1029
  f" be registered."
@@ -1036,7 +1036,7 @@ To avoid this consider setting step parameters only in one place (config or code
1036
1036
  ):
1037
1037
  raise StepInterfaceError(
1038
1038
  f"Materializer source `{source}` "
1039
- f"for output '{output_name}' of step `{self.name}` "
1039
+ f"for output '{output_name}' of step '{self.name}' "
1040
1040
  "does not resolve to a `BaseMaterializer` subclass."
1041
1041
  )
1042
1042
 
@@ -1070,7 +1070,9 @@ To avoid this consider setting step parameters only in one place (config or code
1070
1070
  or key in client_lazy_loaders
1071
1071
  ):
1072
1072
  continue
1073
- raise StepInterfaceError(f"Missing entrypoint input {key}.")
1073
+ raise StepInterfaceError(
1074
+ f"Missing entrypoint input '{key}' in step '{self.name}'."
1075
+ )
1074
1076
 
1075
1077
  def _finalize_configuration(
1076
1078
  self,
@@ -107,7 +107,7 @@ def _is_valid_optional_arg(arg_type: Any) -> bool:
107
107
  if (
108
108
  args[0] not in _ALLOWED_TYPES
109
109
  and not _is_valid_collection_arg(args[0])
110
- ) or args[1] != type(None):
110
+ ) or args[1] is not type(None):
111
111
  return False
112
112
  return True
113
113
  return False
@@ -146,7 +146,7 @@ def _cli_wrapped_function(func: F) -> F:
146
146
  if _is_valid_optional_arg(arg_type):
147
147
  arg_type = arg_type.__args__[0]
148
148
  arg_name = _cli_arg_name(arg_name)
149
- if arg_type == bool:
149
+ if arg_type is bool:
150
150
  options.append(
151
151
  click.option(
152
152
  f"--{arg_name}",
@@ -13,7 +13,7 @@
13
13
  # permissions and limitations under the License.
14
14
  """Pagination utilities."""
15
15
 
16
- from typing import Callable, List, TypeVar
16
+ from typing import Any, Callable, List, TypeVar
17
17
 
18
18
  from zenml.models import BaseIdentifiedResponse, Page
19
19
 
@@ -21,20 +21,22 @@ AnyResponse = TypeVar("AnyResponse", bound=BaseIdentifiedResponse) # type: igno
21
21
 
22
22
 
23
23
  def depaginate(
24
- list_method: Callable[..., Page[AnyResponse]],
24
+ list_method: Callable[..., Page[AnyResponse]], **kwargs: Any
25
25
  ) -> List[AnyResponse]:
26
26
  """Depaginate the results from a client or store method that returns pages.
27
27
 
28
28
  Args:
29
- list_method: The list method to wrap around.
29
+ list_method: The list method to depaginate.
30
+ **kwargs: Arguments for the list method.
30
31
 
31
32
  Returns:
32
33
  A list of the corresponding Response Models.
33
34
  """
34
- page = list_method()
35
+ page = list_method(**kwargs)
35
36
  items = list(page.items)
36
37
  while page.index < page.total_pages:
37
- page = list_method(page=page.index + 1)
38
+ kwargs["page"] = page.index + 1
39
+ page = list_method(**kwargs)
38
40
  items += list(page.items)
39
41
 
40
42
  return items