zenml-nightly 0.62.0.dev20240729__py3-none-any.whl → 0.63.0.dev20240731__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 (157) hide show
  1. README.md +1 -1
  2. RELEASE_NOTES.md +41 -0
  3. zenml/VERSION +1 -1
  4. zenml/actions/pipeline_run/pipeline_run_action.py +19 -17
  5. zenml/analytics/enums.py +4 -0
  6. zenml/cli/__init__.py +28 -15
  7. zenml/cli/base.py +1 -1
  8. zenml/cli/pipeline.py +54 -61
  9. zenml/cli/stack.py +6 -8
  10. zenml/client.py +232 -99
  11. zenml/config/compiler.py +14 -22
  12. zenml/config/pipeline_run_configuration.py +3 -0
  13. zenml/config/server_config.py +3 -0
  14. zenml/config/source.py +2 -1
  15. zenml/constants.py +2 -0
  16. zenml/enums.py +3 -0
  17. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +13 -4
  18. zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +11 -2
  19. zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +19 -13
  20. zenml/models/__init__.py +26 -10
  21. zenml/models/v2/base/filter.py +32 -0
  22. zenml/models/v2/core/pipeline.py +73 -89
  23. zenml/models/v2/core/pipeline_build.py +15 -11
  24. zenml/models/v2/core/pipeline_deployment.py +56 -0
  25. zenml/models/v2/core/pipeline_run.py +52 -1
  26. zenml/models/v2/core/run_template.py +393 -0
  27. zenml/models/v2/misc/stack_deployment.py +5 -0
  28. zenml/new/pipelines/build_utils.py +34 -58
  29. zenml/new/pipelines/pipeline.py +17 -76
  30. zenml/new/pipelines/run_utils.py +12 -0
  31. zenml/post_execution/pipeline.py +1 -4
  32. zenml/service_connectors/service_connector_utils.py +4 -2
  33. zenml/stack_deployments/aws_stack_deployment.py +6 -5
  34. zenml/stack_deployments/azure_stack_deployment.py +118 -11
  35. zenml/stack_deployments/gcp_stack_deployment.py +12 -5
  36. zenml/stack_deployments/stack_deployment.py +6 -5
  37. zenml/steps/utils.py +0 -4
  38. zenml/utils/package_utils.py +39 -0
  39. zenml/zen_server/dashboard/assets/{404-B_YdvmwS.js → 404-CI13wQp4.js} +1 -1
  40. zenml/zen_server/dashboard/assets/{@reactflow-l_1hUr1S.js → @reactflow-DIYUhKYX.js} +1 -1
  41. zenml/zen_server/dashboard/assets/{@tanstack-DYiOyJUL.js → @tanstack-k96lU_C-.js} +4 -4
  42. zenml/zen_server/dashboard/assets/{AwarenessChannel-CFg5iX4Z.js → AwarenessChannel-BNg5uWgI.js} +1 -1
  43. zenml/zen_server/dashboard/assets/{CodeSnippet-Dvkx_82E.js → CodeSnippet-Cyp7f4dM.js} +2 -2
  44. zenml/zen_server/dashboard/assets/CollapsibleCard-Cu_A9W57.js +1 -0
  45. zenml/zen_server/dashboard/assets/{Commands-DoN1xrEq.js → Commands-DmQwTXjj.js} +1 -1
  46. zenml/zen_server/dashboard/assets/{CopyButton-Cr7xYEPb.js → CopyButton-B3sWVJ4Z.js} +1 -1
  47. zenml/zen_server/dashboard/assets/{CsvVizualization-Ck-nZ43m.js → CsvVizualization-BvqItd-O.js} +1 -1
  48. zenml/zen_server/dashboard/assets/{Error-kLtljEOM.js → Error-DbXCTGua.js} +1 -1
  49. zenml/zen_server/dashboard/assets/{ExecutionStatus-DguLLgTK.js → ExecutionStatus-9zM7eaLh.js} +1 -1
  50. zenml/zen_server/dashboard/assets/{Helpbox-BXUMP21n.js → Helpbox-BIiNc-uH.js} +1 -1
  51. zenml/zen_server/dashboard/assets/{Infobox-DSt0O-dm.js → Infobox-iv1Nu1A0.js} +1 -1
  52. zenml/zen_server/dashboard/assets/{InlineAvatar-xsrsIGE-.js → InlineAvatar-BvBtO2Dp.js} +1 -1
  53. zenml/zen_server/dashboard/assets/ProviderRadio-pSAvrGRS.js +1 -0
  54. zenml/zen_server/dashboard/assets/SearchField-CXoBknpt.js +1 -0
  55. zenml/zen_server/dashboard/assets/{SetPassword-BXGTWiwj.js → SetPassword-BOxpgh6N.js} +1 -1
  56. zenml/zen_server/dashboard/assets/{SuccessStep-DZC60t0x.js → SuccessStep-CTSKN2lp.js} +1 -1
  57. zenml/zen_server/dashboard/assets/Tick-Bnr2TpW6.js +1 -0
  58. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DGvwFWO1.js → UpdatePasswordSchemas-BeCeaRW5.js} +1 -1
  59. zenml/zen_server/dashboard/assets/chevron-down-D_ZlKMqH.js +1 -0
  60. zenml/zen_server/dashboard/assets/{cloud-only-C_yFCAkP.js → cloud-only-qelmY92E.js} +1 -1
  61. zenml/zen_server/dashboard/assets/components-DWe4cTjS.js +1 -0
  62. zenml/zen_server/dashboard/assets/dots-horizontal-BObFzD5l.js +1 -0
  63. zenml/zen_server/dashboard/assets/{index-BczVOqUf.js → index-KsTz2dHG.js} +5 -5
  64. zenml/zen_server/dashboard/assets/index-vfjX_fJV.css +1 -0
  65. zenml/zen_server/dashboard/assets/index.esm-CbHNSeVw.js +1 -0
  66. zenml/zen_server/dashboard/assets/{login-mutation-CrHrndTI.js → login-mutation-DRpbESS7.js} +1 -1
  67. zenml/zen_server/dashboard/assets/{not-found-DYa4pC-C.js → not-found-Dfx9hfkf.js} +1 -1
  68. zenml/zen_server/dashboard/assets/package-ClbU3KUi.js +1 -0
  69. zenml/zen_server/dashboard/assets/{page-uA5prJGY.js → page-399pVZHU.js} +1 -1
  70. zenml/zen_server/dashboard/assets/{page-1h_sD1jz.js → page-BoFtUD9H.js} +1 -1
  71. zenml/zen_server/dashboard/assets/{page-BDns21Iz.js → page-Btu39x7k.js} +1 -1
  72. zenml/zen_server/dashboard/assets/{page-BnaevhnB.js → page-BxiWdeyg.js} +1 -1
  73. zenml/zen_server/dashboard/assets/{page-1iL8aMqs.js → page-C176KxyB.js} +1 -1
  74. zenml/zen_server/dashboard/assets/page-C6tXXjnK.js +1 -0
  75. zenml/zen_server/dashboard/assets/{page-BkeAAYwp.js → page-CDgZmwxP.js} +1 -1
  76. zenml/zen_server/dashboard/assets/page-CP9obrnG.js +1 -0
  77. zenml/zen_server/dashboard/assets/{page-C6-UGEbH.js → page-CZe9GEBF.js} +1 -1
  78. zenml/zen_server/dashboard/assets/page-CaTOsNNw.js +1 -0
  79. zenml/zen_server/dashboard/assets/{page-CCNRIt_f.js → page-Cjn97HMv.js} +1 -1
  80. zenml/zen_server/dashboard/assets/page-CmXmB_5i.js +1 -0
  81. zenml/zen_server/dashboard/assets/page-CvGAOfad.js +1 -0
  82. zenml/zen_server/dashboard/assets/page-CzucfYPo.js +2 -0
  83. zenml/zen_server/dashboard/assets/{page-Bi-wtWiO.js → page-D0bbc-qr.js} +1 -1
  84. zenml/zen_server/dashboard/assets/page-DLEtD2ex.js +1 -0
  85. zenml/zen_server/dashboard/assets/{page-BhgCDInH.js → page-DVPxY5fT.js} +1 -1
  86. zenml/zen_server/dashboard/assets/{page-BkuQDIf-.js → page-DYBNGxJt.js} +1 -1
  87. zenml/zen_server/dashboard/assets/{page-8a4UMKXZ.js → page-DtpwnNXq.js} +1 -1
  88. zenml/zen_server/dashboard/assets/{page-B6h3iaHJ.js → page-DupV0aBd.js} +1 -1
  89. zenml/zen_server/dashboard/assets/page-EweAR81y.js +1 -0
  90. zenml/zen_server/dashboard/assets/{page-MFQyIJd3.js → page-f3jBVI5Z.js} +1 -1
  91. zenml/zen_server/dashboard/assets/{page-2grKx_MY.js → page-p2hLJdS2.js} +1 -1
  92. zenml/zen_server/dashboard/assets/page-w-YaL77M.js +9 -0
  93. zenml/zen_server/dashboard/assets/persist-BReKApOc.js +14 -0
  94. zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
  95. zenml/zen_server/dashboard/assets/{stack-detail-query-Cficsl6d.js → stack-detail-query-Ck7j7BP_.js} +1 -1
  96. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-7d8xi1tS.js → update-server-settings-mutation-f3ZT7psb.js} +1 -1
  97. zenml/zen_server/dashboard/assets/{url-D7mAQGUM.js → url-rGEp5Umh.js} +1 -1
  98. zenml/zen_server/dashboard/assets/{zod-BhoGpZ63.js → zod-BtSyGx4C.js} +1 -1
  99. zenml/zen_server/dashboard/index.html +5 -5
  100. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  101. zenml/zen_server/dashboard_legacy/index.html +1 -1
  102. zenml/zen_server/dashboard_legacy/{precache-manifest.12246c7548e71e2c4438e496360de80c.js → precache-manifest.2fa6e528a6e7447caaf35dadfe7514bb.js} +4 -4
  103. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  104. zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js → main.4aab7e98.chunk.js} +2 -2
  105. zenml/zen_server/dashboard_legacy/static/js/{main.3b27024b.chunk.js.map → main.4aab7e98.chunk.js.map} +1 -1
  106. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  107. zenml/zen_server/deploy/helm/README.md +2 -2
  108. zenml/zen_server/rbac/models.py +1 -0
  109. zenml/zen_server/rbac/utils.py +4 -0
  110. zenml/zen_server/routers/pipeline_builds_endpoints.py +2 -66
  111. zenml/zen_server/routers/pipeline_deployments_endpoints.py +2 -53
  112. zenml/zen_server/routers/pipelines_endpoints.py +1 -74
  113. zenml/zen_server/routers/run_templates_endpoints.py +212 -0
  114. zenml/zen_server/routers/workspaces_endpoints.py +79 -0
  115. zenml/zen_server/{pipeline_deployment → template_execution}/runner_entrypoint_configuration.py +1 -8
  116. zenml/zen_server/{pipeline_deployment → template_execution}/utils.py +214 -92
  117. zenml/zen_server/utils.py +2 -2
  118. zenml/zen_server/zen_server_api.py +2 -1
  119. zenml/zen_stores/migrations/versions/0.63.0_release.py +23 -0
  120. zenml/zen_stores/migrations/versions/7d1919bb1ef0_add_run_templates.py +100 -0
  121. zenml/zen_stores/migrations/versions/b59aa68fdb1f_simplify_pipelines.py +139 -0
  122. zenml/zen_stores/rest_zen_store.py +107 -36
  123. zenml/zen_stores/schemas/__init__.py +2 -0
  124. zenml/zen_stores/schemas/pipeline_build_schemas.py +3 -3
  125. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +29 -2
  126. zenml/zen_stores/schemas/pipeline_run_schemas.py +26 -3
  127. zenml/zen_stores/schemas/pipeline_schemas.py +29 -30
  128. zenml/zen_stores/schemas/run_template_schemas.py +264 -0
  129. zenml/zen_stores/schemas/step_run_schemas.py +11 -4
  130. zenml/zen_stores/sql_zen_store.py +364 -150
  131. zenml/zen_stores/template_utils.py +261 -0
  132. zenml/zen_stores/zen_store_interface.py +93 -20
  133. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.63.0.dev20240731.dist-info}/METADATA +2 -2
  134. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.63.0.dev20240731.dist-info}/RECORD +139 -129
  135. zenml/models/v2/core/pipeline_namespace.py +0 -113
  136. zenml/new/pipelines/deserialization_utils.py +0 -292
  137. zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +0 -1
  138. zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +0 -1
  139. zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +0 -1
  140. zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +0 -1
  141. zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +0 -1
  142. zenml/zen_server/dashboard/assets/package-B3fWP-Dh.js +0 -1
  143. zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +0 -1
  144. zenml/zen_server/dashboard/assets/page-Bq0YxkLV.js +0 -1
  145. zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +0 -2
  146. zenml/zen_server/dashboard/assets/page-CHNxpz3n.js +0 -1
  147. zenml/zen_server/dashboard/assets/page-DgorQFqi.js +0 -1
  148. zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +0 -1
  149. zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +0 -1
  150. zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +0 -9
  151. zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +0 -1
  152. zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +0 -1
  153. /zenml/zen_server/{pipeline_deployment → template_execution}/__init__.py +0 -0
  154. /zenml/zen_server/{pipeline_deployment → template_execution}/workload_manager_interface.py +0 -0
  155. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.63.0.dev20240731.dist-info}/LICENSE +0 -0
  156. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.63.0.dev20240731.dist-info}/WHEEL +0 -0
  157. {zenml_nightly-0.62.0.dev20240729.dist-info → zenml_nightly-0.63.0.dev20240731.dist-info}/entry_points.txt +0 -0
