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
@@ -13,15 +13,14 @@
13
13
  # permissions and limitations under the License.
14
14
  """Collection of all models concerning triggers."""
15
15
 
16
- import copy
17
- from typing import TYPE_CHECKING, Any, Dict, Optional, Union
16
+ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union
18
17
  from uuid import UUID
19
18
 
20
- from pydantic import BaseModel, Field
19
+ from pydantic import Field, model_validator
21
20
 
21
+ from zenml.config.schedule import Schedule
22
22
  from zenml.constants import STR_FIELD_MAX_LENGTH
23
- from zenml.enums import PluginSubType
24
- from zenml.models.v2.base.base import BaseZenModel
23
+ from zenml.models.v2.base.base import BaseUpdate
25
24
  from zenml.models.v2.base.page import Page
26
25
  from zenml.models.v2.base.scoped import (
27
26
  WorkspaceScopedFilter,
@@ -32,138 +31,129 @@ from zenml.models.v2.base.scoped import (
32
31
  WorkspaceScopedResponseResources,
33
32
  )
34
33
  from zenml.models.v2.core.trigger_execution import TriggerExecutionResponse
35
- from zenml.models.v2.core.user import UserResponse
36
34
 
37
35
  if TYPE_CHECKING:
36
+ from sqlalchemy.sql.elements import ColumnElement
37
+
38
+ from zenml.models.v2.core.action import (
39
+ ActionResponse,
40
+ )
38
41
  from zenml.models.v2.core.event_source import EventSourceResponse
39
42
 
40
- # ------------------ Base Model ------------------
43
+
44
+ # ------------------ Request Model ------------------
41
45
 
42
46
 
43
- class TriggerBase(BaseModel):
44
- """Base model for triggers."""
47
+ class TriggerRequest(WorkspaceScopedRequest):
48
+ """Model for creating a new trigger."""
45
49
 
46
50
  name: str = Field(
47
- title="The name of the Trigger.", max_length=STR_FIELD_MAX_LENGTH
51
+ title="The name of the trigger.", max_length=STR_FIELD_MAX_LENGTH
48
52
  )
49
53
  description: str = Field(
50
54
  default="",
51
55
  title="The description of the trigger",
52
56
  max_length=STR_FIELD_MAX_LENGTH,
53
57
  )
54
- event_source_id: UUID = Field(
55
- title="The event source that activates this trigger.",
56
- )
57
- event_filter: Dict[str, Any] = Field(
58
- title="Filter applied to events that activate this trigger.",
59
- )
60
-
61
- action: Dict[str, Any] = Field(
62
- title="The configuration for the action that is executed by this "
63
- "trigger.",
64
- )
65
- action_flavor: str = Field(
66
- title="The flavor of the action that is executed by this trigger.",
67
- max_length=STR_FIELD_MAX_LENGTH,
58
+ action_id: UUID = Field(
59
+ title="The action that is executed by this trigger.",
68
60
  )
69
- action_subtype: PluginSubType = Field(
70
- title="The subtype of the action that is executed by this trigger.",
61
+ schedule: Optional[Schedule] = Field(
62
+ default=None,
63
+ title="The schedule for the trigger. Either a schedule or an event "
64
+ "source is required.",
71
65
  )
72
- service_account_id: UUID = Field(
73
- title="The service account that is used to execute the action.",
66
+ event_source_id: Optional[UUID] = Field(
67
+ default=None,
68
+ title="The event source that activates this trigger. Either a schedule "
69
+ "or an event source is required.",
74
70
  )
75
- auth_window: Optional[int] = Field(
71
+ event_filter: Optional[Dict[str, Any]] = Field(
76
72
  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.",
73
+ title="Filter applied to events that activate this trigger. Only "
74
+ "set if the trigger is activated by an event source.",
81
75
  )
82
76
 
77
+ @model_validator(mode="after")
78
+ def _validate_schedule_or_event_source(self) -> "TriggerRequest":
79
+ """Validate that either a schedule or an event source is provided.
83
80
 
84
- # ------------------ Request Model ------------------
85
- class TriggerRequest(TriggerBase, WorkspaceScopedRequest):
86
- """Model for creating a new Trigger."""
81
+ Returns:
82
+ The validated request.
83
+
84
+ Raises:
85
+ ValueError: If neither a schedule nor an event source is provided,
86
+ or if both are provided.
87
+ """
88
+ if not self.schedule and not self.event_source_id:
89
+ raise ValueError(
90
+ "Either a schedule or an event source is required."
91
+ )
92
+
93
+ if self.schedule and self.event_source_id:
94
+ raise ValueError("Only a schedule or an event source is allowed.")
95
+
96
+ return self
87
97
 
88
98
 
89
99
  # ------------------ Update Model ------------------
90
100
 
91
101
 
92
- class TriggerUpdate(BaseZenModel):
102
+ class TriggerUpdate(BaseUpdate):
93
103
  """Update model for triggers."""
94
104
 
95
105
  name: Optional[str] = Field(
96
106
  default=None,
97
- title="The new name for the Trigger.",
107
+ title="The new name for the trigger.",
98
108
  max_length=STR_FIELD_MAX_LENGTH,
99
109
  )
100
110
  description: Optional[str] = Field(
101
111
  default=None,
102
- title="The new description for the trigger",
112
+ title="The new description for the trigger.",
103
113
  max_length=STR_FIELD_MAX_LENGTH,
104
114
  )
105
115
  event_filter: Optional[Dict[str, Any]] = Field(
106
116
  default=None,
107
- title="New filter applied to events that activate this trigger.",
117
+ title="New filter applied to events that activate this trigger. Only "
118
+ "valid if the trigger is already configured to be activated by an "
119
+ "event source.",
108
120
  )
109
- action: Optional[Dict[str, Any]] = Field(
121
+ schedule: Optional[Schedule] = Field(
110
122
  default=None,
111
- title="The new configuration for the action that is executed by this "
112
- "trigger.",
123
+ title="The updated schedule for the trigger. Only valid if the trigger "
124
+ "is already configured to be activated by a schedule.",
113
125
  )
114
126
  is_active: Optional[bool] = Field(
115
127
  default=None,
116
128
  title="The new status of the trigger.",
117
129
  )
118
- service_account_id: Optional[UUID] = Field(
119
- default=None,
120
- title="The service account that is used to execute the action.",
121
- )
122
- auth_window: Optional[int] = Field(
123
- default=None,
124
- title="The time window in minutes for which the service account is "
125
- "authorized to execute the action. Set this to 0 to authorize the "
126
- "service account indefinitely (not recommended). If not set, a "
127
- "default value defined for each individual action type is used.",
128
- )
129
-
130
- @classmethod
131
- def from_response(cls, response: "TriggerResponse") -> "TriggerUpdate":
132
- """Create an update model from a response model.
133
-
134
- Args:
135
- response: The response model to create the update model from.
136
-
137
- Returns:
138
- The update model.
139
- """
140
- return TriggerUpdate(
141
- name=response.name,
142
- description=response.description,
143
- action=copy.deepcopy(response.action),
144
- event_filter=copy.deepcopy(response.event_filter),
145
- is_active=response.is_active,
146
- service_account_id=response.get_resources().service_account.id,
147
- )
148
130
 
149
131
 
150
132
  # ------------------ Response Model ------------------
151
133
 
152
134
 
153
135
  class TriggerResponseBody(WorkspaceScopedResponseBody):
154
- """ResponseBody for triggers."""
136
+ """Response body for triggers."""
155
137
 
156
- event_source_flavor: str = Field(
157
- title="The flavor of the event source that activates this trigger.",
158
- max_length=STR_FIELD_MAX_LENGTH,
159
- )
160
138
  action_flavor: str = Field(
161
139
  title="The flavor of the action that is executed by this trigger.",
162
140
  max_length=STR_FIELD_MAX_LENGTH,
163
141
  )
164
- action_subtype: PluginSubType = Field(
142
+ action_subtype: str = Field(
165
143
  title="The subtype of the action that is executed by this trigger.",
166
144
  )
145
+ event_source_flavor: Optional[str] = Field(
146
+ default=None,
147
+ title="The flavor of the event source that activates this trigger. Not "
148
+ "set if the trigger is activated by a schedule.",
149
+ max_length=STR_FIELD_MAX_LENGTH,
150
+ )
151
+ event_source_subtype: Optional[str] = Field(
152
+ default=None,
153
+ title="The subtype of the event source that activates this trigger. "
154
+ "Not set if the trigger is activated by a schedule.",
155
+ max_length=STR_FIELD_MAX_LENGTH,
156
+ )
167
157
  is_active: bool = Field(
168
158
  title="Whether the trigger is active.",
169
159
  )
@@ -172,33 +162,33 @@ class TriggerResponseBody(WorkspaceScopedResponseBody):
172
162
  class TriggerResponseMetadata(WorkspaceScopedResponseMetadata):
173
163
  """Response metadata for triggers."""
174
164
 
175
- event_filter: Dict[str, Any] = Field(
176
- title="The event that activates this trigger.",
177
- )
178
- action: Dict[str, Any] = Field(
179
- title="The action that is executed by this trigger.",
180
- )
181
165
  description: str = Field(
182
166
  default="",
183
- title="The description of the trigger",
167
+ title="The description of the trigger.",
184
168
  max_length=STR_FIELD_MAX_LENGTH,
185
169
  )
186
- auth_window: int = Field(
187
- title="The time window in minutes for which the service account is "
188
- "authorized to execute the action. Set this to 0 to authorize the "
189
- "service account indefinitely (not recommended). If not set, a "
190
- "default value defined for each individual action type is used.",
170
+ event_filter: Optional[Dict[str, Any]] = Field(
171
+ default=None,
172
+ title="The event that activates this trigger. Not set if the trigger "
173
+ "is activated by a schedule.",
174
+ )
175
+ schedule: Optional[Schedule] = Field(
176
+ default=None,
177
+ title="The schedule that activates this trigger. Not set if the "
178
+ "trigger is activated by an event source.",
191
179
  )
192
180
 
193
181
 
194
182
  class TriggerResponseResources(WorkspaceScopedResponseResources):
195
183
  """Class for all resource models associated with the trigger entity."""
196
184
 
197
- event_source: "EventSourceResponse" = Field(
198
- title="The event source that activates this trigger.",
185
+ action: "ActionResponse" = Field(
186
+ title="The action that is executed by this trigger.",
199
187
  )
200
- service_account: UserResponse = Field(
201
- title="The service account that is used to execute the action.",
188
+ event_source: Optional["EventSourceResponse"] = Field(
189
+ default=None,
190
+ title="The event source that activates this trigger. Not set if the "
191
+ "trigger is activated by a schedule.",
202
192
  )
203
193
  executions: Page[TriggerExecutionResponse] = Field(
204
194
  title="The executions of this trigger.",
@@ -213,7 +203,7 @@ class TriggerResponse(
213
203
  """Response model for models."""
214
204
 
215
205
  name: str = Field(
216
- title="The name of the model",
206
+ title="The name of the trigger",
217
207
  max_length=STR_FIELD_MAX_LENGTH,
218
208
  )
219
209
 
@@ -227,15 +217,6 @@ class TriggerResponse(
227
217
 
228
218
  return Client().zen_store.get_trigger(self.id)
229
219
 
230
- @property
231
- def event_source_flavor(self) -> str:
232
- """The `event_source_flavor` property.
233
-
234
- Returns:
235
- the value of the property.
236
- """
237
- return self.get_body().event_source_flavor
238
-
239
220
  @property
240
221
  def action_flavor(self) -> str:
241
222
  """The `action_flavor` property.
@@ -246,7 +227,7 @@ class TriggerResponse(
246
227
  return self.get_body().action_flavor
247
228
 
248
229
  @property
249
- def action_subtype(self) -> PluginSubType:
230
+ def action_subtype(self) -> str:
250
231
  """The `action_subtype` property.
251
232
 
252
233
  Returns:
@@ -255,48 +236,40 @@ class TriggerResponse(
255
236
  return self.get_body().action_subtype
256
237
 
257
238
  @property
258
- def is_active(self) -> bool:
259
- """The `is_active` property.
239
+ def event_source_flavor(self) -> Optional[str]:
240
+ """The `event_source_flavor` property.
260
241
 
261
242
  Returns:
262
243
  the value of the property.
263
244
  """
264
- return self.get_body().is_active
245
+ return self.get_body().event_source_flavor
265
246
 
266
247
  @property
267
- def event_filter(self) -> Dict[str, Any]:
268
- """The `event_filter` property.
248
+ def event_source_subtype(self) -> Optional[str]:
249
+ """The `event_source_subtype` property.
269
250
 
270
251
  Returns:
271
252
  the value of the property.
272
253
  """
273
- return self.get_metadata().event_filter
254
+ return self.get_body().event_source_subtype
274
255
 
275
256
  @property
276
- def action(self) -> Dict[str, Any]:
277
- """The `action` property.
257
+ def is_active(self) -> bool:
258
+ """The `is_active` property.
278
259
 
279
260
  Returns:
280
261
  the value of the property.
281
262
  """
282
- return self.get_metadata().action
283
-
284
- def set_action(self, action: Dict[str, Any]) -> None:
285
- """Set the `action` property.
286
-
287
- Args:
288
- action: The value to set.
289
- """
290
- self.get_metadata().action = action
263
+ return self.get_body().is_active
291
264
 
292
265
  @property
293
- def event_source(self) -> "EventSourceResponse":
294
- """The `event_source` property.
266
+ def event_filter(self) -> Optional[Dict[str, Any]]:
267
+ """The `event_filter` property.
295
268
 
296
269
  Returns:
297
270
  the value of the property.
298
271
  """
299
- return self.get_resources().event_source
272
+ return self.get_metadata().event_filter
300
273
 
301
274
  @property
302
275
  def description(self) -> str:
@@ -308,37 +281,59 @@ class TriggerResponse(
308
281
  return self.get_metadata().description
309
282
 
310
283
  @property
311
- def service_account(self) -> UserResponse:
312
- """The `service_account` property.
284
+ def action(self) -> "ActionResponse":
285
+ """The `action` property.
313
286
 
314
287
  Returns:
315
288
  the value of the property.
316
289
  """
317
- return self.get_resources().service_account
290
+ return self.get_resources().action
318
291
 
319
292
  @property
320
- def auth_window(self) -> int:
321
- """The `auth_window` property.
293
+ def event_source(self) -> Optional["EventSourceResponse"]:
294
+ """The `event_source` property.
322
295
 
323
296
  Returns:
324
297
  the value of the property.
325
298
  """
326
- return self.get_metadata().auth_window
299
+ return self.get_resources().event_source
300
+
301
+ @property
302
+ def executions(self) -> Page[TriggerExecutionResponse]:
303
+ """The `event_source` property.
304
+
305
+ Returns:
306
+ the value of the property.
307
+ """
308
+ return self.get_resources().executions
327
309
 
328
310
 
329
311
  # ------------------ Filter Model ------------------
330
312
 
331
313
 
332
314
  class TriggerFilter(WorkspaceScopedFilter):
333
- """Model to enable advanced filtering of all TriggerModels."""
315
+ """Model to enable advanced filtering of all triggers."""
316
+
317
+ FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
318
+ *WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
319
+ "action_flavor",
320
+ "action_subtype",
321
+ "event_source_flavor",
322
+ "event_source_subtype",
323
+ ]
334
324
 
335
325
  name: Optional[str] = Field(
336
326
  default=None,
337
- description="Name of the trigger",
327
+ description="Name of the trigger.",
338
328
  )
339
329
  event_source_id: Optional[Union[UUID, str]] = Field(
340
330
  default=None,
341
- description="By the event source this trigger is attached to.",
331
+ description="The event source this trigger is attached to.",
332
+ union_mode="left_to_right",
333
+ )
334
+ action_id: Optional[Union[UUID, str]] = Field(
335
+ default=None,
336
+ description="The action this trigger is attached to.",
342
337
  union_mode="left_to_right",
343
338
  )
344
339
  is_active: Optional[bool] = Field(
@@ -353,13 +348,59 @@ class TriggerFilter(WorkspaceScopedFilter):
353
348
  default=None,
354
349
  title="The subtype of the action that is executed by this trigger.",
355
350
  )
356
- # TODO: Ignore these in normal filter and handle in sqlzenstore
357
- resource_id: Optional[Union[UUID, str]] = Field(
351
+ event_source_flavor: Optional[str] = Field(
358
352
  default=None,
359
- description="By the resource this trigger references.",
360
- union_mode="left_to_right",
353
+ title="The flavor of the event source that activates this trigger.",
361
354
  )
362
- resource_type: Optional[str] = Field(
355
+ event_source_subtype: Optional[str] = Field(
363
356
  default=None,
364
- description="By the resource type this trigger references.",
357
+ title="The subtype of the event source that activates this trigger.",
365
358
  )
359
+
360
+ def get_custom_filters(
361
+ self,
362
+ ) -> List["ColumnElement[bool]"]:
363
+ """Get custom filters.
364
+
365
+ Returns:
366
+ A list of custom filters.
367
+ """
368
+ from sqlmodel import and_
369
+
370
+ from zenml.zen_stores.schemas import (
371
+ ActionSchema,
372
+ EventSourceSchema,
373
+ TriggerSchema,
374
+ )
375
+
376
+ custom_filters = super().get_custom_filters()
377
+
378
+ if self.event_source_flavor:
379
+ event_source_flavor_filter = and_(
380
+ EventSourceSchema.id == TriggerSchema.event_source_id,
381
+ EventSourceSchema.flavor == self.event_source_flavor,
382
+ )
383
+ custom_filters.append(event_source_flavor_filter)
384
+
385
+ if self.event_source_subtype:
386
+ event_source_subtype_filter = and_(
387
+ EventSourceSchema.id == TriggerSchema.event_source_id,
388
+ EventSourceSchema.plugin_subtype == self.event_source_subtype,
389
+ )
390
+ custom_filters.append(event_source_subtype_filter)
391
+
392
+ if self.action_flavor:
393
+ action_flavor_filter = and_(
394
+ ActionSchema.id == TriggerSchema.action_id,
395
+ ActionSchema.flavor == self.action_flavor,
396
+ )
397
+ custom_filters.append(action_flavor_filter)
398
+
399
+ if self.action_subtype:
400
+ action_subtype_filter = and_(
401
+ ActionSchema.id == TriggerSchema.action_id,
402
+ ActionSchema.plugin_subtype == self.action_subtype,
403
+ )
404
+ custom_filters.append(action_subtype_filter)
405
+
406
+ return custom_filters
@@ -0,0 +1,97 @@
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
+ """Models representing full stack requests."""
15
+
16
+ from typing import Any, Dict, List, Optional, Union
17
+ from uuid import UUID
18
+
19
+ from pydantic import BaseModel, Field, model_validator
20
+
21
+ from zenml.constants import STR_FIELD_MAX_LENGTH
22
+ from zenml.enums import StackComponentType
23
+ from zenml.models.v2.base.base import BaseRequest
24
+
25
+
26
+ class ServiceConnectorInfo(BaseModel):
27
+ """Information about the service connector when creating a full stack."""
28
+
29
+ type: str
30
+ auth_method: str
31
+ configuration: Dict[str, Any] = {}
32
+
33
+
34
+ class ComponentInfo(BaseModel):
35
+ """Information about each stack components when creating a full stack."""
36
+
37
+ flavor: str
38
+ service_connector_index: Optional[int] = Field(
39
+ default=None,
40
+ title="The id of the service connector from the list "
41
+ "`service_connectors`.",
42
+ description="The id of the service connector from the list "
43
+ "`service_connectors` from `FullStackRequest`.",
44
+ )
45
+ service_connector_resource_id: Optional[str] = None
46
+ configuration: Dict[str, Any] = {}
47
+
48
+
49
+ class FullStackRequest(BaseRequest):
50
+ """Request model for a full-stack."""
51
+
52
+ user: Optional[UUID] = None
53
+ workspace: Optional[UUID] = None
54
+
55
+ name: str = Field(
56
+ title="The name of the stack.", max_length=STR_FIELD_MAX_LENGTH
57
+ )
58
+ description: Optional[str] = Field(
59
+ default="",
60
+ title="The description of the stack",
61
+ max_length=STR_FIELD_MAX_LENGTH,
62
+ )
63
+ labels: Optional[Dict[str, Any]] = Field(
64
+ default=None,
65
+ title="The stack labels.",
66
+ )
67
+ service_connectors: List[Union[UUID, ServiceConnectorInfo]] = Field(
68
+ default=[],
69
+ title="The service connectors dictionary for the full stack "
70
+ "registration.",
71
+ description="The UUID of an already existing service connector or "
72
+ "request information to create a service connector from "
73
+ "scratch.",
74
+ )
75
+ components: Dict[StackComponentType, Union[UUID, ComponentInfo]] = Field(
76
+ title="The mapping for the components of the full stack registration.",
77
+ description="The mapping from component types to either UUIDs of "
78
+ "existing components or request information for brand new "
79
+ "components.",
80
+ )
81
+
82
+ @model_validator(mode="after")
83
+ def _validate_indexes_in_components(self) -> "FullStackRequest":
84
+ for component in self.components.values():
85
+ if isinstance(component, ComponentInfo):
86
+ if component.service_connector_index is not None:
87
+ if (
88
+ component.service_connector_index < 0
89
+ or component.service_connector_index
90
+ >= len(self.service_connectors)
91
+ ):
92
+ raise ValueError(
93
+ f"Service connector index {component.service_connector_index} "
94
+ "is out of range. Please provide a valid index referring to "
95
+ "the position in the list of service connectors."
96
+ )
97
+ return self
@@ -0,0 +1,86 @@
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
+ """Models related to cloud stack deployments."""
15
+
16
+ from typing import Dict, List, Optional
17
+
18
+ from pydantic import BaseModel, Field
19
+
20
+ from zenml.enums import StackDeploymentProvider
21
+ from zenml.models.v2.core.service_connector import ServiceConnectorResponse
22
+ from zenml.models.v2.core.stack import StackResponse
23
+
24
+
25
+ class StackDeploymentInfo(BaseModel):
26
+ """Information about a stack deployment."""
27
+
28
+ provider: StackDeploymentProvider = Field(
29
+ title="The provider of the stack deployment."
30
+ )
31
+ description: str = Field(
32
+ title="The description of the stack deployment.",
33
+ description="The description of the stack deployment.",
34
+ )
35
+ instructions: str = Field(
36
+ title="The instructions for deploying the stack.",
37
+ description="The instructions for deploying the stack.",
38
+ )
39
+ post_deploy_instructions: str = Field(
40
+ title="The instructions for post-deployment.",
41
+ description="The instructions for post-deployment.",
42
+ )
43
+ integrations: List[str] = Field(
44
+ title="ZenML integrations required for the stack.",
45
+ description="The list of ZenML integrations that need to be installed "
46
+ "for the stack to be usable.",
47
+ )
48
+ permissions: Dict[str, List[str]] = Field(
49
+ title="The permissions granted to ZenML to access the cloud resources.",
50
+ description="The permissions granted to ZenML to access the cloud "
51
+ "resources, as a dictionary grouping permissions by resource.",
52
+ )
53
+ locations: Dict[str, str] = Field(
54
+ title="The locations where the stack can be deployed.",
55
+ description="The locations where the stack can be deployed, as a "
56
+ "dictionary mapping location names to descriptions.",
57
+ )
58
+
59
+
60
+ class StackDeploymentConfig(BaseModel):
61
+ """Configuration about a stack deployment."""
62
+
63
+ deployment_url: str = Field(
64
+ title="The cloud provider console URL where the stack will be deployed.",
65
+ )
66
+ deployment_url_text: str = Field(
67
+ title="A textual description for the cloud provider console URL.",
68
+ )
69
+ configuration: Optional[str] = Field(
70
+ title="Configuration for the stack deployment that the user must "
71
+ "manually configure into the cloud provider console.",
72
+ )
73
+
74
+
75
+ class DeployedStack(BaseModel):
76
+ """Information about a deployed stack."""
77
+
78
+ stack: StackResponse = Field(
79
+ title="The stack that was deployed.",
80
+ description="The stack that was deployed.",
81
+ )
82
+ service_connector: Optional[ServiceConnectorResponse] = Field(
83
+ default=None,
84
+ title="The service connector for the deployed stack.",
85
+ description="The service connector for the deployed stack.",
86
+ )