zenml-nightly 0.73.0.dev20250128__py3-none-any.whl → 0.73.0.dev20250130__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.
zenml/VERSION CHANGED
@@ -1 +1 @@
1
- 0.73.0.dev20250128
1
+ 0.73.0.dev20250130
zenml/cli/utils.py CHANGED
@@ -76,6 +76,7 @@ from zenml.models import (
76
76
  from zenml.models.v2.base.filter import FilterGenerator
77
77
  from zenml.services import BaseService, ServiceState
78
78
  from zenml.stack import StackComponent
79
+ from zenml.stack.flavor import Flavor
79
80
  from zenml.stack.stack_component import StackComponentConfig
80
81
  from zenml.utils import secret_utils
81
82
  from zenml.utils.time_utils import expires_in
@@ -2151,10 +2152,11 @@ def _scrub_secret(config: StackComponentConfig) -> Dict[str, Any]:
2151
2152
  config_dict = {}
2152
2153
  config_fields = config.__class__.model_fields
2153
2154
  for key, value in config_fields.items():
2154
- if secret_utils.is_secret_field(value):
2155
- config_dict[key] = "********"
2156
- else:
2157
- config_dict[key] = getattr(config, key)
2155
+ if getattr(config, key):
2156
+ if secret_utils.is_secret_field(value):
2157
+ config_dict[key] = "********"
2158
+ else:
2159
+ config_dict[key] = getattr(config, key)
2158
2160
  return config_dict
2159
2161
 
2160
2162
 
@@ -2164,8 +2166,6 @@ def print_debug_stack() -> None:
2164
2166
 
2165
2167
  client = Client()
2166
2168
  stack = client.get_stack()
2167
- active_stack = client.active_stack
2168
- components = _get_stack_components(active_stack)
2169
2169
 
2170
2170
  declare("\nCURRENT STACK\n", bold=True)
2171
2171
  console.print(f"Name: {stack.name}")
@@ -2176,7 +2176,8 @@ def print_debug_stack() -> None:
2176
2176
  f"Workspace: {stack.workspace.name} / {str(stack.workspace.id)}"
2177
2177
  )
2178
2178
 
2179
- for component in components:
2179
+ for component_type, components in stack.components.items():
2180
+ component = components[0]
2180
2181
  component_response = client.get_stack_component(
2181
2182
  name_id_or_prefix=component.id, component_type=component.type
2182
2183
  )
@@ -2186,8 +2187,12 @@ def print_debug_stack() -> None:
2186
2187
  console.print(f"Name: {component.name}")
2187
2188
  console.print(f"ID: {str(component.id)}")
2188
2189
  console.print(f"Type: {component.type.value}")