@@ -20,6 +20,7 @@ from pydantic import Field
20
20
 
21
21
  from zenml.config.docker_settings import SourceFileMode
22
22
  from zenml.config.pipeline_configurations import PipelineConfiguration
23
+ from zenml.config.pipeline_spec import PipelineSpec
23
24
  from zenml.config.step_configurations import Step
24
25
  from zenml.models.v2.base.base import BaseZenModel
25
26
  from zenml.models.v2.base.page import Page
@@ -71,6 +72,14 @@ class PipelineDeploymentBase(BaseZenModel):
71
72
  default=None,
72
73
  title="The version of the ZenML installation on the server side.",
73
74
  )
75
+ pipeline_version_hash: Optional[str] = Field(
76
+ default=None,
77
+ title="The pipeline version hash of the deployment.",
78
+ )
79
+ pipeline_spec: Optional[PipelineSpec] = Field(
80
+ default=None,
81
+ title="The pipeline spec of the deployment.",
82
+ )
74
83
 
75
84
  @property
76
85
  def requires_included_files(self) -> bool:
@@ -116,6 +125,10 @@ class PipelineDeploymentRequest(
116
125
  default=None,
117
126
  title="The code reference associated with the deployment.",
118
127
  )
128
+ template: Optional[UUID] = Field(
129
+ default=None,
130
+ description="Template used for the deployment.",
131
+ )
119
132
 
