zenml-nightly 0.70.0.dev20241125__py3-none-any.whl → 0.71.0.dev20241220__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 (254) hide show
  1. README.md +4 -4
  2. RELEASE_NOTES.md +112 -0
  3. zenml/VERSION +1 -1
  4. zenml/artifact_stores/base_artifact_store.py +2 -2
  5. zenml/artifacts/artifact_config.py +15 -6
  6. zenml/artifacts/utils.py +59 -32
  7. zenml/cli/__init__.py +22 -4
  8. zenml/cli/base.py +5 -5
  9. zenml/cli/login.py +26 -0
  10. zenml/cli/pipeline.py +111 -62
  11. zenml/cli/server.py +20 -20
  12. zenml/cli/service_connectors.py +3 -3
  13. zenml/cli/stack.py +0 -3
  14. zenml/cli/stack_components.py +0 -1
  15. zenml/cli/utils.py +0 -5
  16. zenml/client.py +62 -20
  17. zenml/config/compiler.py +12 -3
  18. zenml/config/pipeline_configurations.py +20 -0
  19. zenml/config/pipeline_run_configuration.py +1 -0
  20. zenml/config/secret_reference_mixin.py +1 -1
  21. zenml/config/server_config.py +4 -0
  22. zenml/config/step_configurations.py +21 -0
  23. zenml/constants.py +10 -0
  24. zenml/enums.py +1 -0
  25. zenml/image_builders/base_image_builder.py +5 -2
  26. zenml/image_builders/build_context.py +7 -16
  27. zenml/image_builders/local_image_builder.py +13 -3
  28. zenml/integrations/__init__.py +1 -0
  29. zenml/integrations/aws/__init__.py +3 -0
  30. zenml/integrations/aws/flavors/__init__.py +6 -0
  31. zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
  32. zenml/integrations/aws/image_builders/__init__.py +20 -0
  33. zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
  34. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +14 -6
  35. zenml/integrations/constants.py +1 -0
  36. zenml/integrations/feast/__init__.py +1 -1
  37. zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -9
  38. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
  39. zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +2 -1
  40. zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +11 -0
  41. zenml/integrations/kubernetes/orchestrators/kube_utils.py +46 -2
  42. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +13 -2
  43. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +3 -1
  44. zenml/integrations/kubernetes/orchestrators/manifest_utils.py +3 -2
  45. zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +3 -2
  46. zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +11 -0
  47. zenml/integrations/modal/__init__.py +46 -0
  48. zenml/integrations/modal/flavors/__init__.py +26 -0
  49. zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
  50. zenml/integrations/modal/step_operators/__init__.py +22 -0
  51. zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
  52. zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
  53. zenml/integrations/neptune/experiment_trackers/run_state.py +69 -53
  54. zenml/integrations/registry.py +2 -2
  55. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +12 -0
  56. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +13 -5
  57. zenml/io/filesystem.py +2 -2
  58. zenml/io/local_filesystem.py +3 -3
  59. zenml/materializers/built_in_materializer.py +18 -1
  60. zenml/materializers/structured_string_materializer.py +8 -3
  61. zenml/model/model.py +23 -101
  62. zenml/model/utils.py +21 -17
  63. zenml/models/__init__.py +6 -0
  64. zenml/models/v2/base/filter.py +26 -30
  65. zenml/models/v2/base/scoped.py +258 -5
  66. zenml/models/v2/core/artifact_version.py +21 -29
  67. zenml/models/v2/core/code_repository.py +1 -12
  68. zenml/models/v2/core/component.py +5 -68
  69. zenml/models/v2/core/flavor.py +1 -11
  70. zenml/models/v2/core/model.py +1 -57
  71. zenml/models/v2/core/model_version.py +11 -36
  72. zenml/models/v2/core/model_version_artifact.py +11 -3
  73. zenml/models/v2/core/model_version_pipeline_run.py +14 -3
  74. zenml/models/v2/core/pipeline.py +47 -55
  75. zenml/models/v2/core/pipeline_build.py +67 -12
  76. zenml/models/v2/core/pipeline_deployment.py +0 -10
  77. zenml/models/v2/core/pipeline_run.py +110 -32
  78. zenml/models/v2/core/run_metadata.py +30 -9
  79. zenml/models/v2/core/run_template.py +21 -29
  80. zenml/models/v2/core/schedule.py +0 -10
  81. zenml/models/v2/core/secret.py +0 -14
  82. zenml/models/v2/core/service.py +9 -16
  83. zenml/models/v2/core/service_connector.py +0 -11
  84. zenml/models/v2/core/stack.py +21 -30
  85. zenml/models/v2/core/step_run.py +24 -18
  86. zenml/models/v2/core/trigger.py +19 -3
  87. zenml/models/v2/misc/run_metadata.py +38 -0
  88. zenml/orchestrators/base_orchestrator.py +13 -1
  89. zenml/orchestrators/input_utils.py +19 -6
  90. zenml/orchestrators/output_utils.py +5 -1
  91. zenml/orchestrators/publish_utils.py +12 -5
  92. zenml/orchestrators/step_launcher.py +16 -16
  93. zenml/orchestrators/step_run_utils.py +18 -197
  94. zenml/orchestrators/step_runner.py +40 -3
  95. zenml/orchestrators/utils.py +79 -50
  96. zenml/pipelines/build_utils.py +12 -0
  97. zenml/pipelines/pipeline_decorator.py +4 -0
  98. zenml/pipelines/pipeline_definition.py +26 -8
  99. zenml/pipelines/run_utils.py +9 -5
  100. zenml/service_connectors/service_connector_utils.py +3 -9
  101. zenml/stack/stack_component.py +1 -1
  102. zenml/stack_deployments/aws_stack_deployment.py +22 -0
  103. zenml/steps/base_step.py +11 -1
  104. zenml/steps/entrypoint_function_utils.py +7 -3
  105. zenml/steps/step_decorator.py +4 -0
  106. zenml/steps/utils.py +23 -7
  107. zenml/types.py +4 -0
  108. zenml/utils/archivable.py +65 -36
  109. zenml/utils/code_utils.py +8 -4
  110. zenml/utils/docker_utils.py +9 -0
  111. zenml/utils/metadata_utils.py +186 -153
  112. zenml/utils/string_utils.py +41 -16
  113. zenml/utils/visualization_utils.py +4 -1
  114. zenml/zen_server/auth.py +9 -10
  115. zenml/zen_server/cloud_utils.py +3 -1
  116. zenml/zen_server/dashboard/assets/{404-NVXKFp-x.js → 404-Cqu3EDCm.js} +1 -1
  117. zenml/zen_server/dashboard/assets/{@reactflow-CK0KJUen.js → @reactflow-D2Y7BWwz.js} +1 -1
  118. zenml/zen_server/dashboard/assets/{AlertDialogDropdownItem-DezXKmDf.js → AlertDialogDropdownItem-BHd71pVS.js} +1 -1
  119. zenml/zen_server/dashboard/assets/{CodeSnippet-JzR8CEtw.js → CodeSnippet-DIonwetW.js} +1 -1
  120. zenml/zen_server/dashboard/assets/{CollapsibleCard-DQW_ktMO.js → CollapsibleCard-CDnC97pB.js} +1 -1
  121. zenml/zen_server/dashboard/assets/{Commands-DL2kwkRd.js → Commands-BVEXKAOj.js} +1 -1
  122. zenml/zen_server/dashboard/assets/{ComponentBadge-D_g62Wv8.js → ComponentBadge-CrRvovox.js} +1 -1
  123. zenml/zen_server/dashboard/assets/{CopyButton-LNcWaa14.js → CopyButton-B6wGAhQv.js} +1 -1
  124. zenml/zen_server/dashboard/assets/{CsvVizualization-DknpE5ej.js → CsvVizualization-CjcT7LMm.js} +5 -5
  125. zenml/zen_server/dashboard/assets/DeleteAlertDialog-D2ELtM2W.js +1 -0
  126. zenml/zen_server/dashboard/assets/{DialogItem-Bxf8FuAT.js → DialogItem-DXIMhBgU.js} +1 -1
  127. zenml/zen_server/dashboard/assets/{Error-DYflYyps.js → Error-B8uUfTpL.js} +1 -1
  128. zenml/zen_server/dashboard/assets/{ExecutionStatus-C7zyIQKZ.js → ExecutionStatus-ibAdY-dG.js} +1 -1
  129. zenml/zen_server/dashboard/assets/{Helpbox-oYSGpLqd.js → Helpbox-BfAfhKHw.js} +1 -1
  130. zenml/zen_server/dashboard/assets/{Infobox-Cx4xGoXR.js → Infobox-M_SMOu96.js} +1 -1
  131. zenml/zen_server/dashboard/assets/{InlineAvatar-DiGOWNKF.js → InlineAvatar-DBA0a0-a.js} +1 -1
  132. zenml/zen_server/dashboard/assets/{NestedCollapsible-DYbgyKxK.js → NestedCollapsible-DpgmEFKw.js} +1 -1
  133. zenml/zen_server/dashboard/assets/{Partials-03iZf8-N.js → Partials-D_ldD9if.js} +1 -1
  134. zenml/zen_server/dashboard/assets/{ProBadge-D_EB8HNo.js → ProBadge-DQbfFotM.js} +1 -1
  135. zenml/zen_server/dashboard/assets/{ProCta-DqNS4v3x.js → ProCta-Bcpb4rcY.js} +1 -1
  136. zenml/zen_server/dashboard/assets/{ProviderIcon-Bki2aw8w.js → ProviderIcon-BZpgPigN.js} +1 -1
  137. zenml/zen_server/dashboard/assets/{ProviderRadio-8f43sPD4.js → ProviderRadio-DWPnMuQ1.js} +1 -1
  138. zenml/zen_server/dashboard/assets/RunSelector-DgRGaAc6.js +1 -0
  139. zenml/zen_server/dashboard/assets/{RunsBody-07YEO7qI.js → RunsBody-KecfSkjY.js} +1 -1
  140. zenml/zen_server/dashboard/assets/{SearchField-lp1KgU4e.js → SearchField-n-ILHnaP.js} +1 -1
  141. zenml/zen_server/dashboard/assets/{SecretTooltip-CgnbyeOx.js → SecretTooltip-B8MrX5yu.js} +1 -1
  142. zenml/zen_server/dashboard/assets/{SetPassword-CpP418A2.js → SetPassword-B_IVq_wg.js} +1 -1
  143. zenml/zen_server/dashboard/assets/StackList-TWPBYnkF.js +1 -0
  144. zenml/zen_server/dashboard/assets/{Tabs-BktHkCJJ.js → Tabs-Rg857zmd.js} +1 -1
  145. zenml/zen_server/dashboard/assets/{Tick-BlMoIlJT.js → Tick-COg4A-xo.js} +1 -1
  146. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-Sc0A0pP-.js → UpdatePasswordSchemas-C6Aj3hm6.js} +1 -1
  147. zenml/zen_server/dashboard/assets/{UsageReason-YYduL4fj.js → UsageReason-BTLbx7w4.js} +1 -1
  148. zenml/zen_server/dashboard/assets/{WizardFooter-dgmizSJC.js → WizardFooter-BCAj69Vj.js} +1 -1
  149. zenml/zen_server/dashboard/assets/{all-pipeline-runs-query-D-c2G6lV.js → all-pipeline-runs-query-DMXkDrV2.js} +1 -1
  150. zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
  151. zenml/zen_server/dashboard/assets/{create-stack-DM_JPgef.js → create-stack-HfdbhLs4.js} +1 -1
  152. zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
  153. zenml/zen_server/dashboard/assets/delete-run-DZ4hIXff.js +1 -0
  154. zenml/zen_server/dashboard/assets/{form-schemas-K6FYKjwa.js → form-schemas-B0AVEd9b.js} +1 -1
  155. zenml/zen_server/dashboard/assets/{index-BAkC7FXi.js → index-DPqSWjug.js} +1 -1
  156. zenml/zen_server/dashboard/assets/{index-CEV4Cvaf.js → index-DScjfBRb.js} +1 -1
  157. zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
  158. zenml/zen_server/dashboard/assets/{index-CCOPpudF.js → index-FO-p0GU7.js} +5 -5
  159. zenml/zen_server/dashboard/assets/{index-B1mVPYxf.js → index-I3bKUGUj.js} +1 -1
  160. zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
  161. zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
  162. zenml/zen_server/dashboard/assets/{login-mutation-hf-lK87O.js → login-mutation-BQeo4wTY.js} +1 -1
  163. zenml/zen_server/dashboard/assets/{not-found-BGirLjU-.js → not-found-gAJ5aDdR.js} +1 -1
  164. zenml/zen_server/dashboard/assets/page-9Y9-gig0.js +1 -0
  165. zenml/zen_server/dashboard/assets/{page-DjRJCGb3.js → page-AUwiQ14W.js} +1 -1
  166. zenml/zen_server/dashboard/assets/page-B6XU7yYT.js +2 -0
  167. zenml/zen_server/dashboard/assets/{page-C00YAkaB.js → page-BKZYc2Zv.js} +1 -1
  168. zenml/zen_server/dashboard/assets/{page-CdMWnQak.js → page-BU9FG4sR.js} +1 -1
  169. zenml/zen_server/dashboard/assets/{page-D7S3aCbF.js → page-B_Apk3xg.js} +1 -1
  170. zenml/zen_server/dashboard/assets/{page-Djikxq_S.js → page-BdowiCbr.js} +1 -1
  171. zenml/zen_server/dashboard/assets/page-Bg8OjTRe.js +1 -0
  172. zenml/zen_server/dashboard/assets/page-BxL4qD4_.js +1 -0
  173. zenml/zen_server/dashboard/assets/{page-DakHVWXF.js → page-CWxT5K5J.js} +1 -1
  174. zenml/zen_server/dashboard/assets/page-CXuQufSe.js +1 -0
  175. zenml/zen_server/dashboard/assets/{page-DLC-bNBP.js → page-CcQr8CPP.js} +1 -1
  176. zenml/zen_server/dashboard/assets/{page-CD-DcWoy.js → page-Ce4Hrjnr.js} +1 -1
  177. zenml/zen_server/dashboard/assets/page-CiYxgZP_.js +1 -0
  178. zenml/zen_server/dashboard/assets/page-Cldq1mpe.js +1 -0
  179. zenml/zen_server/dashboard/assets/{page-BDigxVpo.js → page-D4wdonLm.js} +1 -1
  180. zenml/zen_server/dashboard/assets/{page-D6uU2ax4.js → page-D8ObrbH8.js} +1 -1
  181. zenml/zen_server/dashboard/assets/{page-DXSTpqRD.js → page-DFuAUGt4.js} +1 -1
  182. zenml/zen_server/dashboard/assets/{page-CbpvrsDL.js → page-DGazBpuP.js} +1 -1
  183. zenml/zen_server/dashboard/assets/{page-COXXJj1k.js → page-DO1UcqPX.js} +1 -1
  184. zenml/zen_server/dashboard/assets/page-DRYXdL5o.js +1 -0
  185. zenml/zen_server/dashboard/assets/{page-Df-Fw0aq.js → page-DYEquBC2.js} +1 -1
  186. zenml/zen_server/dashboard/assets/page-Dk32IeZm.js +1 -0
  187. zenml/zen_server/dashboard/assets/{page-yYC9OI-E.js → page-I3nKFGie.js} +1 -1
  188. zenml/zen_server/dashboard/assets/{page-6m6yHHlE.js → page-M0w-n6vn.js} +1 -1
  189. zenml/zen_server/dashboard/assets/{page-Vcxara9U.js → page-R5dx3xGF.js} +1 -1
  190. zenml/zen_server/dashboard/assets/{page-BR68V0V1.js → page-bT5pOvcB.js} +1 -1
  191. zenml/zen_server/dashboard/assets/page-hUqK889I.js +6 -0
  192. zenml/zen_server/dashboard/assets/{page-CjGdWY13.js → page-h_Stveon.js} +1 -1
  193. zenml/zen_server/dashboard/assets/{page-D01JhjQB.js → page-r8XK5vR7.js} +1 -1
  194. zenml/zen_server/dashboard/assets/page-u_-ZXBKb.js +1 -0
  195. zenml/zen_server/dashboard/assets/page-zaMqB_ao.js +1 -0
  196. zenml/zen_server/dashboard/assets/{persist-GjC8PZoC.js → persist-AppN1B0J.js} +1 -1
  197. zenml/zen_server/dashboard/assets/{persist-Coz7ZWvz.js → persist-DAUi_3za.js} +1 -1
  198. zenml/zen_server/dashboard/assets/service-BqqeXLEe.js +2 -0
  199. zenml/zen_server/dashboard/assets/{sharedSchema-CQb14VSr.js → sharedSchema-uXN9FLLk.js} +1 -1
  200. zenml/zen_server/dashboard/assets/{stack-detail-query-OPEW-cDJ.js → stack-detail-query-XfZBiBP2.js} +1 -1
  201. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-LwuQfHYn.js → update-server-settings-mutation-BWmgVJwA.js} +1 -1
  202. zenml/zen_server/dashboard/assets/{url-CkvKAnwF.js → url-BLwMbzES.js} +1 -1
  203. zenml/zen_server/dashboard/index.html +4 -4
  204. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  205. zenml/zen_server/deploy/helm/README.md +2 -2
  206. zenml/zen_server/rbac/endpoint_utils.py +6 -4
  207. zenml/zen_server/rbac/models.py +3 -2
  208. zenml/zen_server/rbac/rbac_sql_zen_store.py +173 -0
  209. zenml/zen_server/rbac/utils.py +4 -7
  210. zenml/zen_server/routers/auth_endpoints.py +22 -11
  211. zenml/zen_server/routers/steps_endpoints.py +7 -1
  212. zenml/zen_server/routers/users_endpoints.py +35 -37
  213. zenml/zen_server/routers/workspaces_endpoints.py +44 -55
  214. zenml/zen_server/template_execution/utils.py +4 -1
  215. zenml/zen_server/utils.py +4 -3
  216. zenml/zen_stores/base_zen_store.py +10 -2
  217. zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
  218. zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
  219. zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
  220. zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
  221. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
  222. zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +7 -6
  223. zenml/zen_stores/rest_zen_store.py +76 -43
  224. zenml/zen_stores/schemas/__init__.py +5 -1
  225. zenml/zen_stores/schemas/artifact_schemas.py +12 -11
  226. zenml/zen_stores/schemas/component_schemas.py +0 -3
  227. zenml/zen_stores/schemas/model_schemas.py +55 -17
  228. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
  229. zenml/zen_stores/schemas/pipeline_run_schemas.py +52 -18
  230. zenml/zen_stores/schemas/pipeline_schemas.py +5 -0
  231. zenml/zen_stores/schemas/run_metadata_schemas.py +66 -31
  232. zenml/zen_stores/schemas/step_run_schemas.py +40 -13
  233. zenml/zen_stores/schemas/utils.py +47 -3
  234. zenml/zen_stores/sql_zen_store.py +462 -134
  235. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/METADATA +5 -5
  236. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/RECORD +239 -217
  237. zenml/utils/cloud_utils.py +0 -40
  238. zenml/zen_server/dashboard/assets/RunSelector-DkPiIiNr.js +0 -1
  239. zenml/zen_server/dashboard/assets/StackList-WvuKQusZ.js +0 -1
  240. zenml/zen_server/dashboard/assets/delete-run-CJdh1P_h.js +0 -1
  241. zenml/zen_server/dashboard/assets/index-DlGvJQPn.css +0 -1
  242. zenml/zen_server/dashboard/assets/page-0JE_-Ec1.js +0 -1
  243. zenml/zen_server/dashboard/assets/page-BRLpxOt0.js +0 -1
  244. zenml/zen_server/dashboard/assets/page-BU7huvKw.js +0 -6
  245. zenml/zen_server/dashboard/assets/page-BvqLv2Ky.js +0 -1
  246. zenml/zen_server/dashboard/assets/page-CwxrFarU.js +0 -1
  247. zenml/zen_server/dashboard/assets/page-DfbXf_8s.js +0 -1
  248. zenml/zen_server/dashboard/assets/page-Dnovpa0i.js +0 -3
  249. zenml/zen_server/dashboard/assets/page-Dot3LPmL.js +0 -1
  250. zenml/zen_server/dashboard/assets/page-Xynx4btY.js +0 -14
  251. zenml/zen_server/dashboard/assets/page-YpKAqVSa.js +0 -1
  252. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/LICENSE +0 -0
  253. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/WHEEL +0 -0
  254. {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.71.0.dev20241220.dist-info}/entry_points.txt +0 -0
