zenml-nightly 0.58.0.dev20240529__py3-none-any.whl → 0.58.1.dev20240608__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 (145) hide show
  1. CONTRIBUTING.md +1 -1
  2. README.md +3 -3
  3. RELEASE_NOTES.md +37 -1
  4. zenml/VERSION +1 -1
  5. zenml/artifacts/utils.py +19 -3
  6. zenml/cli/__init__.py +28 -22
  7. zenml/cli/base.py +17 -6
  8. zenml/cli/pipeline.py +18 -3
  9. zenml/cli/server.py +1 -1
  10. zenml/cli/stack.py +1 -1
  11. zenml/client.py +24 -4
  12. zenml/config/docker_settings.py +3 -0
  13. zenml/config/global_config.py +1 -1
  14. zenml/config/secret_reference_mixin.py +1 -1
  15. zenml/environment.py +1 -1
  16. zenml/integrations/huggingface/materializers/huggingface_tokenizer_materializer.py +11 -12
  17. zenml/integrations/kaniko/flavors/kaniko_image_builder_flavor.py +2 -44
  18. zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +4 -1
  19. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +4 -16
  20. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +2 -1
  21. zenml/integrations/kubernetes/orchestrators/manifest_utils.py +15 -15
  22. zenml/integrations/s3/flavors/s3_artifact_store_flavor.py +0 -38
  23. zenml/integrations/spark/flavors/spark_step_operator_flavor.py +1 -38
  24. zenml/materializers/base_materializer.py +3 -3
  25. zenml/materializers/cloudpickle_materializer.py +1 -1
  26. zenml/orchestrators/base_orchestrator.py +1 -1
  27. zenml/orchestrators/local_docker/local_docker_orchestrator.py +1 -37
  28. zenml/orchestrators/step_runner.py +2 -2
  29. zenml/stack/flavor.py +3 -1
  30. zenml/stack/stack.py +2 -2
  31. zenml/stack/stack_component.py +42 -2
  32. zenml/steps/base_step.py +1 -1
  33. zenml/steps/entrypoint_function_utils.py +2 -2
  34. zenml/steps/utils.py +1 -1
  35. zenml/utils/dashboard_utils.py +1 -1
  36. zenml/utils/pipeline_docker_image_builder.py +23 -3
  37. zenml/utils/source_utils.py +32 -7
  38. zenml/zen_server/auth.py +2 -2
  39. zenml/zen_server/dashboard/assets/{404-DIgYOHj5.js → 404-D5p6PIdn.js} +1 -1
  40. zenml/zen_server/dashboard/assets/{@radix-BrEjOMvl.js → @radix-C9DBgJhe.js} +9 -9
  41. zenml/zen_server/dashboard/assets/@react-router-DYovave8.js +29 -0
  42. zenml/zen_server/dashboard/assets/@reactflow-C26Olbza.css +1 -0
  43. zenml/zen_server/dashboard/assets/@reactflow-CegZ5GV3.js +17 -0
  44. zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +30 -0
  45. zenml/zen_server/dashboard/assets/{AwarenessChannel-CqRB1HO9.js → AwarenessChannel-DDpU6zHx.js} +1 -1
  46. zenml/zen_server/dashboard/assets/{Cards-DuJ8uYGM.js → Cards-wfOUm_Ae.js} +1 -1
  47. zenml/zen_server/dashboard/assets/CodeSnippet-iinvcx17.js +9 -0
  48. zenml/zen_server/dashboard/assets/Commands-DGnWeAWF.js +1 -0
  49. zenml/zen_server/dashboard/assets/{CopyButton-BOFZCr5Z.js → CopyButton-eUfW9370.js} +2 -2
  50. zenml/zen_server/dashboard/assets/{CsvVizualization-D4QRvdDk.js → CsvVizualization-CoIkmrjr.js} +7 -7
  51. zenml/zen_server/dashboard/assets/{DisplayDate-BoCi3-Ng.js → DisplayDate-BdguISQF.js} +1 -1
  52. zenml/zen_server/dashboard/assets/{EmptyState-CPJglRv0.js → EmptyState-BkooiGtL.js} +1 -1
  53. zenml/zen_server/dashboard/assets/{Error-C9i5GdiH.js → Error-CDMUBgpN.js} +1 -1
  54. zenml/zen_server/dashboard/assets/{Helpbox-CnuWjxcc.js → Helpbox-BV73V0J6.js} +1 -1
  55. zenml/zen_server/dashboard/assets/Infobox-DG7zmtut.js +1 -0
  56. zenml/zen_server/dashboard/assets/{InlineAvatar-DE_1-SDN.js → InlineAvatar-BiKh3XC5.js} +1 -1
  57. zenml/zen_server/dashboard/assets/{MarkdownVisualization-CMOybYJS.js → MarkdownVisualization-DsB2QZiK.js} +1 -1
  58. zenml/zen_server/dashboard/assets/{PageHeader-D7r1Jb6H.js → PageHeader-D-u0obgg.js} +1 -1
  59. zenml/zen_server/dashboard/assets/{Pagination-0-Hv-4DJ.js → Pagination-ZYqHJ5gE.js} +1 -1
  60. zenml/zen_server/dashboard/assets/{PasswordChecker-C2ImqlTr.js → PasswordChecker-DSLBp7Vl.js} +1 -1
  61. zenml/zen_server/dashboard/assets/{SetPassword-074iDZCm.js → SetPassword-Dq6iUfpW.js} +1 -1
  62. zenml/zen_server/dashboard/assets/{SuccessStep-DEeKB0Wq.js → SuccessStep-BHhPYxz9.js} +1 -1
  63. zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-4be5el9x.js → UpdatePasswordSchemas-4FyPPBY9.js} +1 -1
  64. zenml/zen_server/dashboard/assets/{aws-BaCucHs5.js → aws-t0gKCj_R.js} +1 -1
  65. zenml/zen_server/dashboard/assets/{check-circle-GxOo3117.js → check-circle-BVvhm5dy.js} +1 -1
  66. zenml/zen_server/dashboard/assets/{chevron-down-tsuIW52H.js → chevron-down-zcvCWmyP.js} +1 -1
  67. zenml/zen_server/dashboard/assets/{chevron-right-double-Dfr12EKG.js → chevron-right-double-CJ50E9Gr.js} +1 -1
  68. zenml/zen_server/dashboard/assets/{cloud-only-lInATL8-.js → cloud-only-DsILLhXk.js} +1 -1
  69. zenml/zen_server/dashboard/assets/{copy-B8yRmO5i.js → copy-BRhQz3j-.js} +1 -1
  70. zenml/zen_server/dashboard/assets/{database-BiV4iNgr.js → database-CRRnyFWh.js} +1 -1
  71. zenml/zen_server/dashboard/assets/{docker-EYFTGVBw.js → docker-BAonhm6G.js} +1 -1
  72. zenml/zen_server/dashboard/assets/{file-text-Bp-4kjON.js → file-text-CbVERUON.js} +1 -1
  73. zenml/zen_server/dashboard/assets/{help-hEyYkC3q.js → help-B8rqCvqn.js} +1 -1
  74. zenml/zen_server/dashboard/assets/index-BhYPVFKa.js +55 -0
  75. zenml/zen_server/dashboard/assets/index-CRZ5qzG3.css +1 -0
  76. zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +1 -0
  77. zenml/zen_server/dashboard/assets/{login-mutation-BfEeVmSl.js → login-mutation-CDARn8rx.js} +1 -1
  78. zenml/zen_server/dashboard/assets/{not-found-an_3Z-Ep.js → not-found-D1_I0ubu.js} +1 -1
  79. zenml/zen_server/dashboard/assets/{page-NlxFzoaz.js → page-7IP7WH5_.js} +1 -1
  80. zenml/zen_server/dashboard/assets/page-B5Y_HW80.js +1 -0
  81. zenml/zen_server/dashboard/assets/{page-Ba5l9-eg.js → page-BQT1Zxsp.js} +1 -1
  82. zenml/zen_server/dashboard/assets/page-BR7WTzLa.js +1 -0
  83. zenml/zen_server/dashboard/assets/page-BmuIfr11.js +1 -0
  84. zenml/zen_server/dashboard/assets/{page-C6Xn5o3F.js → page-Bwrw_wb_.js} +1 -1
  85. zenml/zen_server/dashboard/assets/{page-GXA0bsIT.js → page-ByiUk9rA.js} +1 -1
  86. zenml/zen_server/dashboard/assets/{page-68OLHx44.js → page-C9lMl0g8.js} +2 -2
  87. zenml/zen_server/dashboard/assets/{page-NTQrxRsu.js → page-CK0iF8U_.js} +1 -1
  88. zenml/zen_server/dashboard/assets/{page-Cea5XeRB.js → page-CQTaUp7q.js} +1 -1
  89. zenml/zen_server/dashboard/assets/{page-ZJ5Cy_-x.js → page-Ca8Zw2SO.js} +1 -1
  90. zenml/zen_server/dashboard/assets/{page-B90yVxNb.js → page-CaDkuI7b.js} +1 -1
  91. zenml/zen_server/dashboard/assets/{page-C1Jl09zF.js → page-DB_mi8or.js} +1 -1
  92. zenml/zen_server/dashboard/assets/page-DDY5j-6S.js +1 -0
  93. zenml/zen_server/dashboard/assets/page-DIz9_5Du.js +2 -0
  94. zenml/zen_server/dashboard/assets/page-DPrgvGj6.js +9 -0
  95. zenml/zen_server/dashboard/assets/{page-C0opS_t4.js → page-D_Vj_UH1.js} +1 -1
  96. zenml/zen_server/dashboard/assets/page-QPP3iIQH.js +1 -0
  97. zenml/zen_server/dashboard/assets/{page-Bjj9GHVF.js → page-bpP11sGS.js} +1 -1
  98. zenml/zen_server/dashboard/assets/page-xA0WcjLa.js +1 -0
  99. zenml/zen_server/dashboard/assets/{page-DVAcOIuw.js → page-zYQJvPVh.js} +1 -1
  100. zenml/zen_server/dashboard/assets/{play-circle-DsngbHkK.js → play-circle-DK5QMJyp.js} +1 -1
  101. zenml/zen_server/dashboard/assets/{terminal-Cb3ce-nr.js → terminal-B2ovgWuz.js} +1 -1
  102. zenml/zen_server/dashboard/assets/{update-server-settings-mutation-CdcOI8-c.js → update-server-settings-mutation-SaWcyAnk.js} +1 -1
  103. zenml/zen_server/dashboard/assets/{url-DLJUVIKc.js → url-ZKNs861m.js} +1 -1
  104. zenml/zen_server/dashboard/assets/zod-DrZvVLjd.js +1 -0
  105. zenml/zen_server/dashboard/index.html +8 -8
  106. zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
  107. zenml/zen_server/dashboard_legacy/index.html +1 -1
  108. zenml/zen_server/dashboard_legacy/{precache-manifest.05e51e85bd64770b2708d408a88d7028.js → precache-manifest.8e59f98d08e9c4c7cb3ef9f0bab7093f.js} +4 -4
  109. zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
  110. zenml/zen_server/dashboard_legacy/static/js/main.a238a4d2.chunk.js +2 -0
  111. zenml/zen_server/dashboard_legacy/static/js/main.a238a4d2.chunk.js.map +1 -0
  112. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  113. zenml/zen_server/deploy/helm/README.md +3 -3
  114. zenml/zen_server/deploy/helm/values.yaml +7 -7
  115. zenml/zen_server/jwt.py +11 -11
  116. zenml/zen_server/routers/auth_endpoints.py +17 -0
  117. zenml/zen_server/routers/steps_endpoints.py +11 -3
  118. zenml/zen_stores/migrations/versions/0.58.1_release.py +23 -0
  119. zenml/zen_stores/rest_zen_store.py +17 -1
  120. {zenml_nightly-0.58.0.dev20240529.dist-info → zenml_nightly-0.58.1.dev20240608.dist-info}/METADATA +4 -3
  121. {zenml_nightly-0.58.0.dev20240529.dist-info → zenml_nightly-0.58.1.dev20240608.dist-info}/RECORD +124 -123
  122. zenml/zen_server/dashboard/assets/@react-router-CCpyfPW-.js +0 -29
  123. zenml/zen_server/dashboard/assets/@reactflow-CF_wPv-n.js +0 -17
  124. zenml/zen_server/dashboard/assets/@reactflow-lOPj8ZwY.css +0 -1
  125. zenml/zen_server/dashboard/assets/@tanstack-GFKzItNf.js +0 -30
  126. zenml/zen_server/dashboard/assets/CodeSnippet-CBFcxTGW.js +0 -9
  127. zenml/zen_server/dashboard/assets/Commands-BQb0_PAa.js +0 -1
  128. zenml/zen_server/dashboard/assets/Infobox-DV6YqO5N.js +0 -1
  129. zenml/zen_server/dashboard/assets/index-D4zsM9tz.css +0 -1
  130. zenml/zen_server/dashboard/assets/index-DKgtNG83.js +0 -56
  131. zenml/zen_server/dashboard/assets/index.esm-DNxbrOmx.js +0 -1
  132. zenml/zen_server/dashboard/assets/page-0AGNIDYi.js +0 -1
  133. zenml/zen_server/dashboard/assets/page-6Gp_NCQL.js +0 -14
  134. zenml/zen_server/dashboard/assets/page-BiyORkbM.js +0 -1
  135. zenml/zen_server/dashboard/assets/page-BnrWbXYJ.js +0 -2
  136. zenml/zen_server/dashboard/assets/page-CUqLUGbU.js +0 -1
  137. zenml/zen_server/dashboard/assets/page-CWpGAjSi.js +0 -1
  138. zenml/zen_server/dashboard/assets/page-DFQa6C6e.js +0 -1
  139. zenml/zen_server/dashboard/assets/page-Dn87PjPv.js +0 -1
  140. zenml/zen_server/dashboard/assets/zod-DueGCdzx.js +0 -1
  141. zenml/zen_server/dashboard_legacy/static/js/main.41d438ec.chunk.js +0 -2
  142. zenml/zen_server/dashboard_legacy/static/js/main.41d438ec.chunk.js.map +0 -1
  143. {zenml_nightly-0.58.0.dev20240529.dist-info → zenml_nightly-0.58.1.dev20240608.dist-info}/LICENSE +0 -0
  144. {zenml_nightly-0.58.0.dev20240529.dist-info → zenml_nightly-0.58.1.dev20240608.dist-info}/WHEEL +0 -0
  145. {zenml_nightly-0.58.0.dev20240529.dist-info → zenml_nightly-0.58.1.dev20240608.dist-info}/entry_points.txt +0 -0