120
133
 
121
134
  # ------------------ Update Model ------------------
@@ -150,6 +163,13 @@ class PipelineDeploymentResponseMetadata(WorkspaceScopedResponseMetadata):
150
163
  server_version: Optional[str] = Field(
151
164
  title="The version of the ZenML installation on the server side."
152
165
  )
166
+ pipeline_version_hash: Optional[str] = Field(
167
+ default=None, title="The pipeline version hash of the deployment."
168
+ )
169
+ pipeline_spec: Optional[PipelineSpec] = Field(
170
+ default=None, title="The pipeline spec of the deployment."
171
+ )
172
+
153
173
  pipeline: Optional[PipelineResponse] = Field(
154
174
  default=None, title="The pipeline associated with the deployment."
155
175
  )
@@ -167,6 +187,10 @@ class PipelineDeploymentResponseMetadata(WorkspaceScopedResponseMetadata):
167
187
  default=None,
168
188
  title="The code reference associated with the deployment.",
169
189
  )
190
+ template_id: Optional[UUID] = Field(
191
+ default=None,
192
+ description="Template used for the pipeline run.",
193
+ )
170
194
 
171
195
 
172
196
  class PipelineDeploymentResponseResources(WorkspaceScopedResponseResources):
@@ -251,6 +275,24 @@ class PipelineDeploymentResponse(
251
275
  """
252
276
  return self.get_metadata().server_version
253
277
 
278
+ @property
279
+ def pipeline_version_hash(self) -> Optional[str]:
280
+ """The `pipeline_version_hash` property.
281
+
282
+ Returns:
283
+ the value of the property.
284
+ """
285
+ return self.get_metadata().pipeline_version_hash
286
+
287
+ @property
288
+ def pipeline_spec(self) -> Optional[PipelineSpec]:
289
+ """The `pipeline_spec` property.
290
+
291
+ Returns:
292
+ the value of the property.
293
+ """
294
+ return self.get_metadata().pipeline_spec
295
+
254
296
  @property
255
297
  def pipeline(self) -> Optional[PipelineResponse]:
256
298
  """The `pipeline` property.
@@ -296,6 +338,15 @@ class PipelineDeploymentResponse(
296
338
  """
297
339
  return self.get_metadata().code_reference
298
340
 
341
+ @property
342
+ def template_id(self) -> Optional[UUID]:
343
+ """The `template_id` property.
344
+
345
+ Returns:
346
+ the value of the property.
347
+ """
348
+ return self.get_metadata().template_id
349
+
299
350
  @property
300
351
  def requires_code_download(self) -> bool:
301
352
  """Whether the deployment requires downloading some code files.
@@ -345,3 +396,8 @@ class PipelineDeploymentFilter(WorkspaceScopedFilter):
345
396
  description="Schedule associated with the deployment.",
346
397
  union_mode="left_to_right",
347
398
  )
399
+ template_id: Optional[Union[UUID, str]] = Field(
400
+ default=None,
401
+ description="Template used as base for the deployment.",
402
+ union_mode="left_to_right",
403
+ )
@@ -37,8 +37,10 @@ from zenml.models.v2.base.scoped import (
37
37
  WorkspaceScopedResponseBody,
38
38
  WorkspaceScopedResponseMetadata,
39
39
  WorkspaceScopedResponseResources,
40
+ WorkspaceScopedTaggableFilter,
40
41
  )
41
42
  from zenml.models.v2.core.model_version import ModelVersionResponse
43
+ from zenml.models.v2.core.tag import TagResponse
42
44
 
43
45
  if TYPE_CHECKING:
44
46
  from sqlalchemy.sql.elements import ColumnElement
@@ -109,6 +111,10 @@ class PipelineRunRequest(WorkspaceScopedRequest):
109
111
  default=None,
110
112
  title="ID of the trigger execution that triggered this run.",
111
113
  )