@@ -15,7 +15,7 @@
15
15
 
16
16
  import json
17
17
  from datetime import datetime
18
- from typing import TYPE_CHECKING, Any, List, Optional
18
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
19
19
  from uuid import UUID
20
20
 
21
21
  from pydantic import ConfigDict
@@ -34,6 +34,7 @@ from zenml.models import (
34
34
  PipelineRunResponseBody,
35
35
  PipelineRunResponseMetadata,
36
36
  PipelineRunUpdate,
37
+ RunMetadataEntry,
37
38
  )
38
39
  from zenml.models.v2.core.pipeline_run import PipelineRunResponseResources
39
40
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
@@ -48,6 +49,7 @@ from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
48
49
  from zenml.zen_stores.schemas.stack_schemas import StackSchema
49
50
  from zenml.zen_stores.schemas.trigger_schemas import TriggerExecutionSchema
50
51
  from zenml.zen_stores.schemas.user_schemas import UserSchema
52
+ from zenml.zen_stores.schemas.utils import RunMetadataInterface
51
53
  from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
52
54
 
53
55
  if TYPE_CHECKING:
@@ -56,13 +58,15 @@ if TYPE_CHECKING:
56
58
  ModelVersionPipelineRunSchema,
57
59
  ModelVersionSchema,