@@ -44,7 +44,9 @@ class KubernetesOrchestratorSettings(BaseSettings):
44
44
  step_pod_service_account_name: Name of the service account to use for the
45
45
  step pods. If not provided, the default service account will be used.
46
46
  privileged: If the container should be run in privileged mode.
47
- pod_settings: Pod settings to apply.
47
+ pod_settings: Pod settings to apply to pods executing the steps.
48
+ orchestrator_pod_settings: Pod settings to apply to the pod which is
49
+ launching the actual steps.
48
50
  """
49
51
 
50
52
  synchronous: bool = True
@@ -53,6 +55,7 @@ class KubernetesOrchestratorSettings(BaseSettings):
53
55
  step_pod_service_account_name: Optional[str] = None
54
56
  privileged: bool = False
55
57
  pod_settings: Optional[KubernetesPodSettings] = None
58
+ orchestrator_pod_settings: Optional[KubernetesPodSettings] = None
56
59
 
57
60
 
58
61
  class KubernetesOrchestratorConfig( # type: ignore[misc] # https://github.com/pydantic/pydantic/issues/4173
@@ -391,20 +391,6 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
391
391
  # Authorize pod to run Kubernetes commands inside the cluster.
392
392
  service_account_name = self._get_service_account_name(settings)
393
393
 
394
- if settings.pod_settings:
395
- # Remove all settings that specify on which pod to run for the
396
- # orchestrator pod. These settings should only be used
397
- # for the pods executing the actual steps.
398
- pod_settings = settings.pod_settings.copy(
399
- update={
400
- "resources": {},
401
- "node_selectors": {},
402
- "affinity": {},
403
- "tolerations": [],
404
- }
405
- )
406
- settings = settings.copy(update={"pod_settings": pod_settings})
407
-
408
394
  # Schedule as CRON job if CRON schedule is given.
409
395
  if deployment.schedule:
410
396
  if not deployment.schedule.cron_expression:
@@ -423,7 +409,8 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
423
409
  command=command,
424
410
  args=args,
425
411
  service_account_name=service_account_name,
426
- settings=settings,
412
+ privileged=False,
413
+ pod_settings=settings.orchestrator_pod_settings,
427
414
  env=environment,
428
415
  mount_local_stores=self.config.is_local,
429
416
  )
@@ -446,8 +433,9 @@ class KubernetesOrchestrator(ContainerizedOrchestrator):
446
433
  image_name=image,
447
434
  command=command,
448
435
  args=args,
436
+ privileged=False,
437
+ pod_settings=settings.orchestrator_pod_settings,
449
438
  service_account_name=service_account_name,
450
- settings=settings,
451
439
  env=environment,
452
440
  mount_local_stores=self.config.is_local,
453
441
  )
@@ -116,7 +116,8 @@ def main() -> None:
116
116
  command=step_command,
117
117
  args=step_args,
118
118
  env=env,
119
- settings=settings,
119
+ privileged=settings.privileged,
120
+ pod_settings=settings.pod_settings,
120
121
  service_account_name=settings.step_pod_service_account_name
121
122
  or settings.service_account_name,
122
123
  mount_local_stores=mount_local_stores,
@@ -25,9 +25,6 @@ from zenml.constants import ENV_ZENML_ENABLE_REPO_INIT_WARNINGS
25
25
  from zenml.integrations.airflow.orchestrators.dag_generator import (
26
26
  ENV_ZENML_LOCAL_STORES_PATH,
27
27
  )
28
- from zenml.integrations.kubernetes.flavors import (
29
- KubernetesOrchestratorSettings,
30
- )
31
28
  from zenml.integrations.kubernetes.pod_settings import KubernetesPodSettings
32
29
 
33
30
 
@@ -100,7 +97,8 @@ def build_pod_manifest(
100
97
  image_name: str,
101
98
  command: List[str],
102
99
  args: List[str],
103
- settings: KubernetesOrchestratorSettings,
100
+ privileged: bool,
101
+ pod_settings: Optional[KubernetesPodSettings] = None,
104
102
  service_account_name: Optional[str] = None,
105
103
  env: Optional[Dict[str, str]] = None,
106
104
  mount_local_stores: bool = False,
@@ -114,7 +112,8 @@ def build_pod_manifest(
114
112
  image_name: Name of the Docker image.
115
113
  command: Command to execute the entrypoint in the pod.
116
114
  args: Arguments provided to the entrypoint command.
117
- settings: `KubernetesOrchestratorSettings` object
115
+ privileged: Whether to run the container in privileged mode.
116
+ pod_settings: Optional settings for the pod.
118
117
  service_account_name: Optional name of a service account.
119
118
  Can be used to assign certain roles to a pod, e.g., to allow it to
120
119
  run Kubernetes commands from within the cluster.
@@ -128,9 +127,7 @@ def build_pod_manifest(
128
127
  env = env.copy() if env else {}
129
128
  env.setdefault(ENV_ZENML_ENABLE_REPO_INIT_WARNINGS, "False")
130
129
 
131
- security_context = k8s_client.V1SecurityContext(
132
- privileged=settings.privileged
133
- )
130
+ security_context = k8s_client.V1SecurityContext(privileged=privileged)
134
131
  container_spec = k8s_client.V1Container(
135
132
  name="main",
136
133
  image=image_name,
@@ -151,8 +148,8 @@ def build_pod_manifest(
151
148
  if service_account_name is not None:
152
149
  pod_spec.service_account_name = service_account_name
153
150
 
154
- if settings.pod_settings:
155
- add_pod_settings(pod_spec, settings.pod_settings)
151
+ if pod_settings:
152
+ add_pod_settings(pod_spec, pod_settings)
156
153
 
157
154
  pod_metadata = k8s_client.V1ObjectMeta(
158
155
  name=pod_name,
@@ -162,8 +159,8 @@ def build_pod_manifest(
162
159
  },
163
160
  )
164
161
 
165
- if settings.pod_settings and settings.pod_settings.annotations:
166
- pod_metadata.annotations = settings.pod_settings.annotations
162
+ if pod_settings and pod_settings.annotations:
163
+ pod_metadata.annotations = pod_settings.annotations
167
164
 
168
165
  pod_manifest = k8s_client.V1Pod(
169
166
  kind="Pod",
@@ -224,7 +221,8 @@ def build_cron_job_manifest(
224
221
  image_name: str,
225
222
  command: List[str],
226
223
  args: List[str],
227
- settings: KubernetesOrchestratorSettings,
224
+ privileged: bool,
225
+ pod_settings: Optional[KubernetesPodSettings] = None,
228
226
  service_account_name: Optional[str] = None,
229
227
  env: Optional[Dict[str, str]] = None,
230
228
  mount_local_stores: bool = False,
@@ -239,7 +237,8 @@ def build_cron_job_manifest(
239
237
  image_name: Name of the Docker image.
240
238
  command: Command to execute the entrypoint in the pod.
241
239
  args: Arguments provided to the entrypoint command.
242
- settings: `KubernetesOrchestratorSettings` object
240
+ privileged: Whether to run the container in privileged mode.
241
+ pod_settings: Optional settings for the pod.
243
242
  service_account_name: Optional name of a service account.
244
243
  Can be used to assign certain roles to a pod, e.g., to allow it to
245
244
  run Kubernetes commands from within the cluster.
@@ -257,7 +256,8 @@ def build_cron_job_manifest(
257
256
  image_name=image_name,
258
257
  command=command,
259
258
  args=args,
260
- settings=settings,
259
+ privileged=privileged,
260
+ pod_settings=pod_settings,
261
261
  service_account_name=service_account_name,
262
262
  env=env,
263
263
  mount_local_stores=mount_local_stores,
@@ -13,7 +13,6 @@
13
13
  # permissions and limitations under the License.
14
14
  """Amazon S3 artifact store flavor."""
15
15
 
16
- import json
17
16
  import re
18
17
  from typing import (
19
18
  TYPE_CHECKING,
@@ -23,7 +22,6 @@ from typing import (
23
22
  Optional,
24
23
  Set,
25
24
  Type,
26
- Union,
27
25
  )
28
26
 
29
27
  from pydantic import validator
@@ -72,42 +70,6 @@ class S3ArtifactStoreConfig(
72
70
  config_kwargs: Optional[Dict[str, Any]] = None
73
71
  s3_additional_kwargs: Optional[Dict[str, Any]] = None
74
72
 
75
- @validator(
76
- "client_kwargs", "config_kwargs", "s3_additional_kwargs", pre=True
77
- )
78
- def _convert_json_string(
79
- cls, value: Union[None, str, Dict[str, Any]]
80
- ) -> Optional[Dict[str, Any]]:
81
- """Converts potential JSON strings passed via the CLI to dictionaries.
82
-
83
- Args:
84
- value: The value to convert.
85
-
86
- Returns:
87
- The converted value.
88
-
89
- Raises:
90
- TypeError: If the value is not a `str`, `Dict` or `None`.
91
- ValueError: If the value is an invalid json string or a json string
92
- that does not decode into a dictionary.
93
- """
94
- if isinstance(value, str):
95
- try:
96
- dict_ = json.loads(value)
97
- except json.JSONDecodeError as e:
98
- raise ValueError(f"Invalid json string '{value}'") from e
99
-
100
- if not isinstance(dict_, Dict):
101
- raise ValueError(
102
- f"Json string '{value}' did not decode into a dictionary."
103
- )
104
-
105
- return dict_
106
- elif isinstance(value, Dict) or value is None:
107
- return value
108
- else:
109
- raise TypeError(f"{value} is not a json string or a dictionary.")
110
-
111
73
  @validator("client_kwargs")
112
74
  def _validate_client_kwargs(
113
75
  cls, value: Optional[Dict[str, Any]]
@@ -13,10 +13,7 @@
13
13
  # permissions and limitations under the License.
14
14
  """Spark step operator flavor."""
15
15
 
16
- import json
17
- from typing import TYPE_CHECKING, Any, Dict, Optional, Type, Union
18
-
19
- from pydantic import validator
16
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Type
20
17
 
21
18
  from zenml.config.base_settings import BaseSettings
22
19
  from zenml.step_operators.base_step_operator import (
@@ -45,40 +42,6 @@ class SparkStepOperatorSettings(BaseSettings):
45
42
  deploy_mode: str = "cluster"
46
43
  submit_kwargs: Optional[Dict[str, Any]] = None
47
44
 
48
- @validator("submit_kwargs", pre=True)
49
- def _convert_json_string(
50
- cls, value: Union[None, str, Dict[str, Any]]
51
- ) -> Optional[Dict[str, Any]]:
52
- """Converts potential JSON strings passed via the CLI to dictionaries.
53
-
54
- Args:
55
- value: The value to convert.
56
-
57
- Returns:
58
- The converted value.
59
-
60
- Raises:
61
- TypeError: If the value is not a `str`, `Dict` or `None`.
62
- ValueError: If the value is an invalid json string or a json string
63
- that does not decode into a dictionary.
64
- """
65
- if isinstance(value, str):
66
- try:
67
- dict_ = json.loads(value)
68
- except json.JSONDecodeError as e:
69
- raise ValueError(f"Invalid json string '{value}'") from e
70
-
71
- if not isinstance(dict_, Dict):
72
- raise ValueError(
73
- f"Json string '{value}' did not decode into a dictionary."
74
- )
75
-
76
- return dict_
77
- elif isinstance(value, Dict) or value is None:
78
- return value
79
- else:
80
- raise TypeError(f"{value} is not a json string or a dictionary.")
81
-
82
45
 
83
46
  class SparkStepOperatorConfig( # type: ignore[misc] # https://github.com/pydantic/pydantic/issues/4173
84
47
  BaseStepOperatorConfig, SparkStepOperatorSettings
@@ -65,7 +65,7 @@ class BaseMaterializerMeta(type):
65
65
  f"Invalid materializer class '{name}'. When creating a "
66
66
  f"custom materializer, make sure to specify at least one "
67
67
  f"type in its ASSOCIATED_TYPES class variable.",
68
- url="https://docs.zenml.io/user-guide/advanced-guide/artifact-management/handle-custom-data-types",
68
+ url="https://docs.zenml.io/how-to/handle-data-artifacts/handle-custom-data-types",
69
69
  )
70
70
 
71
71
  # Validate associated artifact type.
@@ -80,7 +80,7 @@ class BaseMaterializerMeta(type):
80
80
  f"custom materializer, make sure to specify a valid "
81
81
  f"artifact type in its ASSOCIATED_ARTIFACT_TYPE class "
82
82
  f"variable.",
83
- url="https://docs.zenml.io/user-guide/advanced-guide/artifact-management/handle-custom-data-types",
83
+ url="https://docs.zenml.io/how-to/handle-data-artifacts/handle-custom-data-types",
84
84
  )
85
85
 
86
86
  # Validate associated data types.
@@ -89,7 +89,7 @@ class BaseMaterializerMeta(type):
89
89
  raise MaterializerInterfaceError(
90
90
  f"Associated type {associated_type} for materializer "
91
91
  f"{name} is not a class.",
92
- url="https://docs.zenml.io/user-guide/advanced-guide/artifact-management/handle-custom-data-types",
92
+ url="https://docs.zenml.io/how-to/handle-data-artifacts/handle-custom-data-types",
93
93
  )
94
94
 
95
95
  # Register the materializer.
@@ -102,7 +102,7 @@ class CloudpickleMaterializer(BaseMaterializer):
102
102
  "the artifacts cannot be loaded when running with a different "
103
103
  "Python version. Please consider implementing a custom "
104
104
  f"materializer for type `{type(data)}` according to the "
105
- "instructions at https://docs.zenml.io/user-guide/advanced-guide/artifact-management/handle-custom-data-types"
105
+ "instructions at https://docs.zenml.io/how-to/handle-data-artifacts/handle-custom-data-types"
106
106
  )
107
107
 
108
108
  # save python version for validation on loading
@@ -51,7 +51,7 @@ class BaseOrchestratorConfig(StackComponentConfig):
51
51
  "The 'custom_docker_base_image_name' field has been "
52
52
  "deprecated. To use a custom base container image with your "
53
53
  "orchestrators, please use the DockerSettings in your "
54
- "pipeline (see https://docs.zenml.io/user-guide/advanced-guide/environment-management/containerize-your-pipeline)."
54
+ "pipeline (see https://docs.zenml.io/how-to/customize-docker-builds)."
55
55
  )
56
56
 
57
57
  return values
@@ -14,15 +14,13 @@
14
14
  """Implementation of the ZenML local Docker orchestrator."""
15
15
 
16
16
  import copy
17
- import json
18
17
  import os
19
18
  import sys
20
19
  import time
21
- from typing import TYPE_CHECKING, Any, Dict, Optional, Type, Union, cast
20
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Type, cast
22
21
  from uuid import uuid4
23
22
 
24
23
  from docker.errors import ContainerError
25
- from pydantic import validator
26
24
 
27
25
  from zenml.config.base_settings import BaseSettings
28
26
  from zenml.config.global_config import GlobalConfiguration
@@ -207,40 +205,6 @@ class LocalDockerOrchestratorSettings(BaseSettings):
207
205
 
208
206
  run_args: Dict[str, Any] = {}
209
207
 
210
- @validator("run_args", pre=True)
211
- def _convert_json_string(
212
- cls, value: Union[None, str, Dict[str, Any]]
213
- ) -> Optional[Dict[str, Any]]:
214
- """Converts potential JSON strings passed via the CLI to dictionaries.
215
-
216
- Args:
217
- value: The value to convert.
218
-
219
- Returns:
220
- The converted value.
221
-
222
- Raises:
223
- TypeError: If the value is not a `str`, `Dict` or `None`.
224
- ValueError: If the value is an invalid json string or a json string
225
- that does not decode into a dictionary.
226
- """
227
- if isinstance(value, str):
228
- try:
229
- dict_ = json.loads(value)
230
- except json.JSONDecodeError as e:
231
- raise ValueError(f"Invalid json string '{value}'") from e
232
-
233
- if not isinstance(dict_, Dict):
234
- raise ValueError(
235
- f"Json string '{value}' did not decode into a dictionary."
236
- )
237
-
238
- return dict_
239
- elif isinstance(value, Dict) or value is None:
240
- return value
241
- else:
242
- raise TypeError(f"{value} is not a json string or a dictionary.")
243
-
244
208
 
245
209
  class LocalDockerOrchestratorConfig( # type: ignore[misc] # https://github.com/pydantic/pydantic/issues/4173
246
210
  BaseOrchestratorConfig, LocalDockerOrchestratorSettings
@@ -348,7 +348,7 @@ class StepRunner:
348
348
  "is deprecated and will be removed in a future release. "
349
349
  f"Please adjust your '{step_name}' step to instead import "
350
350
  "the `StepContext` inside your step, as shown here: "
351
- "https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/fetch-metadata-within-steps"
351
+ "https://docs.zenml.io/how-to/track-metrics-metadata/fetch-metadata-within-steps"
352
352
  )
353
353
  function_params[arg] = get_step_context()
354
354
  elif arg in input_artifacts:
@@ -409,7 +409,7 @@ class StepRunner:
409
409
  "is deprecated and will be removed in a future release. "
410
410
  f"Please adjust your '{step_name}' hook to instead import "
411
411
  "the `StepContext` inside your hook, as shown here: "
412
- "https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/fetch-metadata-within-steps"
412
+ "https://docs.zenml.io/how-to/track-metrics-metadata/fetch-metadata-within-steps"
413
413
  )
414
414
  function_params[arg] = get_step_context()
415
415
 
zenml/stack/flavor.py CHANGED
@@ -206,7 +206,9 @@ class Flavor:
206
206
  name = self.name.replace("_", "-")
207
207
  docs_component_name = component_name or name
208
208
  base = f"https://docs.zenml.io/v/{__version__}"
209
- return f"{base}/user-guide/component-guide/{component_type}/{docs_component_name}"
209
+ return (
210
+ f"{base}/stack-components/{component_type}/{docs_component_name}"
211
+ )
210
212
 
211
213
  def generate_default_sdk_docs_url(self) -> str:
212
214
  """Generate SDK docs url for a flavor.