114
+ tags: Optional[List[str]] = Field(
115
+ default=None,
116
+ title="Tags of the pipeline run.",
117
+ )
112
118
 
113
119
 
114
120
  # ------------------ Update Model ------------------
@@ -119,6 +125,13 @@ class PipelineRunUpdate(BaseModel):
119
125
 
120
126
  status: Optional[ExecutionStatus] = None
121
127
  end_time: Optional[datetime] = None
128
+ # TODO: we should maybe have a different update model here, the upper two attributes should only be for internal use
129
+ add_tags: Optional[List[str]] = Field(
130
+ default=None, title="New tags to add to the pipeline run."
131
+ )
132
+ remove_tags: Optional[List[str]] = Field(
133
+ default=None, title="Tags to remove from the pipeline run."
134
+ )
122
135
 
123
136
 
124
137
  # ------------------ Response Model ------------------
@@ -193,12 +206,19 @@ class PipelineRunResponseMetadata(WorkspaceScopedResponseMetadata):
193
206
  max_length=STR_FIELD_MAX_LENGTH,
194
207
  default=None,
195
208
  )
209
+ template_id: Optional[UUID] = Field(
210
+ default=None,
211
+ description="Template used for the pipeline run.",
212
+ )
196
213
 
197
214
 
198
215
  class PipelineRunResponseResources(WorkspaceScopedResponseResources):