58
60
  )
59
- from zenml.zen_stores.schemas.run_metadata_schemas import RunMetadataSchema
61
+ from zenml.zen_stores.schemas.run_metadata_schemas import (
62
+ RunMetadataResourceSchema,
63
+ )
60
64
  from zenml.zen_stores.schemas.service_schemas import ServiceSchema
61
65
  from zenml.zen_stores.schemas.step_run_schemas import StepRunSchema
62
66
  from zenml.zen_stores.schemas.tag_schemas import TagResourceSchema
63
67
 
64
68
 
65
- class PipelineRunSchema(NamedSchema, table=True):
69
+ class PipelineRunSchema(NamedSchema, RunMetadataInterface, table=True):
66
70
  """SQL Model for pipeline runs."""
67
71
 
68
72
  __tablename__ = "pipeline_run"
@@ -136,12 +140,12 @@ class PipelineRunSchema(NamedSchema, table=True):
136
140
  )
137
141
  workspace: "WorkspaceSchema" = Relationship(back_populates="runs")
138
142
  user: Optional["UserSchema"] = Relationship(back_populates="runs")
139
- run_metadata: List["RunMetadataSchema"] = Relationship(
140
- back_populates="pipeline_run",
143
+ run_metadata_resources: List["RunMetadataResourceSchema"] = Relationship(
144
+ back_populates="pipeline_runs",
141
145
  sa_relationship_kwargs=dict(
142
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.PIPELINE_RUN.value}', foreign(RunMetadataSchema.resource_id)==PipelineRunSchema.id)",
146
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.PIPELINE_RUN.value}', foreign(RunMetadataResourceSchema.resource_id)==PipelineRunSchema.id)",
143
147
  cascade="delete",
144
- overlaps="run_metadata",
148
+ overlaps="run_metadata_resources",
145
149
  ),