2189
- console.print(f"Flavor: {component.flavor}")
2190
- console.print(f"Configuration: {_scrub_secret(component.config)}")
2190
+ console.print(f"Flavor: {component.flavor_name}")
2191
+
2192
+ flavor = Flavor.from_model(component.flavor)
2193
+ config = flavor.config_class(**component.configuration)
2194
+
2195
+ console.print(f"Configuration: {_scrub_secret(config)}")
2191
2196
  if (
2192
2197
  component_response.user
2193
2198
  and component_response.user.name
zenml/client.py CHANGED
@@ -2453,7 +2453,9 @@ class Client(metaclass=ClientMetaClass):
2453
2453
  def trigger_pipeline(
2454
2454
  self,
2455
2455
  pipeline_name_or_id: Union[str, UUID, None] = None,
2456
- run_configuration: Optional[PipelineRunConfiguration] = None,
2456
+ run_configuration: Union[
2457
+ PipelineRunConfiguration, Dict[str, Any], None
2458
+ ] = None,
2457
2459
  config_path: Optional[str] = None,
2458
2460
  template_id: Optional[UUID] = None,
2459
2461
  stack_name_or_id: Union[str, UUID, None] = None,
@@ -2524,6 +2526,11 @@ class Client(metaclass=ClientMetaClass):
2524
2526
  if config_path:
2525
2527
  run_configuration = PipelineRunConfiguration.from_yaml(config_path)
2526
2528
 
2529
+ if isinstance(run_configuration, Dict):
2530
+ run_configuration = PipelineRunConfiguration.model_validate(
2531
+ run_configuration
2532
+ )
2533
+
2527
2534
  if run_configuration:
2528
2535
  validate_run_config_is_runnable_from_server(run_configuration)
2529
2536
 
zenml/constants.py CHANGED
@@ -138,6 +138,7 @@ ENV_ZENML_USER_ID = "ZENML_USER_ID"
138
138
  ENV_ZENML_CONFIG_PATH = "ZENML_CONFIG_PATH"
139
139
  ENV_ZENML_DEBUG = "ZENML_DEBUG"
140
140
  ENV_ZENML_LOGGING_VERBOSITY = "ZENML_LOGGING_VERBOSITY"
141
+ ENV_ZENML_LOGGING_FORMAT = "ZENML_LOGGING_FORMAT"
141
142
  ENV_ZENML_REPOSITORY_PATH = "ZENML_REPOSITORY_PATH"
142
143
  ENV_ZENML_PREVENT_PIPELINE_EXECUTION = "ZENML_PREVENT_PIPELINE_EXECUTION"
143
144
  ENV_ZENML_ENABLE_RICH_TRACEBACK = "ZENML_ENABLE_RICH_TRACEBACK"
@@ -154,6 +155,7 @@ ENV_ZENML_SECRETS_STORE_PREFIX = "ZENML_SECRETS_STORE_"
154
155
  ENV_ZENML_BACKUP_SECRETS_STORE_PREFIX = "ZENML_BACKUP_SECRETS_STORE_"
155
156
  ENV_ZENML_SKIP_PIPELINE_REGISTRATION = "ZENML_SKIP_PIPELINE_REGISTRATION"
156
157
  ENV_AUTO_OPEN_DASHBOARD = "AUTO_OPEN_DASHBOARD"
158
+ ENV_ZENML_AUTO_OPEN_DASHBOARD = "ZENML_AUTO_OPEN_DASHBOARD"
157
159
  ENV_ZENML_DISABLE_DATABASE_MIGRATION = "DISABLE_DATABASE_MIGRATION"
158
160
  ENV_ZENML_LOCAL_STORES_PATH = "ZENML_LOCAL_STORES_PATH"
159
161
  ENV_ZENML_CONTAINER = "ZENML_CONTAINER"
@@ -22,6 +22,8 @@ from uuid import UUID
22
22
 
23
23
  from zenml.client import Client
24
24
  from zenml.code_repositories import BaseCodeRepository
25
+ from zenml.enums import StackComponentType
26
+ from zenml.exceptions import CustomFlavorImportError
25
27
  from zenml.logger import get_logger
26
28
  from zenml.utils import (
27
29
  code_repository_utils,
@@ -31,6 +33,7 @@ from zenml.utils import (
31
33
  )
32
34
 
33
35
  if TYPE_CHECKING:
36
+ from zenml.artifact_stores import BaseArtifactStore
34
37
  from zenml.models import CodeReferenceResponse, PipelineDeploymentResponse
35
38
 
36
39
  logger = get_logger(__name__)
@@ -204,6 +207,8 @@ class BaseEntrypointConfiguration(ABC):
204
207
  decision instead.
205
208
 
206
209
  Raises:
210
+ CustomFlavorImportError: If the artifact store flavor can't be
211
+ imported.
207
212
  RuntimeError: If the current environment requires code download
208
213
  but the deployment does not have a reference to any code.
209
214
  """
@@ -215,7 +220,27 @@ class BaseEntrypointConfiguration(ABC):
215
220
  return
216
221
 
217
222
  if code_path := deployment.code_path:
218
- code_utils.download_code_from_artifact_store(code_path=code_path)
223
+ # Load the artifact store not from the active stack but separately.
224
+ # This is required in case the stack has custom flavor components
225
+ # (other than the artifact store) for which the flavor
226
+ # implementations will only be available once the download finishes.
227
+ try:
228
+ artifact_store = self._load_active_artifact_store()
229
+ except CustomFlavorImportError as e:
230
+ raise CustomFlavorImportError(
231
+ "Failed to import custom artifact store flavor. The "
232
+ "artifact store flavor is needed to download your code, "
233
+ "but it looks like it might be part of the files "
234
+ "that we're trying to download. If this is the case, you "
235
+ "should disable downloading code from the artifact store "
236
+ "using `DockerSettings(allow_download_from_artifact_store=False)` "
237
+ "or make sure the artifact flavor files are included in "
238
+ "Docker image by using a custom parent image or installing "
239
+ "them as part of a pip dependency."
240
+ ) from e
241
+ code_utils.download_code_from_artifact_store(
242
+ code_path=code_path, artifact_store=artifact_store
243
+ )
219
244
  elif code_reference := deployment.code_reference:
220
245
  # TODO: This might fail if the code repository had unpushed changes
221
246
  # at the time the pipeline run was started.
@@ -300,6 +325,22 @@ class BaseEntrypointConfiguration(ABC):
300
325
 
301
326
  return False
302
327
 
328
+ def _load_active_artifact_store(self) -> "BaseArtifactStore":
329
+ """Load the active artifact store.
330
+
331
+ Returns:
332
+ The active artifact store.
333
+ """
334
+ from zenml.artifact_stores import BaseArtifactStore
335
+
336
+ artifact_store_model = Client().active_stack_model.components[
337
+ StackComponentType.ARTIFACT_STORE
338
+ ][0]
339
+ artifact_store = BaseArtifactStore.from_model(artifact_store_model)
340
+ assert isinstance(artifact_store, BaseArtifactStore)
341
+
342
+ return artifact_store
343
+
303
344
  @abstractmethod
304
345
  def run(self) -> None:
305
346
  """Runs the entrypoint configuration."""
zenml/exceptions.py CHANGED
@@ -314,3 +314,7 @@ class SecretsStoreNotConfiguredError(NotImplementedError):
314
314
 
315
315
  class BackupSecretsStoreNotConfiguredError(NotImplementedError):
316
316
  """Raised when a backup secrets store is not configured."""
317
+
318
+
319
+ class CustomFlavorImportError(ImportError):
320
+ """Raised when failing to import a custom flavor."""
@@ -16,7 +16,7 @@
16
16
  from google.cloud.aiplatform_v1.types.job_state import JobState
17
17
 
18
18
  VERTEX_ENDPOINT_SUFFIX = "-aiplatform.googleapis.com"
19
- POLLING_INTERVAL_IN_SECONDS = 30
19
+ POLLING_INTERVAL_IN_SECONDS = 10
20
20
  CONNECTION_ERROR_RETRY_LIMIT = 5
21
21
  _VERTEX_JOB_STATE_SUCCEEDED = JobState.JOB_STATE_SUCCEEDED
22
22
  _VERTEX_JOB_STATE_FAILED = JobState.JOB_STATE_FAILED
@@ -51,7 +51,8 @@ class VertexStepOperatorSettings(BaseSettings):
51
51
  https://cloud.google.com/vertex-ai/docs/training/configure-compute#boot_disk_options
52
52
  boot_disk_type: Type of the boot disk. (Default: pd-ssd)
53
53
  https://cloud.google.com/vertex-ai/docs/training/configure-compute#boot_disk_options
54
-
54
+ persistent_resource_id: The ID of the persistent resource to use for the job.
55
+ https://cloud.google.com/vertex-ai/docs/training/persistent-resource-overview
55
56
  """
56
57
 
57
58
  accelerator_type: Optional[str] = None
@@ -59,6 +60,7 @@ class VertexStepOperatorSettings(BaseSettings):
59
60
  machine_type: str = "n1-standard-4"
60
61
  boot_disk_size_gb: int = 100
61
62
  boot_disk_type: str = "pd-ssd"
63
+ persistent_resource_id: Optional[str] = None
62
64
 
63
65
 
64
66
  class VertexStepOperatorConfig(
@@ -258,6 +258,7 @@ class VertexStepOperator(BaseStepOperator, GoogleCredentialsMixin):
258
258
  if self.config.reserved_ip_ranges
259
259
  else []
260
260
  ),
261
+ "persistent_resource_id": settings.persistent_resource_id,
261
262
  },
262
263
  "labels": job_labels,
263
264
  "encryption_spec": {
@@ -13,17 +13,18 @@
13
13
  # permissions and limitations under the License.
14
14
  """Implementation of the Hugging Face Deployment service."""
15
15
 
16
- from typing import Any, Generator, Optional, Tuple
16
+ from typing import Any, Dict, Generator, Optional, Tuple
17
17
 
18
18
  from huggingface_hub import (
19
19
  InferenceClient,
20
20
  InferenceEndpoint,
21
21
  InferenceEndpointError,
22
22
  InferenceEndpointStatus,
23
+ InferenceEndpointType,
23
24
  create_inference_endpoint,
24
25
  get_inference_endpoint,
25
26
  )
26
- from huggingface_hub.utils import HfHubHTTPError
27
+ from huggingface_hub.errors import HfHubHTTPError
27
28
  from pydantic import Field
28
29
 
29
30
  from zenml.client import Client
@@ -138,30 +139,67 @@ class HuggingFaceDeploymentService(BaseDeploymentService):
138
139
  """
139
140
  return self.hf_endpoint.client
140
141
 
142
+ def _validate_endpoint_configuration(self) -> Dict[str, str]:
143
+ """Validates the configuration to provision a Huggingface service.
144
+
145
+ Raises:
146
+ ValueError: if there is a missing value in the configuration
147
+
148
+ Returns:
149
+ The validated configuration values.
150
+ """
151
+ configuration = {}
152
+ missing_keys = []
153
+
154
+ for k, v in {
155
+ "repository": self.config.repository,
156
+ "framework": self.config.framework,
157
+ "accelerator": self.config.accelerator,
158
+ "instance_size": self.config.instance_size,
159
+ "instance_type": self.config.instance_type,
160
+ "region": self.config.region,
161
+ "vendor": self.config.vendor,
162
+ "endpoint_type": self.config.endpoint_type,
163
+ }.items():
164
+ if v is None:
165
+ missing_keys.append(k)
166
+ else:
167
+ configuration[k] = v
168
+
169
+ if missing_keys:
170
+ raise ValueError(
171
+ f"Missing values in the Huggingface Service "
172
+ f"configuration: {', '.join(missing_keys)}"
173
+ )
174
+
175
+ return configuration
176
+
141
177
  def provision(self) -> None:
142
178
  """Provision or update remote Hugging Face deployment instance.
143
179
 
144
180
  Raises:
145
- Exception: If any unexpected error while creating inference endpoint.
181
+ Exception: If any unexpected error while creating inference
182
+ endpoint.
146
183
  """
147
184
  try:
148
- # Attempt to create and wait for the inference endpoint
185
+ validated_config = self._validate_endpoint_configuration()
186
+
149
187
  hf_endpoint = create_inference_endpoint(
150
188
  name=self._generate_an_endpoint_name(),
151
- repository=self.config.repository,
152
- framework=self.config.framework,
153
- accelerator=self.config.accelerator,
154
- instance_size=self.config.instance_size,
155
- instance_type=self.config.instance_type,
156
- region=self.config.region,
157
- vendor=self.config.vendor,
189
+ repository=validated_config["repository"],
190
+ framework=validated_config["framework"],
191
+ accelerator=validated_config["accelerator"],
192
+ instance_size=validated_config["instance_size"],
193
+ instance_type=validated_config["instance_type"],
194
+ region=validated_config["region"],
195
+ vendor=validated_config["vendor"],
158
196
  account_id=self.config.account_id,
159
197
  min_replica=self.config.min_replica,
160
198
  max_replica=self.config.max_replica,
161
199
  revision=self.config.revision,
162
200
  task=self.config.task,
163
201
  custom_image=self.config.custom_image,
164
- type=self.config.endpoint_type,
202
+ type=InferenceEndpointType(validated_config["endpoint_type"]),
165
203
  token=self.get_token(),
166
204
  namespace=self.config.namespace,
167
205
  ).wait(timeout=POLLING_TIMEOUT)
@@ -172,21 +210,25 @@ class HuggingFaceDeploymentService(BaseDeploymentService):
172
210
  )
173
211
  # Catch-all for any other unexpected errors
174
212
  raise Exception(
175
- f"An unexpected error occurred while provisioning the Hugging Face inference endpoint: {e}"
213
+ "An unexpected error occurred while provisioning the "
214
+ f"Hugging Face inference endpoint: {e}"
176
215
  )
177
216
 
178
217
  # Check if the endpoint URL is available after provisioning
179
218
  if hf_endpoint.url:
180
219
  logger.info(
181
- f"Hugging Face inference endpoint successfully deployed and available. Endpoint URL: {hf_endpoint.url}"
220
+ "Hugging Face inference endpoint successfully deployed "
221
+ f"and available. Endpoint URL: {hf_endpoint.url}"
182
222
  )
183
223
  else:
184
224
  logger.error(
185
- "Failed to start Hugging Face inference endpoint service: No URL available, please check the Hugging Face console for more details."
225
+ "Failed to start Hugging Face inference endpoint "
226
+ "service: No URL available, please check the Hugging "
227
+ "Face console for more details."
186
228
  )
187
229
 
188
230
  def check_status(self) -> Tuple[ServiceState, str]:
189
- """Check the the current operational state of the Hugging Face deployment.
231
+ """Check the current operational state of the Hugging Face deployment.
190
232
 
191
233
  Returns:
192
234
  The operational state of the Hugging Face deployment and a message
@@ -196,26 +238,29 @@ class HuggingFaceDeploymentService(BaseDeploymentService):
196
238
  try:
197
239
  status = self.hf_endpoint.status
198
240
  if status == InferenceEndpointStatus.RUNNING:
199
- return (ServiceState.ACTIVE, "")
241
+ return ServiceState.ACTIVE, ""
200
242
 
201
243
  elif status == InferenceEndpointStatus.SCALED_TO_ZERO:
202
244
  return (
203
245
  ServiceState.SCALED_TO_ZERO,
204
- "Hugging Face Inference Endpoint is scaled to zero, but still running. It will be started on demand.",
246
+ "Hugging Face Inference Endpoint is scaled to zero, but "
247
+ "still running. It will be started on demand.",
205
248
  )
206
249
 
207
250
  elif status == InferenceEndpointStatus.FAILED:
208
251
  return (
209
252
  ServiceState.ERROR,
210
- "Hugging Face Inference Endpoint deployment is inactive or not found",
253
+ "Hugging Face Inference Endpoint deployment is inactive "
254
+ "or not found",
211
255
  )
212
256
  elif status == InferenceEndpointStatus.PENDING:
213
- return (ServiceState.PENDING_STARTUP, "")
214
- return (ServiceState.PENDING_STARTUP, "")
257
+ return ServiceState.PENDING_STARTUP, ""
258
+ return ServiceState.PENDING_STARTUP, ""
215
259
  except (InferenceEndpointError, HfHubHTTPError):
216
260
  return (
217
261
  ServiceState.INACTIVE,
218
- "Hugging Face Inference Endpoint deployment is inactive or not found",
262
+ "Hugging Face Inference Endpoint deployment is inactive or "
263
+ "not found",
219
264
  )
220
265
 
221
266
  def deprovision(self, force: bool = False) -> None:
@@ -253,15 +298,13 @@ class HuggingFaceDeploymentService(BaseDeploymentService):
253
298
  )
254
299
  if self.prediction_url is not None:
255
300
  if self.hf_endpoint.task == "text-generation":
256
- result = self.inference_client.task_generation(
301
+ return self.inference_client.text_generation(
257
302
  data, max_new_tokens=max_new_tokens
258
303
  )
259
- else:
260
- # TODO: Add support for all different supported tasks
261
- raise NotImplementedError(
262
- "Tasks other than text-generation is not implemented."
263
- )
264
- return result
304
+ # TODO: Add support for all different supported tasks
305
+ raise NotImplementedError(
306
+ "Tasks other than text-generation is not implemented."
307
+ )
265
308
 
266
309
  def get_logs(
267
310
  self, follow: bool = False, tail: Optional[int] = None
@@ -152,9 +152,14 @@ class VLLMDeploymentService(LocalDaemonService, BaseDeploymentService):
152
152
  parser: argparse.ArgumentParser = make_arg_parser(
153
153
  FlexibleArgumentParser()
154
154
  )
155
- args: argparse.Namespace = parser.parse_args()
155
+ # pass in empty list to get default args
156
+ # otherwise it will try to get the args from sys.argv
157
+ # and if there's a --config in there, it will want to use
158
+ # that file for vLLM configuration, which is not what we want
159
+ args: argparse.Namespace = parser.parse_args(args=[])
156
160
  # Override port with the available port
157
161
  self.config.port = self.endpoint.status.port or self.config.port
162
+
158
163
  # Update the arguments in place
159
164
  args.__dict__.update(self.config.model_dump())
160
165
  uvloop.run(run_server(args=args))
zenml/logger.py CHANGED
@@ -24,6 +24,7 @@ from rich.traceback import install as rich_tb_install
24
24
  from zenml.constants import (
25
25
  ENABLE_RICH_TRACEBACK,
26
26
  ENV_ZENML_LOGGING_COLORS_DISABLED,
27
+ ENV_ZENML_LOGGING_FORMAT,
27
28
  ENV_ZENML_SUPPRESS_LOGS,
28
29
  ZENML_LOGGING_VERBOSITY,
29
30
  handle_bool_env_var,
@@ -144,6 +145,18 @@ def set_root_verbosity() -> None:
144
145
  get_logger(__name__).debug("Logging NOTSET")
145
146
 
146
147
 
148
+ def get_formatter() -> logging.Formatter:
149
+ """Get a configured logging formatter.
150
+
151
+ Returns:
152
+ The formatter.
153
+ """
154
+ if log_format := os.environ.get(ENV_ZENML_LOGGING_FORMAT, None):
155
+ return logging.Formatter(fmt=log_format)
156
+ else:
157
+ return CustomFormatter()
158
+
159
+
147
160
  def get_console_handler() -> Any:
148
161
  """Get console handler for logging.
149
162
 
@@ -151,7 +164,7 @@ def get_console_handler() -> Any:
151
164
  A console handler.
152
165
  """
153
166
  console_handler = logging.StreamHandler(sys.stdout)
154
- console_handler.setFormatter(CustomFormatter())
167
+ console_handler.setFormatter(get_formatter())
155
168
  return console_handler
156
169
 
157
170
 
@@ -179,7 +192,7 @@ def init_logging() -> None:
179
192
  set_root_verbosity()
180
193
 
181
194
  console_handler = logging.StreamHandler(sys.stdout)
182
- console_handler.setFormatter(CustomFormatter())
195
+ console_handler.setFormatter(get_formatter())
183
196
  logging.root.addHandler(console_handler)
184
197
 
185
198
  # Enable logs if environment variable SUPPRESS_ZENML_LOGS is not set to True
@@ -241,8 +241,9 @@ class UserScopedFilter(BaseFilter):
241
241
  if sort_by == "user":
242
242
  column = UserSchema.name
243
243
 
244
- query = query.join(
245
- UserSchema, getattr(table, "user_id") == UserSchema.id
244
+ query = query.outerjoin(
245
+ UserSchema,
246
+ getattr(table, "user_id") == UserSchema.id,
246
247
  )
247
248
 
248
249
  query = query.add_columns(UserSchema.name)
@@ -950,31 +950,31 @@ class PipelineRunFilter(WorkspaceScopedTaggableFilter):
950
950
  sort_by, operand = self.sorting_params
951
951
 
952
952
  if sort_by == "pipeline":
953
- query = query.join(
953
+ query = query.outerjoin(
954
954
  PipelineSchema,
955
955
  PipelineRunSchema.pipeline_id == PipelineSchema.id,
956
956
  )
957
957
  column = PipelineSchema.name
958
958
  elif sort_by == "stack":
959
- query = query.join(
959
+ query = query.outerjoin(
960
960
  PipelineDeploymentSchema,
961
961
  PipelineRunSchema.deployment_id == PipelineDeploymentSchema.id,
962
- ).join(
962
+ ).outerjoin(
963
963
  StackSchema,
964
964
  PipelineDeploymentSchema.stack_id == StackSchema.id,
965
965
  )
966
966
  column = StackSchema.name
967
967
  elif sort_by == "model":
968
- query = query.join(
968
+ query = query.outerjoin(
969
969
  ModelVersionSchema,
970
970
  PipelineRunSchema.model_version_id == ModelVersionSchema.id,
971
- ).join(
971
+ ).outerjoin(
972
972
  ModelSchema,
973
973
  ModelVersionSchema.model_id == ModelSchema.id,
974
974
  )
975
975
  column = ModelSchema.name
976
976
  elif sort_by == "model_version":
977
- query = query.join(
977
+ query = query.outerjoin(
978
978
  ModelVersionSchema,
979
979
  PipelineRunSchema.model_version_id == ModelVersionSchema.id,
980
980
  )
zenml/stack/flavor.py CHANGED
@@ -13,11 +13,13 @@
13
13
  # permissions and limitations under the License.
14
14
  """Base ZenML Flavor implementation."""
15
15
 
16
+ import os
16
17
  from abc import abstractmethod
17
18
  from typing import Any, Dict, Optional, Type, cast
18
19
 
19
20
  from zenml.client import Client
20
21
  from zenml.enums import StackComponentType
22
+ from zenml.exceptions import CustomFlavorImportError
21
23
  from zenml.models import (
22
24
  FlavorRequest,
23
25
  FlavorResponse,
@@ -126,10 +128,34 @@ class Flavor:
126
128
  Args:
127
129
  flavor_model: The model to load from.
128
130
 
131
+ Raises:
132
+ CustomFlavorImportError: If the custom flavor can't be imported.
133
+ ImportError: If the flavor can't be imported.
134
+
129
135
  Returns:
130
136
  The loaded flavor.
131
137
  """
132
- flavor = source_utils.load(flavor_model.source)()
138
+ try:
139
+ flavor = source_utils.load(flavor_model.source)()
140
+ except (ModuleNotFoundError, ImportError, NotImplementedError) as err:
141
+ if flavor_model.is_custom:
142
+ flavor_module, _ = flavor_model.source.rsplit(".")
143
+ expected_file_path = os.path.join(
144
+ source_utils.get_source_root(),
145
+ flavor_module.replace(".", os.path.sep),
146
+ )
147
+ raise CustomFlavorImportError(
148
+ f"Couldn't import custom flavor {flavor_model.name}: "
149
+ f"{err}. Make sure the custom flavor class "
150
+ f"`{flavor_model.source}` is importable. If it is part of "
151
+ "a library, make sure it is installed. If "
152
+ "it is a local code file, make sure it exists at "
153
+ f"`{expected_file_path}.py`."
154
+ )
155
+ else:
156
+ raise ImportError(
157
+ f"Couldn't import flavor {flavor_model.name}: {err}"
158
+ )
133
159
  return cast(Flavor, flavor)
134
160
 
135
161
  def to_model(
@@ -402,16 +402,10 @@ class StackComponent:
402
402
  Raises:
403
403
  ImportError: If the flavor can't be imported.
404
404
  """
405
- flavor_model = component_model.flavor
406
-
407
- try:
408
- from zenml.stack import Flavor
405
+ from zenml.stack import Flavor
409
406
 
410
- flavor = Flavor.from_model(flavor_model)
411
- except (ModuleNotFoundError, ImportError, NotImplementedError) as err:
412
- raise ImportError(
413
- f"Couldn't import flavor {flavor_model.name}: {err}"
414
- )
407
+ flavor_model = component_model.flavor
408
+ flavor = Flavor.from_model(flavor_model)
415
409
 
416
410
  configuration = flavor.config_class(**component_model.configuration)
417
411
 
zenml/utils/code_utils.py CHANGED
@@ -249,16 +249,7 @@ def download_and_extract_code(code_path: str, extract_dir: str) -> None:
249
249
  Args:
250
250
  code_path: Path where the code is uploaded.
251
251
  extract_dir: Directory where to code should be extracted to.
252
-
253
- Raises:
254
- RuntimeError: If the code is stored in an artifact store which is
255
- not active.
256
252
  """
257
- artifact_store = Client().active_stack.artifact_store
258
-
259
- if not code_path.startswith(artifact_store.path):
260
- raise RuntimeError("Code stored in different artifact store.")
261
-
262
253
  download_path = os.path.basename(code_path)
263
254
  fileio.copy(code_path, download_path)
264
255
 
@@ -266,17 +257,30 @@ def download_and_extract_code(code_path: str, extract_dir: str) -> None:
266
257
  os.remove(download_path)
267
258
 
268
259
 
269
- def download_code_from_artifact_store(code_path: str) -> None:
260
+ def download_code_from_artifact_store(
261
+ code_path: str, artifact_store: "BaseArtifactStore"
262
+ ) -> None:
270
263
  """Download code from the artifact store.
271
264
 
272
265
  Args:
273
266
  code_path: Path where the code is stored.
267
+ artifact_store: The artifact store to use for the download.
268
+
269
+ Raises:
270
+ RuntimeError: If the code is stored in an artifact store which is
271
+ not active.
274
272
  """
275
273
  logger.info("Downloading code from artifact store path `%s`.", code_path)
276
274
 
277
- # Do not remove this line, we need to instantiate the artifact store to
278
- # register the filesystem needed for the file download
279
- _ = Client().active_stack.artifact_store
275
+ if not code_path.startswith(artifact_store.path):
276
+ raise RuntimeError(
277
+ "The code is not stored in the artifact store "
278
+ f"{artifact_store.name} that was passed to download it."
279
+ )
280
+
281
+ # Make sure we register the artifact store filesystem here so the
282
+ # fileio.copy call will pick up the right credentials
283
+ artifact_store._register()
280
284
 
281
285
  extract_dir = os.path.abspath("code")
282
286
  os.makedirs(extract_dir)
@@ -13,6 +13,7 @@
13
13
  # permissions and limitations under the License.
14
14
  """Utility class to help with interacting with the dashboard."""
15
15
 
16
+ import os
16
17
  from typing import Optional
17
18
  from uuid import UUID
18
19
 
@@ -156,9 +157,27 @@ def show_dashboard(url: str) -> None:
156
157
  display(IFrame(src=url, width="100%", height=720))
157
158
 
158
159
  elif environment in (EnvironmentType.NATIVE, EnvironmentType.WSL):
159
- if constants.handle_bool_env_var(
160
+ open_dashboard = True
161
+
162
+ if constants.ENV_AUTO_OPEN_DASHBOARD in os.environ:
163
+ logger.warning(
164
+ "The `%s` environment variable is deprecated, use the `%s` "
165
+ "environment variable instead.",
166
+ constants.ENV_AUTO_OPEN_DASHBOARD,
167
+ constants.ENV_ZENML_AUTO_OPEN_DASHBOARD,
168
+ )
169
+
170
+ if not constants.handle_bool_env_var(
160
171
  constants.ENV_AUTO_OPEN_DASHBOARD, default=True
161
172
  ):
173
+ open_dashboard = False
174
+
175
+ if not constants.handle_bool_env_var(
176
+ constants.ENV_ZENML_AUTO_OPEN_DASHBOARD, default=True
177
+ ):
178
+ open_dashboard = False
179
+
180
+ if open_dashboard:
162
181
  try:
163
182
  import webbrowser
164
183
 
@@ -169,14 +188,16 @@ def show_dashboard(url: str) -> None:
169
188
  logger.info(
170
189
  "Automatically opening the dashboard in your "
171
190
  "browser. To disable this, set the env variable "
172
- "AUTO_OPEN_DASHBOARD=false."
191
+ "`%s=false`.",
192
+ constants.ENV_ZENML_AUTO_OPEN_DASHBOARD,
173
193
  )
174
194
  except Exception as e:
175
195
  logger.error(e)
176
196
  else:
177
197
  logger.info(
178
198
  "To open the dashboard in a browser automatically, "
179
- "set the env variable AUTO_OPEN_DASHBOARD=true."
199
+ "set the env variable `%s=true`.",
200
+ constants.ENV_ZENML_AUTO_OPEN_DASHBOARD,
180
201
  )
181
202
 
182
203
  else:
@@ -587,7 +587,7 @@ class PipelineDockerImageBuilder:
587
587
  f"ENV {ENV_ZENML_LOGGING_COLORS_DISABLED}={str(handle_bool_env_var(ENV_ZENML_LOGGING_COLORS_DISABLED, False))}"
588
588
  )
589
589
  for key, value in docker_settings.environment.items():
590
- lines.append(f"ENV {key.upper()}={value}")
590
+ lines.append(f"ENV {key.upper()}='{value}'")
591
591
 
592
592
  if apt_packages:
593
593
  apt_packages = " ".join(f"'{p}'" for p in apt_packages)
@@ -365,17 +365,16 @@ class RestZenStoreConfiguration(StoreConfiguration):
365
365
 
366
366
  if os.path.isfile(verify_ssl):
367
367
  with open(verify_ssl, "r") as f:
368
- verify_ssl = f.read()
368
+ cert_content = f.read()
369
369
 
370
370
  fileio.makedirs(str(secret_folder))
371
371
  file_path = Path(secret_folder, "ca_bundle.pem")
372
372
  with os.fdopen(
373
373
  os.open(file_path, flags=os.O_RDWR | os.O_CREAT, mode=0o600), "w"
374
374
  ) as f:
375
- f.write(verify_ssl)
376
- verify_ssl = str(file_path)
375
+ f.write(cert_content)
377
376
 
378
- return verify_ssl
377
+ return str(file_path)
379
378
 
380
379
  @classmethod
381
380
  def supports_url_scheme(cls, url: str) -> bool:
@@ -389,15 +388,6 @@ class RestZenStoreConfiguration(StoreConfiguration):
389
388
  """
390
389
  return urlparse(url).scheme in ("http", "https")
391
390
 
392
- def expand_certificates(self) -> None:
393
- """Expands the certificates in the verify_ssl field."""
394
- # Load the certificate values back into the configuration
395
- if isinstance(self.verify_ssl, str) and os.path.isfile(
396
- self.verify_ssl
397
- ):
398
- with open(self.verify_ssl, "r") as f:
399
- self.verify_ssl = f.read()
400
-
401
391
  @model_validator(mode="before")
402
392
  @classmethod
403
393
  @before_validator_handler
@@ -37,6 +37,7 @@ from zenml.exceptions import (
37
37
  IllegalOperationError,
38
38
  )
39
39
  from zenml.logger import get_logger
40
+ from zenml.utils.secret_utils import PlainSerializedSecretStr
40
41
  from zenml.zen_stores.schemas import (
41
42
  SecretSchema,
42
43
  )
@@ -62,7 +63,7 @@ class SqlSecretsStoreConfiguration(SecretsStoreConfiguration):
62
63
  """
63
64
 
64
65
  type: SecretsStoreType = SecretsStoreType.SQL
65
- encryption_key: Optional[str] = None
66
+ encryption_key: Optional[PlainSerializedSecretStr] = None
66
67
  model_config = ConfigDict(
67
68
  # Don't validate attributes when assigning them. This is necessary
68
69
  # because the certificate attributes can be expanded to the contents
@@ -159,7 +160,9 @@ class SqlSecretsStore(BaseSecretsStore):
159
160
  # Initialize the encryption engine
160
161
  if self.config.encryption_key:
161
162
  self._encryption_engine = AesGcmEngine()
162
- self._encryption_engine._update_key(self.config.encryption_key)
163
+ self._encryption_engine._update_key(
164
+ self.config.encryption_key.get_secret_value()
165
+ )
163
166
 
164
167
  # Nothing else to do here, the SQL ZenML store back-end is already
165
168
  # initialized
@@ -304,6 +304,7 @@ from zenml.utils.networking_utils import (
304
304
  replace_localhost_with_internal_hostname,
305
305
  )
306
306
  from zenml.utils.pydantic_utils import before_validator_handler
307
+ from zenml.utils.secret_utils import PlainSerializedSecretStr
307
308
  from zenml.utils.string_utils import (
308
309
  format_name_template,
309
310
  random_str,
@@ -460,11 +461,11 @@ class SqlZenStoreConfiguration(StoreConfiguration):
460
461
 
461
462
  driver: Optional[SQLDatabaseDriver] = None
462
463
  database: Optional[str] = None
463
- username: Optional[str] = None
464
- password: Optional[str] = None
465
- ssl_ca: Optional[str] = None
466
- ssl_cert: Optional[str] = None
467
- ssl_key: Optional[str] = None
464
+ username: Optional[PlainSerializedSecretStr] = None
465
+ password: Optional[PlainSerializedSecretStr] = None
466
+ ssl_ca: Optional[PlainSerializedSecretStr] = None
467
+ ssl_cert: Optional[PlainSerializedSecretStr] = None
468
+ ssl_key: Optional[PlainSerializedSecretStr] = None
468
469
  ssl_verify_server_cert: bool = False
469
470
  pool_size: int = 20
470
471
  max_overflow: int = 20
@@ -611,10 +612,10 @@ class SqlZenStoreConfiguration(StoreConfiguration):
611
612
  self.database = sql_url.database
612
613
  elif sql_url.drivername == SQLDatabaseDriver.MYSQL:
613
614
  if sql_url.username:
614
- self.username = sql_url.username
615
+ self.username = PlainSerializedSecretStr(sql_url.username)
615
616
  sql_url = sql_url._replace(username=None)
616
617
  if sql_url.password:
617
- self.password = sql_url.password
618
+ self.password = PlainSerializedSecretStr(sql_url.password)
618
619
  sql_url = sql_url._replace(password=None)
619
620
  if sql_url.database:
620
621
  self.database = sql_url.database
@@ -642,13 +643,13 @@ class SqlZenStoreConfiguration(StoreConfiguration):
642
643
  for k, v in sql_url.query.items():
643
644
  if k == "ssl_ca":
644
645
  if r := _get_query_result(v):
645
- self.ssl_ca = r
646
+ self.ssl_ca = PlainSerializedSecretStr(r)
646
647
  elif k == "ssl_cert":
647
648
  if r := _get_query_result(v):
648
- self.ssl_cert = r
649
+ self.ssl_cert = PlainSerializedSecretStr(r)
649
650
  elif k == "ssl_key":
650
651
  if r := _get_query_result(v):
651
- self.ssl_key = r
652
+ self.ssl_key = PlainSerializedSecretStr(r)
652
653
  elif k == "ssl_verify_server_cert":
653
654
  if r := _get_query_result(v):
654
655
  if is_true_string_value(r):
@@ -688,7 +689,7 @@ class SqlZenStoreConfiguration(StoreConfiguration):
688
689
  )
689
690
  for key in ["ssl_key", "ssl_ca", "ssl_cert"]:
690
691
  content = getattr(self, key)
691
- if content and not os.path.isfile(content):
692
+ if content and not os.path.isfile(content.get_secret_value()):
692
693
  fileio.makedirs(str(secret_folder))
693
694
  file_path = Path(secret_folder, f"{key}.pem")
694
695
  with os.fdopen(
@@ -697,7 +698,7 @@ class SqlZenStoreConfiguration(StoreConfiguration):
697
698
  ),
698
699
  "w",
699
700
  ) as f:
700
- f.write(content)
701
+ f.write(content.get_secret_value())
701
702
  setattr(self, key, str(file_path))
702
703
 
703
704
  self.url = str(sql_url)
@@ -732,7 +733,7 @@ class SqlZenStoreConfiguration(StoreConfiguration):
732
733
  # Load the certificate values back into the configuration
733
734
  for key in ["ssl_key", "ssl_ca", "ssl_cert"]:
734
735
  file_path = getattr(self, key, None)
735
- if file_path and os.path.isfile(file_path):
736
+ if file_path and os.path.isfile(file_path.get_secret_value()):
736
737
  with open(file_path, "r") as f:
737
738
  setattr(self, key, f.read())
738
739
 
@@ -780,8 +781,8 @@ class SqlZenStoreConfiguration(StoreConfiguration):
780
781
 
781
782
  sql_url = sql_url._replace(
782
783
  drivername="mysql+pymysql",
783
- username=self.username,
784
- password=self.password,
784
+ username=self.username.get_secret_value(),
785
+ password=self.password.get_secret_value(),
785
786
  database=database,
786
787
  )
787
788
 
@@ -792,11 +793,17 @@ class SqlZenStoreConfiguration(StoreConfiguration):
792
793
  ssl_setting = getattr(self, key)
793
794
  if not ssl_setting:
794
795
  continue
795
- if not os.path.isfile(ssl_setting):
796
+ if not os.path.isfile(ssl_setting.get_secret_value()):
796
797
  logger.warning(
797
798
  f"Database SSL setting `{key}` is not a file. "
798
799
  )
799
- sqlalchemy_ssl_args[key.removeprefix("ssl_")] = ssl_setting
800
+ sqlalchemy_ssl_args[key.lstrip("ssl_")] = (
801
+ ssl_setting.get_secret_value()
802
+ )
803
+ sqlalchemy_ssl_args[key.removeprefix("ssl_")] = (
804
+ ssl_setting.get_secret_value()
805
+ )
806
+
800
807
  if len(sqlalchemy_ssl_args) > 0:
801
808
  sqlalchemy_ssl_args["check_hostname"] = (
802
809
  self.ssl_verify_server_cert
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: zenml-nightly
3
- Version: 0.73.0.dev20250128
3
+ Version: 0.73.0.dev20250130
4
4
  Summary: ZenML: Write production-ready ML code.
5
5
  License: Apache-2.0
6
6
  Keywords: machine learning,production,pipeline,mlops,devops
@@ -1,5 +1,5 @@
1
1
  zenml/README.md,sha256=827dekbOWAs1BpW7VF1a4d7EbwPbjwccX-2zdXBENZo,1777
2
- zenml/VERSION,sha256=idxxoPzqv46tqwm3PHoXsGFsEa0kogFk5FNLMlg5-3Y,19
2
+ zenml/VERSION,sha256=wW7R7I2rStFIfLzfJIdNqUBozH4gk7VR6MkRm4Ntduk,19
3
3
  zenml/__init__.py,sha256=SkMObQA41ajqdZqGErN00S1Vf3KAxpLvbZ-OBy5uYoo,2130
4
4
  zenml/actions/__init__.py,sha256=mrt6wPo73iKRxK754_NqsGyJ3buW7RnVeIGXr1xEw8Y,681
5
5
  zenml/actions/base_action.py,sha256=UcaHev6BTuLDwuswnyaPjdA8AgUqB5xPZ-lRtuvf2FU,25553
@@ -52,10 +52,10 @@ zenml/cli/stack_components.py,sha256=7RXVCJTX6sU-CiyDeu4kGYPJZ7QRQjDTptsvl__sI_A
52
52
  zenml/cli/tag.py,sha256=Co-AL1eNZMf_AsqlcnJpoZ_k7UKa0l5X_g_TLpJdGes,4884
53
53
  zenml/cli/text_utils.py,sha256=bY1GIjoULt1cW2FyrPlMoAXNS2R7cSOjDFEZQqrpVQ8,3553
54
54
  zenml/cli/user_management.py,sha256=fTuRworQahst_j78qPYTtgciUeUOxwo7efiyPwmj2tI,13075
55
- zenml/cli/utils.py,sha256=aCSQFjfaLtBt4OYzYDwO2Rmdmn-b5AVBqpBGvv7OT7E,86420
55
+ zenml/cli/utils.py,sha256=kqTFuEyXgx0eP_7mtWwmDwF3JvDSQ7dnOMhlNYSSJfM,86594
56
56
  zenml/cli/version.py,sha256=nm1iSU_1V6-MUwpMKeXcwFhLYGUMLswvQL67cEuCpxA,3635
57
57
  zenml/cli/workspace.py,sha256=bp02aXou574ToWPD8OAIB_cg3mvpE011H8aMKegT-nU,2970
58
- zenml/client.py,sha256=f0ySssFW_m7G5cj9UKEeA0Tm-e8GwfjIvLaVuixHnKM,283418
58
+ zenml/client.py,sha256=Aj3-Ofz9t0MltZarqdgb4fSFqhrl6SWC5VjEoHkcCdU,283629
59
59
  zenml/client_lazy_loader.py,sha256=MOBgS1ITYqGvPUnWQ6edn9s8Hr_72YfWbwEIfHKUr9g,7104
60
60
  zenml/code_repositories/__init__.py,sha256=W5bDfzAG8OXIKZSV1L-VHuzMcSCYa9qzTdPb3jqfyYw,920
61
61
  zenml/code_repositories/base_code_repository.py,sha256=_DbxIBxvJlN0PFhST0vlTIQ26Q6V3Nar0kYdeGaJrk8,4386
@@ -85,7 +85,7 @@ zenml/config/step_run_info.py,sha256=KiVRSTtKmZ1GbvseDTap2imr7XwMHD3jSFVpyLNEK1I
85
85
  zenml/config/store_config.py,sha256=Cla5p5dTB6nNlo8_OZDs9hod5hspi64vxwtZj882XgU,3559
86
86
  zenml/config/strict_base_model.py,sha256=iHnO9qOmLUP_eiy9IjRr3JjIs1l1I_CsRQ76EyAneYU,860
87
87
  zenml/console.py,sha256=hj_KerPQKwnyKACj0ehSqUQX0mGVCJBKE1QvCt6ik3A,1160
88
- zenml/constants.py,sha256=kCdTTDV5r48dUSD1AVCPH1DL7GqUjhFSErh4Zdp7LCE,15639
88
+ zenml/constants.py,sha256=d6RrpS0nni9bAHa2BR6R8bzXiRe9ELKCYVZcKUAE9tE,15749
89
89
  zenml/container_registries/__init__.py,sha256=ZSPbBIOnzhg88kQSpYgKe_POLuru14m629665-kAVAA,2200
90
90
  zenml/container_registries/azure_container_registry.py,sha256=t1sfDa94Vzbyqtb1iPFNutJ2EXV5_p9CUNITasoiQ70,2667
91
91
  zenml/container_registries/base_container_registry.py,sha256=6c2e32wuqxYHJXm5OV2LY1MtX9yopB7WZtes9fmTAz0,7625
@@ -96,7 +96,7 @@ zenml/container_registries/github_container_registry.py,sha256=rbcGkFfPDk-Il0T9F
96
96
  zenml/data_validators/__init__.py,sha256=9Fa0jiUSQ_JsLMHYjqDayWQl4m_uuai9tQjIP60OTk8,886
97
97
  zenml/data_validators/base_data_validator.py,sha256=reGUJ6NEFfd_wocrcYBSU5QHCSBOll-pP_suTP_bfv0,9839
98
98
  zenml/entrypoints/__init__.py,sha256=2CMemOrHIJauxAss6k7dKFtsCFqgYR-JbAx4REoCaE8,946
99
- zenml/entrypoints/base_entrypoint_configuration.py,sha256=-JCuetzQGOPo5R6VmM2q2JVcLaEimrGPikTkXFXuiOI,10468
99
+ zenml/entrypoints/base_entrypoint_configuration.py,sha256=5GY0W-29pabMmtb8WlnEKtg3H-ywFEpXzpud3hC12_o,12516
100
100
  zenml/entrypoints/entrypoint.py,sha256=XNgXBCMKoidmP0_AYgMpqo-neG8Y8jG0rj43ofTDZ9E,2033
101
101
  zenml/entrypoints/pipeline_entrypoint_configuration.py,sha256=To-vTP29qAE36ndJDF1fRw9wL2Nk2bsBuO-ayAwvSmo,1646
102
102
  zenml/entrypoints/step_entrypoint_configuration.py,sha256=fETr5E7eH8QEWYqgaarIrLQzrPrdLEr194xhd3H5yU4,7206
@@ -110,7 +110,7 @@ zenml/event_sources/base_event.py,sha256=irrpiYi4fDYewzaXtb6_gPsqyFlYYLSap2BTGQz
110
110
  zenml/event_sources/base_event_source.py,sha256=04ramQhcPhGD9Mo9BcJZR-b9fJb8a4wzvlPVMAb9Dyk,25893
111
111
  zenml/event_sources/webhooks/__init__.py,sha256=VsHzSn1oKFaUs495ZqsKCfXiYxtaeGsnSGuvuqbGXCg,658
112
112
  zenml/event_sources/webhooks/base_webhook_event_source.py,sha256=2zADrL3cNpD-akZRdemUePUnTl8pPMPVX6eFQgWeUSo,7371
113
- zenml/exceptions.py,sha256=lPJ3_uJYwK33hIC6uebDHcGVX-NU2L51Q5ulMChYqv0,9687
113
+ zenml/exceptions.py,sha256=PcWF8BWbOgET5YUIzGMviYgHw7htspL98XovWCGS72M,9790
114
114
  zenml/experiment_trackers/__init__.py,sha256=b5XlKoRtMR1WBQVEiItolkpsa0iJ1IqxTmmRatr4YDw,1119
115
115
  zenml/experiment_trackers/base_experiment_tracker.py,sha256=K92w7c0r45qLPIsA3YmwPflaIl_WTK8-_Hh_1MQiLkE,2218
116
116
  zenml/feature_stores/__init__.py,sha256=tSW7YnDa3NDnlkX3yA_CTdX7ocWB9gsfF-7X9sc6i8Y,1415
@@ -256,7 +256,7 @@ zenml/integrations/feast/flavors/feast_feature_store_flavor.py,sha256=E0k2iwgNti
256
256
  zenml/integrations/gcp/__init__.py,sha256=H8iCKBFOOF4WFuZFqMc4ihgrFz-EOxfkstImNYo2dmE,2943
257
257
  zenml/integrations/gcp/artifact_stores/__init__.py,sha256=zYQkZBI4-COGX-E0NS7G-hLT88wbQBnYY6Oh1gruSRs,798
258
258
  zenml/integrations/gcp/artifact_stores/gcp_artifact_store.py,sha256=XfSIJ4HtsZvaUrUtzXvUp7QHr3WbgVDNsz7_q1h-DCo,10988
259
- zenml/integrations/gcp/constants.py,sha256=VdxUxJGi88QvHKpm48dCwcPTdWHC-lIZAoSdnc_CoDo,1334
259
+ zenml/integrations/gcp/constants.py,sha256=ZBQS_ZEjerUrJq-hH3UusgZAvB45FLgxNv11TSt3qhw,1334
260
260
  zenml/integrations/gcp/experiment_trackers/__init__.py,sha256=TBBlZZaeJS-wza6mU54GDlRBdi3b5DcxDxVStQxds0o,775
261
261
  zenml/integrations/gcp/experiment_trackers/vertex_experiment_tracker.py,sha256=7vhCibjKZgPbw85ja_VVM1bH-P_M5F60xGnsXzNkCls,7181
262
262
  zenml/integrations/gcp/flavors/__init__.py,sha256=GcB8EvYjXM_VSku16jnDSNyJYMgKc2ZiM_odyKEc1uc,1654
@@ -264,7 +264,7 @@ zenml/integrations/gcp/flavors/gcp_artifact_store_flavor.py,sha256=Ts2jvR3IgGH8Y
264
264
  zenml/integrations/gcp/flavors/gcp_image_builder_flavor.py,sha256=K6sE9D-okbdlctNwNeDYEfhWmMXXW-S92x342dnhjqY,4451
265
265
  zenml/integrations/gcp/flavors/vertex_experiment_tracker_flavor.py,sha256=icexIPoqyJ_tsO6M5-Vncd1TAUaKTGbdUG0cDOYC6Kc,6834
266
266
  zenml/integrations/gcp/flavors/vertex_orchestrator_flavor.py,sha256=m01jsJbyX9i29l4VmCNKRo6skwyLi_RQgTJM5oKWMMQ,9907
267
- zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py,sha256=MrfcSQIyW0a3R3H2JyLdCb4nkx7wgNc73PR2SnuJcvo,6429
267
+ zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py,sha256=VHg2coeKoBJjSYkiVSTtbfKRg9qW9o8_QZ_xXskfzI4,6653
268
268
  zenml/integrations/gcp/google_credentials_mixin.py,sha256=bPy3JYCCcyuTmPiVFqbY81YJ5g1yRdzHLlBlokvbeqg,4026
269
269
  zenml/integrations/gcp/image_builders/__init__.py,sha256=2IvTL6U2YpUoxGQXeXew-6WFoL5hHIxkqr4DaA5Ez9w,786
270
270
  zenml/integrations/gcp/image_builders/gcp_image_builder.py,sha256=dNpMJa1TITUOHSn5nj1gWTFwVNmvWz321A_JoTMOqCM,9114
@@ -273,7 +273,7 @@ zenml/integrations/gcp/orchestrators/vertex_orchestrator.py,sha256=7O-Wh-LTGKOWp
273
273
  zenml/integrations/gcp/service_connectors/__init__.py,sha256=fdydawaor8KAtMYvRZieiTuA1i5QATxXXgI-yV1lsn8,788
274
274
  zenml/integrations/gcp/service_connectors/gcp_service_connector.py,sha256=-QmTN9RbbuxIJjWrzx6eZoCqMGXHeJZ_w_2tBHd-FoQ,94807
275
275
  zenml/integrations/gcp/step_operators/__init__.py,sha256=iPkob2LtPIQ-OHszhbNz_ojhoovL6SprmTx37It4EJ8,808
276
- zenml/integrations/gcp/step_operators/vertex_step_operator.py,sha256=qPQOSacCFUcXCl0MkuzVkxpewU8NAPjiGQsjBF1N0ro,13492
276
+ zenml/integrations/gcp/step_operators/vertex_step_operator.py,sha256=X8CCniyAo7NHiy3Mv_YSKQ4Hw3UYMXob6B3uWKsCJ-0,13567
277
277
  zenml/integrations/github/__init__.py,sha256=A8Yd--BbAG3HEfbWYOIEy_kzyLs2tBiawiLMosXd1Do,1467
278
278
  zenml/integrations/github/code_repositories/__init__.py,sha256=ub_hSE2ks2mZB1aeHRjQYz7QIRQIgOw2s080IIqJaGs,817
279
279
  zenml/integrations/github/code_repositories/github_code_repository.py,sha256=7s4NjOn_bItAbwcxQQQfo9IlW8vowleUQMiBjjn6iJo,7041
@@ -308,7 +308,7 @@ zenml/integrations/huggingface/materializers/huggingface_tokenizer_materializer.
308
308
  zenml/integrations/huggingface/model_deployers/__init__.py,sha256=58O81P3mCg9LO3iaU7jMqBqZb0o5zSXS0r7nb2ogN1Q,840
309
309
  zenml/integrations/huggingface/model_deployers/huggingface_model_deployer.py,sha256=2pfKewps4sI7dLBTyARaK8e-TRpsJX9pTdJqJe7XRwo,9095
310
310
  zenml/integrations/huggingface/services/__init__.py,sha256=QkGAmOdUBQLKfMpaG-u_rXjBVtQRx0ip2fii10IM3P0,815
311
- zenml/integrations/huggingface/services/huggingface_deployment.py,sha256=FIJoaGqHAZhxKgR0T1UwaVvudKVSYMFQes2pzXzrzd8,10550
311
+ zenml/integrations/huggingface/services/huggingface_deployment.py,sha256=TcqealbqKBiCpbKhw79syr3wA1svM16OdWBQF9Zknn0,11917
312
312
  zenml/integrations/huggingface/steps/__init__.py,sha256=tjsmnE9lJcXsE46YGPNWJICHXDUWn34m7jE-os-CFLo,879
313
313
  zenml/integrations/huggingface/steps/accelerate_runner.py,sha256=0fazQcqopAVRCInNePsIEy2Vn4EePioAetWXhewXpFA,6387
314
314
  zenml/integrations/huggingface/steps/huggingface_deployer.py,sha256=Wk1wzYwy-kpA-IJAHzukUpIGRxrhZTuyXNYVriXBqCI,4103
@@ -547,7 +547,7 @@ zenml/integrations/vllm/flavors/vllm_model_deployer_flavor.py,sha256=_3P0-qyjdsV
547
547
  zenml/integrations/vllm/model_deployers/__init__.py,sha256=Z38oWIfkArNsxCm3rQkTdYK4dbtx2BpTUw1gw_kl6Do,803
548
548
  zenml/integrations/vllm/model_deployers/vllm_model_deployer.py,sha256=OYPNSkB-I5r4eQ_7kr4F7GDwNj6efcsio8WRteQ5cYI,9665
549
549
  zenml/integrations/vllm/services/__init__.py,sha256=Id28GEfHECI0RnGAGGNioD9eZ6aJxdNebe112VgC59g,788
550
- zenml/integrations/vllm/services/vllm_deployment.py,sha256=mp42O5_DaTIoJzerPMVuukEPT3XQkrzVQcSJdEto-wI,6800
550
+ zenml/integrations/vllm/services/vllm_deployment.py,sha256=UkSMVk3usu4kUEqbs6vUjdy25tcoZCWT8zkJvRXiao4,7071
551
551
  zenml/integrations/wandb/__init__.py,sha256=LBlnX4chpaB3atIsxkF0RSz2AJs9gHQWRptkgkqF6lw,1711
552
552
  zenml/integrations/wandb/experiment_trackers/__init__.py,sha256=8nFyyvh-PTF5d9ZfjS7xFSWTWSpreRB1azePv-Ex2sc,771
553
553
  zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py,sha256=xNkF-3-WwpC8OV38T5evV35t6rH5o3O6uBlX4cimsKs,5092
@@ -574,7 +574,7 @@ zenml/io/fileio.py,sha256=6Z4ywg-1X49Xemf22sm7r9Z603kqUSpQAkw46UDBTyk,8758
574
574
  zenml/io/filesystem.py,sha256=3z13GIQpEVmatGXzrTZj8nIsaYb_N3bHwmgH_FKrMiA,6580
575
575
  zenml/io/filesystem_registry.py,sha256=stujDg4a5k983WMwp3rj4Z4puiUco4REyVoIoMIpIII,4541
576
576
  zenml/io/local_filesystem.py,sha256=xQTZPT5cpooptUV8KiifxZojS6pWCv1-6UUxitUYb_E,7386
577
- zenml/logger.py,sha256=me8hascHygTlfqR0w3MpvuSLGfjTLdCftK0aWf79uww,6647
577
+ zenml/logger.py,sha256=LMV2sMFQ-6JK9xEn6kEt1C9vAoQ0lwuHVM5XHIeKubE,6966
578
578
  zenml/logging/__init__.py,sha256=lnqbOa31wAHwPP5f8vZazOrUwnP2QviLiIVwxoAefD8,975
579
579
  zenml/logging/step_logging.py,sha256=L8Kruo9HfVoSIhHEjN6ls3Ywd6wk4w9rTvFipTWkkGA,17606
580
580
  zenml/login/__init__.py,sha256=Evi7hq8tpUn57IM3iX3hYP0r8oIeEWUhS471TAOyVGs,644
@@ -622,7 +622,7 @@ zenml/models/v2/base/base.py,sha256=tXzNTIwGNz7MEgfii3-6ASBNFg4SkR9D9ZM48tlNr84,
622
622
  zenml/models/v2/base/base_plugin_flavor.py,sha256=BfPL4gm5i7ad7_vuRmPtC-rE2kl0W_8SmpWme8Akv1c,2608
623
623
  zenml/models/v2/base/filter.py,sha256=uCZa3MFdEmUL91DYa43vZVuHYBQDC-z3gZWUzzqd63U,36990
624
624
  zenml/models/v2/base/page.py,sha256=yBpWB-8iUmyRwXKSJvX3v9SB7WOnyRa25O8SAss24xk,2601
625
- zenml/models/v2/base/scoped.py,sha256=VYly8lTGD9P4aAO6F3lJ45pBGPFqIMCOwqeb8xei65U,17556
625
+ zenml/models/v2/base/scoped.py,sha256=fOZpuTTUjkg2xE8LvPFUP8lpU9HC-chSQ8xNpmWAW-c,17578
626
626
  zenml/models/v2/core/__init__.py,sha256=LGMIUJi19sOsvo54roZSQwDp_czNQYtenqd_frTLIhU,613
627
627
  zenml/models/v2/core/action.py,sha256=6n6Lep_2-OVUDCWs6eKiUHFKLvcoMjHWP4ZSbua1JRY,7911
628
628
  zenml/models/v2/core/action_flavor.py,sha256=DlGlJTOcgLSDYAsrbAyXOJVdo7X2GYTFQTTEG5BEf-Q,1718
@@ -645,7 +645,7 @@ zenml/models/v2/core/model_version_pipeline_run.py,sha256=JbPZZEQvOK9I32htkWdAON
645
645
  zenml/models/v2/core/pipeline.py,sha256=TGsxPvFzGwHebEVNyNc2kHCQQlMB8CCWWveKXDkACYY,11817
646
646
  zenml/models/v2/core/pipeline_build.py,sha256=bjSvmNnTF9xAycYfmTHO2wzgR-ZVWyy5V5-9ajZUxag,16399
647
647
  zenml/models/v2/core/pipeline_deployment.py,sha256=6PbpnEUAbTT-_jPmyNtKuTJHFGdGLD2h5Zu_pXIHW1I,12108
648
- zenml/models/v2/core/pipeline_run.py,sha256=41TqY_CzUCWlunnyX6GBJ-OmcRtGIm9sHAXB4pIuwMo,32669
648
+ zenml/models/v2/core/pipeline_run.py,sha256=HwZtUGDdjfxUmlbTdkI6Fnvlt0jiLk2aatwYwbhjonI,32699
649
649
  zenml/models/v2/core/run_metadata.py,sha256=YDiPVRzTUMVHqW4T_Ke4GJMdscp0aS_g8I4P8n70szc,2436
650
650
  zenml/models/v2/core/run_template.py,sha256=A_dezNA9o1uJW-o1B9fYaSSWHwwglJYP3jvhWhGcJK4,12971
651
651
  zenml/models/v2/core/schedule.py,sha256=JNYTGPXDPMz7A9OjhnHIXyOLQuoFnrzOwChGibz2xQY,10774
@@ -729,10 +729,10 @@ zenml/services/service_status.py,sha256=-Y1uH43l1VuuvReETCKCBAdYOE0KZeANJ021xyNw
729
729
  zenml/services/service_type.py,sha256=3MVWQu7AgsDyxOIKA79_kkgoBWPri3aJRbZlz2T6NBo,1202
730
730
  zenml/stack/__init__.py,sha256=vfHzaoRhPtS-XSlM8Vx1noJZDHF1Pj6LDz2knpn_QBg,1236
731
731
  zenml/stack/authentication_mixin.py,sha256=sg7GkpB-Ao9Gsa7Po0jxMn-_mVYUB42etmspZ6dk8cI,3982
732
- zenml/stack/flavor.py,sha256=F60xxZaqsNRK51K1g-SIWAK9dFxRQXaIErtr3evQ-ng,9775
732
+ zenml/stack/flavor.py,sha256=8vcaGCwHOyLG3LIaKQxS12N5uSFFLYyNhrHdb5WOE2w,10988
733
733
  zenml/stack/flavor_registry.py,sha256=IL0fRrxxQJ9YkCYCeADP7nwWEQo4XBElJY4owMjKGbQ,6108
734
734
  zenml/stack/stack.py,sha256=ytt38mBjG3an8FTK5-59k0kXMo-QRX-OhaSNmdvXK80,32906
735
- zenml/stack/stack_component.py,sha256=NqUqvufQ3dClK8rdo491K7KRAgv6VbUteA0JApC49VE,29639
735
+ zenml/stack/stack_component.py,sha256=w9GUnlYG89gH0t-Nq3ZM2lVcgFBSzPtdQhYZ9yF4f9o,29424
736
736
  zenml/stack/stack_validator.py,sha256=hWbvvGIeWLj6NwSsF4GCc6RAxAWvxHXTcBZL9nJvcak,3111
737
737
  zenml/stack/utils.py,sha256=qHMFi8SVMSDFeZTFO4KkvaLUbF-l3B0_JZ5SSMxYrwI,6406
738
738
  zenml/stack_deployments/__init__.py,sha256=-7593cQ_ZgRn774Ol-8AKXXQquIU4DSiaThVEr6TfWM,644
@@ -757,10 +757,10 @@ zenml/utils/__init__.py,sha256=jaMTbjm8tLYkaRoxlZ0Em4ye_ZHOHKgP2goPTTiYGUQ,797
757
757
  zenml/utils/archivable.py,sha256=QuLe1IhyABTrE6Y0hAT3tKjaUCpcze5ffZ_RKoKtJwY,6549
758
758
  zenml/utils/callback_registry.py,sha256=QBWdaraLAxBxi8DKbv9X1SUpTKDhhj-XE0JomB2Ax2Y,2411
759
759
  zenml/utils/code_repository_utils.py,sha256=f_VaN-QaCd66xVJJjM4mIo6Heu96-c9qdWh5XUjGpMY,4950
760
- zenml/utils/code_utils.py,sha256=y7_vmqYv_e11xekFjK7Dm4LkFu6SGl73tr2fVxBAK3s,11336
760
+ zenml/utils/code_utils.py,sha256=SsfE4sHcBX3yPyrk3QWZXpXfsTcjycbVIuqVV6zKPDY,11463
761
761
  zenml/utils/cuda_utils.py,sha256=RR21m__Zs-OnI5n-veFUzWniZjwLSbalHE5QV3jK1Hw,1624
762
762
  zenml/utils/daemon.py,sha256=GZ7Dx6GLHK04SR50wBxpKYmFhxPBfdLWxJiAWzJC6cM,11863
763
- zenml/utils/dashboard_utils.py,sha256=JyT-rOsqipazmImXBB-UzCg0GJ3UNzVCFdMcQisInfQ,5379
763
+ zenml/utils/dashboard_utils.py,sha256=fV1U0KeQEmipVRfrhkgXFVenWiz2qctm0kx7aaI5Aww,6073
764
764
  zenml/utils/deprecation_utils.py,sha256=QcWkOnzIRDKPOfkr523n3l2MoY2wE0LIPfbx99t4Gmg,6343
765
765
  zenml/utils/dict_utils.py,sha256=i7KAaKrkaWA_cG5IvVfMnr0CwWlBJ7KAsGvP2wxjZI8,2667
766
766
  zenml/utils/docker_utils.py,sha256=QvkKnvIYSKAhW7mErXwSaQ432-q1LAsLjo2YWSXD8Bk,13889
@@ -779,7 +779,7 @@ zenml/utils/networking_utils.py,sha256=zTDbOMkMPRWiWLZ2ccchd37rvvZWIIh0Kr9dZE-VJ
779
779
  zenml/utils/notebook_utils.py,sha256=VBMU9Qnx_NdpB1TQtnej56L0hRr11fwniOva3ltUT90,4113
780
780
  zenml/utils/package_utils.py,sha256=wy0Mh8hHhOX2z1JfGN5lifG9yEsBQGLwNfur0M3J2tQ,2730
781
781
  zenml/utils/pagination_utils.py,sha256=TufckOqOKeDPwE3ySefL05zOzGUUA2Fqx_QFVhE2so0,1445
782
- zenml/utils/pipeline_docker_image_builder.py,sha256=5gTY5bf58UYy1p_s7_4odEcunC7Hpe1DbdVnCFyPkiY,25034
782
+ zenml/utils/pipeline_docker_image_builder.py,sha256=QOZV_AYFbUtcfJZGNO7pH2_EoXyRqs9GZF_hTeoqW5E,25036
783
783
  zenml/utils/proxy_utils.py,sha256=fgRlLa9pfXJDoxtB31_YP7DClOMQLek_nMmM0et6i3w,7241
784
784
  zenml/utils/pydantic_utils.py,sha256=oQcxY4VXuVY3n632atlvdmi12EYcSQ1xZuQJY3Je-sA,16592
785
785
  zenml/utils/requirements_utils.py,sha256=pUVlQpEtLfz7lLJEUN-t7oHKLzdZZdgHoMzv0V5WXZI,2250
@@ -1246,7 +1246,7 @@ zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.p
1246
1246
  zenml/zen_stores/migrations/versions/f3b3964e3a0f_add_oauth_devices.py,sha256=2CR4R-7Vx6j_AXxo-e5Guy6OX-ZnS47HSKSGfqlO-y0,3065
1247
1247
  zenml/zen_stores/migrations/versions/f49904a80aa7_increase_length_of_artifact_table_sources.py,sha256=kLgfDUnQdAb5_SyFx3VKXDLC0YbuBKf9iXRDNeBin7Q,1618
1248
1248
  zenml/zen_stores/migrations/versions/fbd7f18ced1e_increase_step_run_field_lengths.py,sha256=kn-ng5EHe_mmLfffIFbz7T59z-to3oMx8III_4wOsz4,1956
1249
- zenml/zen_stores/rest_zen_store.py,sha256=Ry1VvFplj9_I_e9_nmWgR7uG7TMPYdhslkY2YEViJH4,160181
1249
+ zenml/zen_stores/rest_zen_store.py,sha256=tB890hOnYaixDKWr7xddpNsNI0GxLV7D4PQd-TE4LiU,159783
1250
1250
  zenml/zen_stores/schemas/__init__.py,sha256=vMb0Pyf94aMWZDWpPKuRaxNoMsTp9DZNKSQScm9Vd5I,4339
1251
1251
  zenml/zen_stores/schemas/action_schemas.py,sha256=uAWlV3Uy8LERBlu7PHCsWEEF4ww6olsVetzVBWmdDSc,6298
1252
1252
  zenml/zen_stores/schemas/api_key_schemas.py,sha256=d_ewTrIJpRjLWupOZFpWcPSlRiHxiBsZJc_qSU7tMMk,7262
@@ -1288,12 +1288,12 @@ zenml/zen_stores/secrets_stores/gcp_secrets_store.py,sha256=qcVyXlDQ3Ur1RQVyzvMY
1288
1288
  zenml/zen_stores/secrets_stores/hashicorp_secrets_store.py,sha256=NfW1EHIA99lsebtSvH_7yhIcLqpTICKTZDKf0Ai255Y,11672
1289
1289
  zenml/zen_stores/secrets_stores/secrets_store_interface.py,sha256=Q2Jbnt2Pp7NGlR-u1YBfRZV2g8su2Fd0ArBMdksAE-Q,2819
1290
1290
  zenml/zen_stores/secrets_stores/service_connector_secrets_store.py,sha256=kPYX-Z_OOhZCI1CP77ncfV7IsV4e8brklnTXmKxZYNc,7078
1291
- zenml/zen_stores/secrets_stores/sql_secrets_store.py,sha256=Bq1djrUP9saoD7vECjS7-TlA_7sjJGgw1talri4spjU,8656
1292
- zenml/zen_stores/sql_zen_store.py,sha256=AaPwO6R_2QVsI_PmDktVTF-Fx6VzR64j-1oU7cJwVxI,416486
1291
+ zenml/zen_stores/secrets_stores/sql_secrets_store.py,sha256=nEO0bAPlULBLxLVk-UTRIZiUeVpATggo8qCsKmgEU1E,8788
1292
+ zenml/zen_stores/sql_zen_store.py,sha256=GEBQDPhm52-YyxLBJcebNviwtr-VK_dnaHrg21fzJOw,417086
1293
1293
  zenml/zen_stores/template_utils.py,sha256=EKYBgmDLTS_PSMWaIO5yvHPLiQvMqHcsAe6NUCrv-i4,9068
1294
1294
  zenml/zen_stores/zen_store_interface.py,sha256=vf2gKBWfUUPtcGZC35oQB6pPNVzWVyQC8nWxVLjfrxM,92692
1295
- zenml_nightly-0.73.0.dev20250128.dist-info/LICENSE,sha256=wbnfEnXnafPbqwANHkV6LUsPKOtdpsd-SNw37rogLtc,11359
1296
- zenml_nightly-0.73.0.dev20250128.dist-info/METADATA,sha256=BV3mpMHnzE1NHGrXN1GGMGemkWe14SU-ysUGOXW2kg8,21355
1297
- zenml_nightly-0.73.0.dev20250128.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
1298
- zenml_nightly-0.73.0.dev20250128.dist-info/entry_points.txt,sha256=QK3ETQE0YswAM2mWypNMOv8TLtr7EjnqAFq1br_jEFE,43
1299
- zenml_nightly-0.73.0.dev20250128.dist-info/RECORD,,
1295
+ zenml_nightly-0.73.0.dev20250130.dist-info/LICENSE,sha256=wbnfEnXnafPbqwANHkV6LUsPKOtdpsd-SNw37rogLtc,11359
1296
+ zenml_nightly-0.73.0.dev20250130.dist-info/METADATA,sha256=Iil8YHORJo4k5qoNT03yMS74Osq372zX8vYS7n7ak6k,21355
1297
+ zenml_nightly-0.73.0.dev20250130.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
1298
+ zenml_nightly-0.73.0.dev20250130.dist-info/entry_points.txt,sha256=QK3ETQE0YswAM2mWypNMOv8TLtr7EjnqAFq1br_jEFE,43
1299
+ zenml_nightly-0.73.0.dev20250130.dist-info/RECORD,,