199
216
  """Class for all resource models associated with the pipeline run entity."""
200
217
 
201
218
  model_version: Optional[ModelVersionResponse] = None
219
+ tags: List[TagResponse] = Field(
220
+ title="Tags associated with the pipeline run.",
221
+ )
202
222
 
203
223
  # TODO: In Pydantic v2, the `model_` is a protected namespaces for all
204
224
  # fields defined under base models. If not handled, this raises a warning.
@@ -405,6 +425,15 @@ class PipelineRunResponse(
405
425
  """
406
426
  return self.get_metadata().orchestrator_run_id
407
427
 
428
+ @property
429
+ def template_id(self) -> Optional[UUID]:
430
+ """The `template_id` property.
431
+
432
+ Returns:
433
+ the value of the property.
434
+ """
435
+ return self.get_metadata().template_id
436
+
408
437
  @property
409
438
  def model_version(self) -> Optional[ModelVersionResponse]:
410
439
  """The `model_version` property.
@@ -414,11 +443,20 @@ class PipelineRunResponse(
414
443
  """
415
444
  return self.get_resources().model_version
416
445
 
446
+ @property
447
+ def tags(self) -> List[TagResponse]:
448
+ """The `tags` property.
449
+
450
+ Returns:
451
+ the value of the property.
452
+ """
453
+ return self.get_resources().tags
454
+
417
455
 
418
456
  # ------------------ Filter Model ------------------
419
457
 
420
458
 
421
- class PipelineRunFilter(WorkspaceScopedFilter):
459
+ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
422
460
  """Model to enable advanced filtering of all Workspaces."""
423
461
 
424
462
  FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
@@ -428,6 +466,7 @@ class PipelineRunFilter(WorkspaceScopedFilter):
428
466
  "build_id",
429
467
  "schedule_id",
430
468
  "stack_id",
469
+ "template_id",
431
470
  "pipeline_name",
432
471
  ]
433
472
  name: Optional[str] = Field(
@@ -482,6 +521,11 @@ class PipelineRunFilter(WorkspaceScopedFilter):
482
521
  description="Code repository used for the Pipeline Run",
483
522
  union_mode="left_to_right",
484
523
  )
524
+ template_id: Optional[Union[UUID, str]] = Field(
525
+ default=None,
526
+ description="Template used for the pipeline run.",
527
+ union_mode="left_to_right",
528
+ )
485
529
  status: Optional[str] = Field(
486
530
  default=None,
487
531
  description="Name of the Pipeline Run",
@@ -574,4 +618,11 @@ class PipelineRunFilter(WorkspaceScopedFilter):
574
618
  )
575
619
  custom_filters.append(pipeline_build_filter)
576
620
 
621
+ if self.template_id:
622
+ run_template_filter = and_(
623
+ PipelineRunSchema.deployment_id == PipelineDeploymentSchema.id,
624
+ PipelineDeploymentSchema.template_id == self.template_id,
625
+ )
626
+ custom_filters.append(run_template_filter)
627
+
577
628
  return custom_filters
@@ -0,0 +1,393 @@
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 pipeline templates."""
15
+
16
+ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union
17
+ from uuid import UUID
18
+
19
+ from pydantic import Field
20
+
21
+ from zenml.config.pipeline_spec import PipelineSpec
22
+ from zenml.constants import STR_FIELD_MAX_LENGTH, TEXT_FIELD_MAX_LENGTH
23
+ from zenml.enums import ExecutionStatus
24
+ from zenml.models.v2.base.base import BaseUpdate
25
+ from zenml.models.v2.base.scoped import (
26
+ WorkspaceScopedRequest,
27
+ WorkspaceScopedResponse,
28
+ WorkspaceScopedResponseBody,
29
+ WorkspaceScopedResponseMetadata,
30
+ WorkspaceScopedResponseResources,
31
+ WorkspaceScopedTaggableFilter,
32
+ )
33
+ from zenml.models.v2.core.code_reference import (
34
+ CodeReferenceResponse,
35
+ )
36
+ from zenml.models.v2.core.pipeline import PipelineResponse
37
+ from zenml.models.v2.core.pipeline_build import (
38
+ PipelineBuildResponse,
39
+ )
40
+ from zenml.models.v2.core.pipeline_deployment import (
41
+ PipelineDeploymentResponse,
42
+ )
43
+ from zenml.models.v2.core.tag import TagResponse
44
+
45
+ if TYPE_CHECKING:
46
+ from sqlalchemy.sql.elements import ColumnElement
47
+
48
+ # ------------------ Request Model ------------------
49
+
50
+
51
+ class RunTemplateRequest(WorkspaceScopedRequest):
52
+ """Request model for run templates."""
53
+
54
+ name: str = Field(
55
+ title="The name of the run template.",
56
+ max_length=STR_FIELD_MAX_LENGTH,
57
+ )
58
+ description: Optional[str] = Field(
59
+ default=None,
60
+ title="The description of the run template.",
61
+ max_length=TEXT_FIELD_MAX_LENGTH,
62
+ )
63
+ source_deployment_id: UUID = Field(
64
+ title="The deployment that should be the base of the created template."
65
+ )
66
+ tags: Optional[List[str]] = Field(
67
+ default=None,
68
+ title="Tags of the run template.",
69
+ )
70
+
71
+
72
+ # ------------------ Update Model ------------------
73
+
74
+
75
+ class RunTemplateUpdate(BaseUpdate):
76
+ """Run template update model."""
77
+
78
+ name: Optional[str] = Field(
79
+ default=None,
80
+ title="The name of the run template.",
81
+ max_length=STR_FIELD_MAX_LENGTH,
82
+ )
83
+ description: Optional[str] = Field(
84
+ default=None,
85
+ title="The description of the run template.",
86
+ max_length=TEXT_FIELD_MAX_LENGTH,
87
+ )
88
+ add_tags: Optional[List[str]] = Field(
89
+ default=None, title="New tags to add to the run template."
90
+ )
91
+ remove_tags: Optional[List[str]] = Field(
92
+ default=None, title="Tags to remove from the run template."
93
+ )
94
+
95
+
96
+ # ------------------ Response Model ------------------
97
+
98
+
99
+ class RunTemplateResponseBody(WorkspaceScopedResponseBody):
100
+ """Response body for run templates."""
101
+
102
+ runnable: bool = Field(
103
+ title="If a run can be started from the template.",
104
+ )
105
+ latest_run_id: Optional[UUID] = Field(
106
+ default=None,
107
+ title="The ID of the latest run of the run template.",
108
+ )
109
+ latest_run_status: Optional[ExecutionStatus] = Field(
110
+ default=None,
111
+ title="The status of the latest run of the run template.",
112
+ )
113
+
114
+
115
+ class RunTemplateResponseMetadata(WorkspaceScopedResponseMetadata):
116
+ """Response metadata for run templates."""
117
+
118
+ description: Optional[str] = Field(
119
+ default=None,
120
+ title="The description of the run template.",
121
+ )
122
+ pipeline_spec: Optional[PipelineSpec] = Field(
123
+ default=None, title="The spec of the pipeline."
124
+ )
125
+ config_template: Optional[Dict[str, Any]] = Field(
126
+ default=None, title="Run configuration template."
127
+ )
128
+ config_schema: Optional[Dict[str, Any]] = Field(
129
+ default=None, title="Run configuration schema."
130
+ )
131
+
132
+
133
+ class RunTemplateResponseResources(WorkspaceScopedResponseResources):
134
+ """All resource models associated with the run template."""
135
+
136
+ source_deployment: Optional[PipelineDeploymentResponse] = Field(
137
+ default=None,
138
+ title="The deployment that is the source of the template.",
139
+ )
140
+ pipeline: Optional[PipelineResponse] = Field(
141
+ default=None, title="The pipeline associated with the template."
142
+ )
143
+ build: Optional[PipelineBuildResponse] = Field(
144
+ default=None,
145
+ title="The pipeline build associated with the template.",
146
+ )
147
+ code_reference: Optional[CodeReferenceResponse] = Field(
148
+ default=None,
149
+ title="The code reference associated with the template.",
150
+ )
151
+ tags: List[TagResponse] = Field(
152
+ title="Tags associated with the run template.",
153
+ )
154
+
155
+
156
+ class RunTemplateResponse(
157
+ WorkspaceScopedResponse[
158
+ RunTemplateResponseBody,
159
+ RunTemplateResponseMetadata,
160
+ RunTemplateResponseResources,
161
+ ]
162
+ ):
163
+ """Response model for run templates."""
164
+
165
+ name: str = Field(
166
+ title="The name of the run template.",
167
+ max_length=STR_FIELD_MAX_LENGTH,
168
+ )
169
+
170
+ def get_hydrated_version(self) -> "RunTemplateResponse":
171
+ """Return the hydrated version of this run template.
172
+
173
+ Returns:
174
+ The hydrated run template.
175
+ """
176
+ from zenml.client import Client
177
+
178
+ return Client().zen_store.get_run_template(
179
+ template_id=self.id, hydrate=True
180
+ )
181
+
182
+ # Body and metadata properties
183
+ @property
184
+ def runnable(self) -> bool:
185
+ """The `runnable` property.
186
+
187
+ Returns:
188
+ the value of the property.
189
+ """
190
+ return self.get_body().runnable
191
+
192
+ @property
193
+ def latest_run_id(self) -> Optional[UUID]:
194
+ """The `latest_run_id` property.
195
+
196
+ Returns:
197
+ the value of the property.
198
+ """
199
+ return self.get_body().latest_run_id
200
+
201
+ @property
202
+ def latest_run_status(self) -> Optional[ExecutionStatus]:
203
+ """The `latest_run_status` property.
204
+
205
+ Returns:
206
+ the value of the property.
207
+ """
208
+ return self.get_body().latest_run_status
209
+
210
+ @property
211
+ def description(self) -> Optional[str]:
212
+ """The `description` property.
213
+
214
+ Returns:
215
+ the value of the property.
216
+ """
217
+ return self.get_metadata().description
218
+
219
+ @property
220
+ def pipeline_spec(self) -> Optional[PipelineSpec]:
221
+ """The `pipeline_spec` property.
222
+
223
+ Returns:
224
+ the value of the property.
225
+ """
226
+ return self.get_metadata().pipeline_spec
227
+
228
+ @property
229
+ def config_template(self) -> Optional[Dict[str, Any]]:
230
+ """The `config_template` property.
231
+
232
+ Returns:
233
+ the value of the property.
234
+ """
235
+ return self.get_metadata().config_template
236
+
237
+ @property
238
+ def config_schema(self) -> Optional[Dict[str, Any]]:
239
+ """The `config_schema` property.
240
+
241
+ Returns:
242
+ the value of the property.
243
+ """
244
+ return self.get_metadata().config_schema
245
+
246
+ @property
247
+ def source_deployment(self) -> Optional[PipelineDeploymentResponse]:
248
+ """The `source_deployment` property.
249
+
250
+ Returns:
251
+ the value of the property.
252
+ """
253
+ return self.get_resources().source_deployment
254
+
255
+ @property
256
+ def pipeline(self) -> Optional[PipelineResponse]:
257
+ """The `pipeline` property.
258
+
259
+ Returns:
260
+ the value of the property.
261
+ """
262
+ return self.get_resources().pipeline
263
+
264
+ @property
265
+ def build(self) -> Optional[PipelineBuildResponse]:
266
+ """The `build` property.
267
+
268
+ Returns:
269
+ the value of the property.
270
+ """
271
+ return self.get_resources().build
272
+
273
+ @property
274
+ def code_reference(self) -> Optional[CodeReferenceResponse]:
275
+ """The `code_reference` property.
276
+
277
+ Returns:
278
+ the value of the property.
279
+ """
280
+ return self.get_resources().code_reference
281
+
282
+ @property
283
+ def tags(self) -> List[TagResponse]:
284
+ """The `tags` property.
285
+
286
+ Returns:
287
+ the value of the property.
288
+ """
289
+ return self.get_resources().tags
290
+
291
+
292
+ # ------------------ Filter Model ------------------
293
+
294
+
295
+ class RunTemplateFilter(WorkspaceScopedTaggableFilter):
296
+ """Model for filtering of run templates."""
297
+
298
+ FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
299
+ *WorkspaceScopedTaggableFilter.FILTER_EXCLUDE_FIELDS,
300
+ "code_repository_id",
301
+ "stack_id",
302
+ "build_id" "pipeline_id",
303
+ ]
304
+
305
+ name: Optional[str] = Field(
306
+ default=None,
307
+ description="Name of the run template.",
308
+ )
309
+ workspace_id: Optional[Union[UUID, str]] = Field(
310
+ default=None,
311
+ description="Workspace associated with the template.",
312
+ union_mode="left_to_right",
313
+ )
314
+ user_id: Optional[Union[UUID, str]] = Field(
315
+ default=None,
316
+ description="User that created the template.",
317
+ union_mode="left_to_right",
318
+ )
319
+ pipeline_id: Optional[Union[UUID, str]] = Field(
320
+ default=None,
321
+ description="Pipeline associated with the template.",
322
+ union_mode="left_to_right",
323
+ )
324
+ build_id: Optional[Union[UUID, str]] = Field(
325
+ default=None,
326
+ description="Build associated with the template.",
327
+ union_mode="left_to_right",
328
+ )
329
+ stack_id: Optional[Union[UUID, str]] = Field(
330
+ default=None,
331
+ description="Stack associated with the template.",
332
+ union_mode="left_to_right",
333
+ )
334
+ code_repository_id: Optional[Union[UUID, str]] = Field(
335
+ default=None,
336
+ description="Code repository associated with the template.",
337
+ union_mode="left_to_right",
338
+ )
339
+
340
+ def get_custom_filters(
341
+ self,
342
+ ) -> List["ColumnElement[bool]"]:
343
+ """Get custom filters.
344
+
345
+ Returns:
346
+ A list of custom filters.
347
+ """
348
+ custom_filters = super().get_custom_filters()
349
+
350
+ from sqlmodel import and_
351
+
352
+ from zenml.zen_stores.schemas import (
353
+ CodeReferenceSchema,
354
+ PipelineDeploymentSchema,
355
+ RunTemplateSchema,
356
+ )
357
+
358
+ if self.code_repository_id:
359
+ code_repo_filter = and_(
360
+ RunTemplateSchema.source_deployment_id
361
+ == PipelineDeploymentSchema.id,
362
+ PipelineDeploymentSchema.code_reference_id
363
+ == CodeReferenceSchema.id,
364
+ CodeReferenceSchema.code_repository_id
365
+ == self.code_repository_id,
366
+ )
367
+ custom_filters.append(code_repo_filter)
368
+
369
+ if self.stack_id:
370
+ stack_filter = and_(
371
+ RunTemplateSchema.source_deployment_id
372
+ == PipelineDeploymentSchema.id,
373
+ PipelineDeploymentSchema.stack_id == self.stack_id,
374
+ )
375
+ custom_filters.append(stack_filter)
376
+
377
+ if self.build_id:
378
+ build_filter = and_(
379
+ RunTemplateSchema.source_deployment_id
380
+ == PipelineDeploymentSchema.id,
381
+ PipelineDeploymentSchema.build_id == self.build_id,
382
+ )
383
+ custom_filters.append(build_filter)
384
+
385
+ if self.pipeline_id:
386
+ pipeline_filter = and_(
387
+ RunTemplateSchema.source_deployment_id
388
+ == PipelineDeploymentSchema.id,
389
+ PipelineDeploymentSchema.pipeline_id == self.pipeline_id,
390
+ )
391
+ custom_filters.append(pipeline_filter)
392
+
393
+ return custom_filters
@@ -72,9 +72,14 @@ class StackDeploymentConfig(BaseModel):
72
72
  title="A textual description for the cloud provider console URL.",
73
73
  )
74
74
  configuration: Optional[str] = Field(
75
+ default=None,
75
76
  title="Configuration for the stack deployment that the user must "
76
77
  "manually configure into the cloud provider console.",
77
78
  )
79
+ instructions: Optional[str] = Field(
80
+ default=None,
81
+ title="Instructions for deploying the stack.",
82
+ )
78
83
 
79
84
 
80
85
  class DeployedStack(BaseModel):