146
150
  )
147
151
  logs: Optional["LogsSchema"] = Relationship(
@@ -249,6 +253,24 @@ class PipelineRunSchema(NamedSchema, table=True):
249
253
  model_version_id=request.model_version_id,
250
254
  )
251
255
 
256
+ def fetch_metadata_collection(self) -> Dict[str, List[RunMetadataEntry]]:
257
+ """Fetches all the metadata entries related to the pipeline run.
258
+
259
+ Returns:
260
+ a dictionary, where the key is the key of the metadata entry
261
+ and the values represent the list of entries with this key.
262
+ """
263
+ # Fetch the metadata related to this run
264
+ metadata_collection = super().fetch_metadata_collection()
265
+
266
+ # Fetch the metadata related to the steps of this run
267
+ for s in self.step_runs:
268
+ step_metadata = s.fetch_metadata_collection()
269
+ for k, v in step_metadata.items():
270
+ metadata_collection[f"{s.name}::{k}"] = v
271
+
272
+ return metadata_collection
273
+
252
274
  def to_model(
253
275
  self,
254
276
  include_metadata: bool = False,
@@ -275,15 +297,14 @@ class PipelineRunSchema(NamedSchema, table=True):
275
297
  else {}
276
298
  )
277
299
 
278
- run_metadata = {
279
- metadata_schema.key: json.loads(metadata_schema.value)
280
- for metadata_schema in self.run_metadata
281
- }
282
-
283
300
  if self.deployment is not None:
284
- deployment = self.deployment.to_model()
301
+ deployment = self.deployment.to_model(include_metadata=True)
285
302
 
286
303
  config = deployment.pipeline_configuration
304
+ new_substitutions = config._get_full_substitutions(self.start_time)
305
+ config = config.model_copy(
306
+ update={"substitutions": new_substitutions}
307
+ )
287
308
  client_environment = deployment.client_environment
288
309
 
289
310
  stack = deployment.stack
@@ -323,9 +344,11 @@ class PipelineRunSchema(NamedSchema, table=True):
323
344
  build=build,
324
345
  schedule=schedule,
325
346
  code_reference=code_reference,
326
- trigger_execution=self.trigger_execution.to_model()
327
- if self.trigger_execution
328
- else None,
347
+ trigger_execution=(
348
+ self.trigger_execution.to_model()
349
+ if self.trigger_execution
350
+ else None
351
+ ),
329
352
  created=self.created,
330
353
  updated=self.updated,
331
354
  deployment_id=self.deployment_id,
@@ -342,11 +365,21 @@ class PipelineRunSchema(NamedSchema, table=True):
342
365
  ):
343
366
  is_templatable = True
344
367
 
345
- steps = {step.name: step.to_model() for step in self.step_runs}
368
+ steps = {
369
+ step.name: step.to_model(include_metadata=True)
370
+ for step in self.step_runs
371
+ }
372
+
373
+ step_substitutions = {}
374
+ for step_name, step in steps.items():
375
+ step_substitutions[step_name] = step.config.substitutions
376
+ # We fetch the steps hydrated before, but want them unhydrated
377
+ # in the response -> We need to reset the metadata here
378
+ step.metadata = None
346
379
 