zenml/stack/stack.py CHANGED
@@ -801,7 +801,7 @@ class Stack:
801
801
  f"Additionally, we are also providing a variety of "
802
802
  f" deployment recipes for popular Kubernetes-based "
803
803
  f"integrations such as Kubeflow, Tekton, and Seldon etc."
804
- f"Check out https://docs.zenml.io/stacks-and-components/stack-deployment/deploy-a-stack-using-stack-recipes"
804
+ f"Check out https://docs.zenml.io/how-to/stack-deployment/deploy-a-stack-using-mlstacks"
805
805
  f"for more information."
806
806
  )
807
807
 
@@ -811,7 +811,7 @@ class Stack:
811
811
  "and step operators require a remote "
812
812
  "ZenML server. To run a pipeline with this stack you need to "
813
813
  "connect to a remote ZenML server first. Check out "
814
- "https://docs.zenml.io/user-guide/starter-guide/switch-to-production "
814
+ "https://docs.zenml.io/getting-started/deploying-zenml "
815
815
  "for more information on how to deploy ZenML."
816
816
  )
817
817
 
@@ -13,12 +13,16 @@
13
13
  # permissions and limitations under the License.
14
14
  """Implementation of the ZenML Stack Component class."""
15
15
 
16
+ import json
16
17
  from abc import ABC