347
380
  metadata = PipelineRunResponseMetadata(
348
381
  workspace=self.workspace.to_model(),
349
- run_metadata=run_metadata,
382
+ run_metadata=self.fetch_metadata(),
350
383
  config=config,
351
384
  steps=steps,
352
385
  start_time=self.start_time,
@@ -361,6 +394,7 @@ class PipelineRunSchema(NamedSchema, table=True):
361
394
  if self.deployment
362
395
  else None,
363
396
  is_templatable=is_templatable,
397
+ step_substitutions=step_substitutions,
364
398
  )
365
399
 
366
400
  resources = None
@@ -156,7 +156,12 @@ class PipelineSchema(NamedSchema, table=True):
156
156
 
157
157
  resources = None
158
158
  if include_resources:
159
+ latest_run_user = self.runs[-1].user if self.runs else None
160
+
159
161
  resources = PipelineResponseResources(
162
+ latest_run_user=latest_run_user.to_model()
163
+ if latest_run_user
164
+ else None,
160
165
  tags=[t.tag.to_model() for t in self.tags],
161
166
  )
162
167
 
@@ -14,15 +14,16 @@
14
14
  """SQLModel implementation of pipeline run metadata tables."""
15
15
 
16
16
  from typing import TYPE_CHECKING, List, Optional
17
- from uuid import UUID
17
+ from uuid import UUID, uuid4
18
18
 
19
19
  from sqlalchemy import TEXT, VARCHAR, Column
20
- from sqlmodel import Field, Relationship
20
+ from sqlmodel import Field, Relationship, SQLModel
21
21
 
22
22
  from zenml.enums import MetadataResourceTypes
23
23
  from zenml.zen_stores.schemas.base_schemas import BaseSchema
24
24
  from zenml.zen_stores.schemas.component_schemas import StackComponentSchema
25
25
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
26
+ from zenml.zen_stores.schemas.step_run_schemas import StepRunSchema
26
27
  from zenml.zen_stores.schemas.user_schemas import UserSchema
27
28
  from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
28
29
 
@@ -30,7 +31,6 @@ if TYPE_CHECKING:
30
31
  from zenml.zen_stores.schemas.artifact_schemas import ArtifactVersionSchema
31
32
  from zenml.zen_stores.schemas.model_schemas import ModelVersionSchema
32
33
  from zenml.zen_stores.schemas.pipeline_run_schemas import PipelineRunSchema
33
- from zenml.zen_stores.schemas.step_run_schemas import StepRunSchema
34
34
 
35
35
 
36
36
  class RunMetadataSchema(BaseSchema, table=True):
@@ -38,35 +38,10 @@ class RunMetadataSchema(BaseSchema, table=True):
38
38
 
39
39
  __tablename__ = "run_metadata"
40
40
 
41
- resource_id: UUID
42
- resource_type: str = Field(sa_column=Column(VARCHAR(255), nullable=False))
43
- pipeline_run: List["PipelineRunSchema"] = Relationship(
44
- back_populates="run_metadata",
45
- sa_relationship_kwargs=dict(
46
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.PIPELINE_RUN.value}', foreign(RunMetadataSchema.resource_id)==PipelineRunSchema.id)",
47
- overlaps="run_metadata,step_run,artifact_version,model_version",
48
- ),
49
- )
50
- step_run: List["StepRunSchema"] = Relationship(
51
- back_populates="run_metadata",
52
- sa_relationship_kwargs=dict(
53
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.STEP_RUN.value}', foreign(RunMetadataSchema.resource_id)==StepRunSchema.id)",
54
- overlaps="run_metadata,pipeline_run,artifact_version,model_version",
55
- ),
56
- )
57
- artifact_version: List["ArtifactVersionSchema"] = Relationship(
58
- back_populates="run_metadata",
59
- sa_relationship_kwargs=dict(
60
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.ARTIFACT_VERSION.value}', foreign(RunMetadataSchema.resource_id)==ArtifactVersionSchema.id)",
61
- overlaps="run_metadata,pipeline_run,step_run,model_version",
62
- ),
63
- )
64
- model_version: List["ModelVersionSchema"] = Relationship(
41
+ # Relationship to link to resources
42
+ resources: List["RunMetadataResourceSchema"] = Relationship(
65
43
  back_populates="run_metadata",
66
- sa_relationship_kwargs=dict(
67
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.MODEL_VERSION.value}', foreign(RunMetadataSchema.resource_id)==ModelVersionSchema.id)",
68
- overlaps="run_metadata,pipeline_run,step_run,artifact_version",
69
- ),
44
+ sa_relationship_kwargs={"cascade": "delete"},
70
45
  )
71
46
  stack_component_id: Optional[UUID] = build_foreign_key_field(
72
47
  source=__tablename__,
@@ -103,3 +78,63 @@ class RunMetadataSchema(BaseSchema, table=True):
103
78
  key: str
104
79
  value: str = Field(sa_column=Column(TEXT, nullable=False))
105
80
  type: str
81
+
82
+ publisher_step_id: Optional[UUID] = build_foreign_key_field(
83
+ source=__tablename__,
84
+ target=StepRunSchema.__tablename__,
85
+ source_column="publisher_step_id",
86
+ target_column="id",
87
+ ondelete="SET NULL",
88
+ nullable=True,
89
+ )
90
+
91
+
92
+ class RunMetadataResourceSchema(SQLModel, table=True):
93
+ """Table for linking resources to run metadata entries."""
94
+
95
+ __tablename__ = "run_metadata_resource"
96
+
97
+ id: UUID = Field(default_factory=uuid4, primary_key=True)
98
+ resource_id: UUID
99
+ resource_type: str = Field(sa_column=Column(VARCHAR(255), nullable=False))
100
+ run_metadata_id: UUID = build_foreign_key_field(
101
+ source=__tablename__,
102
+ target=RunMetadataSchema.__tablename__,
103
+ source_column="run_metadata_id",
104
+ target_column="id",
105
+ ondelete="CASCADE",
106
+ nullable=False,
107
+ )
108
+
109
+ # Relationship back to the base metadata table
110
+ run_metadata: RunMetadataSchema = Relationship(back_populates="resources")
111
+
112
+ # Relationship to link specific resource types
113
+ pipeline_runs: List["PipelineRunSchema"] = Relationship(
114
+ back_populates="run_metadata_resources",
115
+ sa_relationship_kwargs=dict(
116
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.PIPELINE_RUN.value}', foreign(RunMetadataResourceSchema.resource_id)==PipelineRunSchema.id)",
117
+ overlaps="run_metadata_resources,step_runs,artifact_versions,model_versions",
118
+ ),
119
+ )
120
+ step_runs: List["StepRunSchema"] = Relationship(
121
+ back_populates="run_metadata_resources",
122
+ sa_relationship_kwargs=dict(
123
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.STEP_RUN.value}', foreign(RunMetadataResourceSchema.resource_id)==StepRunSchema.id)",
124
+ overlaps="run_metadata_resources,pipeline_runs,artifact_versions,model_versions",
125
+ ),
126
+ )
127
+ artifact_versions: List["ArtifactVersionSchema"] = Relationship(
128
+ back_populates="run_metadata_resources",
129
+ sa_relationship_kwargs=dict(
130
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.ARTIFACT_VERSION.value}', foreign(RunMetadataResourceSchema.resource_id)==ArtifactVersionSchema.id)",
131
+ overlaps="run_metadata_resources,pipeline_runs,step_runs,model_versions",
132
+ ),
133
+ )
134
+ model_versions: List["ModelVersionSchema"] = Relationship(
135
+ back_populates="run_metadata_resources",
136
+ sa_relationship_kwargs=dict(
137
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.MODEL_VERSION.value}', foreign(RunMetadataResourceSchema.resource_id)==ModelVersionSchema.id)",
138
+ overlaps="run_metadata_resources,pipeline_runs,step_runs,artifact_versions",
139
+ ),
140
+ )
@@ -19,10 +19,11 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional
19
19
  from uuid import UUID
20
20
 
21
21
  from pydantic import ConfigDict
22
- from sqlalchemy import TEXT, Column, String
22
+ from sqlalchemy import TEXT, Column, String, UniqueConstraint
23
23
  from sqlalchemy.dialects.mysql import MEDIUMTEXT
24
24
  from sqlmodel import Field, Relationship, SQLModel
25
25
 
26
+ from zenml.config.pipeline_configurations import PipelineConfiguration
26
27
  from zenml.config.step_configurations import Step
27
28
  from zenml.constants import MEDIUMTEXT_MAX_LENGTH