18
+ from collections.abc import Mapping, Sequence
17
19
  from datetime import datetime
20
+ from inspect import isclass
18
21
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Type, Union
19
22
  from uuid import UUID
20
23
 
21
- from pydantic import BaseModel, Extra
24
+ from pydantic import BaseModel, Extra, root_validator
25
+ from pydantic.typing import get_origin
22
26
 
23
27
  from zenml.config.build_configuration import BuildConfiguration
24
28
  from zenml.config.step_configurations import Step
@@ -93,7 +97,7 @@ class StackComponentConfig(BaseModel, ABC):
93
97
  "in sensitive information as secrets. Check out the "
94
98
  "documentation on how to configure your stack "
95
99
  "components with secrets here: "
96
- "https://docs.zenml.io/user-guide/advanced-guide/secret-management"
100
+ "https://docs.zenml.io/getting-started/deploying-zenml/manage-the-deployed-services/secret-management"
97
101
  )
98
102
  continue
99
103
 
@@ -242,6 +246,42 @@ class StackComponentConfig(BaseModel, ABC):
242
246
  # (see https://github.com/python/mypy/issues/13319).
243
247
  __getattribute__ = __custom_getattribute__
244
248
 
249
+ @root_validator(pre=True)
250
+ def _convert_json_strings(cls, values: Dict[str, Any]) -> Any:
251
+ """Converts potential JSON strings.
252
+
253
+ Args:
254
+ values: The model values.
255
+
256
+ Returns:
257
+ The potentially converted values.
258
+
259
+ Raises:
260
+ ValueError: If any of the values is an invalid JSON string.
261
+ """
262
+ for key, field in cls.__fields__.items():
263
+ value = values.get(key, None)
264
+
265
+ if isinstance(value, str):
266
+ if get_origin(field.outer_type_) in {
267
+ dict,
268
+ list,
269
+ Mapping,
270
+ Sequence,
271
+ }:
272
+ try:
273
+ values[key] = json.loads(value)
274
+ except json.JSONDecodeError as e:
275
+ raise ValueError(
276
+ f"Invalid json string '{value}'"
277
+ ) from e
278
+ elif isclass(field.type_) and issubclass(
279
+ field.type_, BaseModel
280
+ ):
281
+ values[key] = field.type_.parse_raw(value).dict()
282
+
283
+ return values
284
+
245
285
  class Config:
246
286
  """Pydantic configuration class."""
247
287
 
zenml/steps/base_step.py CHANGED
@@ -1233,7 +1233,7 @@ To avoid this consider setting step parameters only in one place (config or code
1233
1233
  logger.warning(
1234
1234
  "The `BaseParameters` class to define step parameters is "
1235
1235
  "deprecated. Check out our docs "
1236
- "https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/configure-steps-pipelines "
1236
+ "https://docs.zenml.io/how-to/use-configuration-files/how-to-use-config "
1237
1237
  "for information on how to parameterize your steps. As a quick "
1238
1238
  "fix to get rid of this warning, make sure your parameter class "
1239
1239
  "inherits from `pydantic.BaseModel` instead of the "
@@ -115,7 +115,7 @@ class StepArtifact:
115
115
  "you're trying to unpack the return value of your step but the "
116
116
  "step only returns a single artifact. For more information on how "
117
117
  "to add type annotations to your step to indicate multiple "
118
- "artifacts visit https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/managing-steps#type-annotations."
118
+ "artifacts visit https://docs.zenml.io/how-to/build-pipelines/step-output-typing-and-annotation#type-annotations."
119
119
  )
120
120
 
121
121
 
@@ -214,7 +214,7 @@ class EntrypointFunctionDefinition(NamedTuple):
214
214
  f"'{key}' is not JSON serializable and can not be passed as "
215
215
  "a parameter. This input can either be provided by the "
216
216
  "output of another step or as an external artifact: "
217
- "https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/configure-steps-pipelines#pass-any-kind-of-data-to-your-steps"
217
+ "https://docs.zenml.io/user-guide/starter-guide/manage-artifacts#managing-artifacts-not-produced-by-zenml-pipelines"
218
218
  )