28
29
  from zenml.enums import (
@@ -50,19 +51,29 @@ from zenml.zen_stores.schemas.pipeline_deployment_schemas import (
50
51
  from zenml.zen_stores.schemas.pipeline_run_schemas import PipelineRunSchema
51
52
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
52
53
  from zenml.zen_stores.schemas.user_schemas import UserSchema
54
+ from zenml.zen_stores.schemas.utils import RunMetadataInterface
53
55
  from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
54
56
 
55
57
  if TYPE_CHECKING:
56
58
  from zenml.zen_stores.schemas.artifact_schemas import ArtifactVersionSchema
57
59
  from zenml.zen_stores.schemas.logs_schemas import LogsSchema
58
60
  from zenml.zen_stores.schemas.model_schemas import ModelVersionSchema
59
- from zenml.zen_stores.schemas.run_metadata_schemas import RunMetadataSchema
61
+ from zenml.zen_stores.schemas.run_metadata_schemas import (
62
+ RunMetadataResourceSchema,
63
+ )
60
64
 
61
65
 
62
- class StepRunSchema(NamedSchema, table=True):
66
+ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
63
67
  """SQL Model for steps of pipeline runs."""
64
68
 
65
69
  __tablename__ = "step_run"
70
+ __table_args__ = (
71
+ UniqueConstraint(
72
+ "name",
73
+ "pipeline_run_id",
74
+ name="unique_step_name_for_pipeline_run",
75
+ ),
76
+ )
66
77
 
67
78
  # Fields
68
79
  start_time: Optional[datetime] = Field(nullable=True)
@@ -139,12 +150,12 @@ class StepRunSchema(NamedSchema, table=True):
139
150
  deployment: Optional["PipelineDeploymentSchema"] = Relationship(
140
151
  back_populates="step_runs"
141
152
  )
142
- run_metadata: List["RunMetadataSchema"] = Relationship(
143
- back_populates="step_run",
153
+ run_metadata_resources: List["RunMetadataResourceSchema"] = Relationship(
154
+ back_populates="step_runs",
144
155
  sa_relationship_kwargs=dict(
145
- primaryjoin=f"and_(RunMetadataSchema.resource_type=='{MetadataResourceTypes.STEP_RUN.value}', foreign(RunMetadataSchema.resource_id)==StepRunSchema.id)",
156
+ primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.STEP_RUN.value}', foreign(RunMetadataResourceSchema.resource_id)==StepRunSchema.id)",
146
157
  cascade="delete",
147
- overlaps="run_metadata",
158
+ overlaps="run_metadata_resources",
148
159
  ),
149
160
  )
150
161
  input_artifacts: List["StepRunInputArtifactSchema"] = Relationship(
@@ -163,9 +174,15 @@ class StepRunSchema(NamedSchema, table=True):
163
174
  "primaryjoin": "StepRunParentsSchema.child_id == StepRunSchema.id",
164
175
  },
165
176
  )
177
+ pipeline_run: "PipelineRunSchema" = Relationship(
178
+ back_populates="step_runs"
179
+ )
166
180
  model_version: "ModelVersionSchema" = Relationship(
167
181
  back_populates="step_runs",
168
182
  )
183
+ original_step_run: Optional["StepRunSchema"] = Relationship(
184
+ sa_relationship_kwargs={"remote_side": "StepRunSchema.id"}
185
+ )
169
186
 
170
187
  model_config = ConfigDict(protected_namespaces=()) # type: ignore[assignment]
171
188
 
@@ -218,11 +235,6 @@ class StepRunSchema(NamedSchema, table=True):
218
235
  RuntimeError: If the step run schema does not have a deployment_id
219
236
  or a step_configuration.
220
237
  """
221
- run_metadata = {
222
- metadata_schema.key: json.loads(metadata_schema.value)
223
- for metadata_schema in self.run_metadata
224
- }
225
-
226
238
  input_artifacts = {
227
239
  artifact.name: StepRunInputResponse(
228
240
  input_type=StepRunInputArtifactType(artifact.type),
@@ -248,6 +260,21 @@ class StepRunSchema(NamedSchema, table=True):
248
260
  full_step_config = Step.model_validate(
249
261
  step_configuration[self.name]
250
262
  )
263
+ new_substitutions = (
264
+ full_step_config.config._get_full_substitutions(
265
+ PipelineConfiguration.model_validate_json(
266
+ self.deployment.pipeline_configuration
267
+ ),
268
+ self.pipeline_run.start_time,
269
+ )
270
+ )
271
+ full_step_config = full_step_config.model_copy(
272
+ update={
273
+ "config": full_step_config.config.model_copy(
274
+ update={"substitutions": new_substitutions}
275
+ )
276
+ }
277
+ )
251
278
  elif not self.step_configuration:
252
279
  raise ValueError(
253
280
  f"Unable to load the configuration for step `{self.name}` from the"
@@ -294,7 +321,7 @@ class StepRunSchema(NamedSchema, table=True):
294
321
  pipeline_run_id=self.pipeline_run_id,
295
322
  original_step_run_id=self.original_step_run_id,
296
323
  parent_step_ids=[p.parent_id for p in self.parents],
297
- run_metadata=run_metadata,
324
+ run_metadata=self.fetch_metadata(),
298
325
  )
299
326
 
300
327
  resources = None
@@ -13,11 +13,14 @@
13
13
  # permissions and limitations under the License.
14
14
  """Utils for schemas."""
15
15
 
16
+ import json
16
17
  import math
17
- from typing import List, Type, TypeVar
18
+ from typing import Dict, List, Type, TypeVar
18
19
 
19
- from zenml.models.v2.base.base import BaseResponse
20
- from zenml.models.v2.base.page import Page
20
+ from sqlmodel import Relationship
21
+
22
+ from zenml.metadata.metadata_types import MetadataType
23
+ from zenml.models import BaseResponse, Page, RunMetadataEntry
21
24
  from zenml.zen_stores.schemas.base_schemas import BaseSchema
22
25
 
23
26
  S = TypeVar("S", bound=BaseSchema)
@@ -67,3 +70,44 @@ def get_page_from_list(
67
70
  total=total,
68
71
  items=page_items,
69
72
  )
73
+
74
+
75
+ class RunMetadataInterface:
76
+ """The interface for entities with run metadata."""
77
+
78
+ run_metadata_resources = Relationship()
79
+
80
+ def fetch_metadata_collection(self) -> Dict[str, List[RunMetadataEntry]]:
81
+ """Fetches all the metadata entries related to the artifact version.
82
+
83
+ Returns:
84
+ a dictionary, where the key is the key of the metadata entry
85
+ and the values represent the list of entries with this key.
86
+ """
87
+ metadata_collection: Dict[str, List[RunMetadataEntry]] = {}
88
+
89
+ # Fetch the metadata related to this step
90
+ for rm in self.run_metadata_resources:
91
+ if rm.run_metadata.key not in metadata_collection:
92
+ metadata_collection[rm.run_metadata.key] = []
93
+ metadata_collection[rm.run_metadata.key].append(
94
+ RunMetadataEntry(
95
+ value=json.loads(rm.run_metadata.value),
96
+ created=rm.run_metadata.created,
97
+ )
98
+ )
99
+
100
+ return metadata_collection
101
+
102
+ def fetch_metadata(self) -> Dict[str, MetadataType]:
103
+ """Fetches the latest metadata entry related to the artifact version.
104
+
105
+ Returns:
106
+ a dictionary, where the key is the key of the metadata entry
107
+ and the values represent the latest entry with this key.
108
+ """
109
+ metadata_collection = self.fetch_metadata_collection()
110
+ return {
111
+ k: sorted(v, key=lambda x: x.created, reverse=True)[0].value
112
+ for k, v in metadata_collection.items()
113
+ }