219
219
 
220
220
  try:
zenml/steps/utils.py CHANGED
@@ -110,7 +110,7 @@ def parse_return_type_annotations(
110
110
  "Using the `Output` class to define the outputs of your steps is "
111
111
  "deprecated. You should instead use the standard Python way of "
112
112
  "type annotating your functions. Check out our documentation "
113
- "https://docs.zenml.io/user-guide/advanced-guide/pipelining-features/configure-steps-pipelines#step-output-names "
113
+ "https://docs.zenml.io/how-to/build-pipelines/step-output-typing-and-annotation "
114
114
  "for more information on how to assign custom names to your step "
115
115
  "outputs."
116
116
  )
@@ -42,7 +42,7 @@ def is_cloud_server(server_info: ServerModel) -> bool:
42
42
  """
43
43
  return (
44
44
  "organization_id" in server_info.metadata
45
- and "cloud.zenml.io" in server_info.server_url
45
+ and "cloud.zenml.io" in server_info.dashboard_url
46
46
  )
47
47
 
48
48
 
@@ -20,6 +20,7 @@ import sys
20
20
  from collections import defaultdict
21
21
  from typing import (
22
22
  TYPE_CHECKING,
23
+ Any,
23
24
  DefaultDict,
24
25
  Dict,
25
26
  List,
@@ -65,6 +66,15 @@ DEFAULT_DOCKER_PARENT_IMAGE = (
65
66
  f"py{sys.version_info.major}.{sys.version_info.minor}"
66
67
  )
67
68
 
69
+ PIP_DEFAULT_ARGS = {
70
+ "no-cache-dir": None,
71
+ "default-timeout": 60,
72
+ }
73
+ UV_DEFAULT_ARGS = {
74
+ "no-cache-dir": None,
75
+ "system": None,
76
+ }
77
+
68
78
 
69
79
  class PipelineDockerImageBuilder:
70
80
  """Builds Docker images to run a ZenML pipeline."""
@@ -636,22 +646,32 @@ class PipelineDockerImageBuilder:
636
646
  docker_settings.python_package_installer
637
647
  == PythonPackageInstaller.PIP
638
648
  ):
639
- install_command = "pip install --default-timeout=60"
649
+ install_command = "pip install"
650
+ default_installer_args: Dict[str, Any] = PIP_DEFAULT_ARGS
640
651
  elif (
641
652
  docker_settings.python_package_installer
642
653
  == PythonPackageInstaller.UV
643
654
  ):
644
655
  lines.append("RUN pip install uv")
645
- install_command = "uv pip install --system"
656
+ install_command = "uv pip install"
657
+ default_installer_args = UV_DEFAULT_ARGS
646
658
  else:
647
659
  raise ValueError("Unsupported python package installer.")
648
660
 
661
+ installer_args = {
662
+ **default_installer_args,
663
+ **docker_settings.python_package_installer_args,
664
+ }
665
+ installer_args_string = " ".join(
666
+ f"--{key}" if value is None else f"--{key}={value}"
667
+ for key, value in installer_args.items()
668
+ )
649
669
  for file, _, options in requirements_files:
650
670
  lines.append(f"COPY {file} .")
651
671
  option_string = " ".join(options)
652
672
 
653
673
  lines.append(
654
- f"RUN {install_command} --no-cache-dir "
674
+ f"RUN {install_command} {installer_args_string}"
655
675
  f"{option_string} -r {file}"
656
676
  )
657
677