zenml-nightly 0.84.0.dev20250727__py3-none-any.whl → 0.84.0.dev20250729__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 +1 -1
- zenml/code_repositories/git/local_git_repository_context.py +3 -4
- zenml/constants.py +3 -0
- zenml/integrations/azure/service_connectors/azure_service_connector.py +20 -9
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +20 -1
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +80 -3
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +18 -14
- zenml/models/__init__.py +2 -0
- zenml/models/v2/core/step_run.py +13 -0
- zenml/models/v2/misc/exception_info.py +30 -0
- zenml/orchestrators/publish_utils.py +10 -0
- zenml/orchestrators/step_launcher.py +9 -2
- zenml/orchestrators/step_runner.py +26 -1
- zenml/utils/exception_utils.py +90 -0
- zenml/zen_stores/migrations/versions/d4591f95ac07_step_exception_info.py +43 -0
- zenml/zen_stores/schemas/step_run_schemas.py +19 -0
- {zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/METADATA +1 -1
- {zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/RECORD +21 -18
- {zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/entry_points.txt +0 -0
zenml/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.84.0.
|
1
|
+
0.84.0.dev20250729
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Implementation of the Local git repository context."""
|
15
15
|
|
16
|
-
from typing import TYPE_CHECKING, Callable, Optional
|
16
|
+
from typing import TYPE_CHECKING, Callable, Optional
|
17
17
|
|
18
18
|
from zenml.code_repositories import (
|
19
19
|
LocalRepositoryContext,
|
@@ -25,7 +25,6 @@ from zenml.constants import (
|
|
25
25
|
from zenml.logger import get_logger
|
26
26
|
|
27
27
|
if TYPE_CHECKING:
|
28
|
-
from git.objects import Commit
|
29
28
|
from git.remote import Remote
|
30
29
|
from git.repo.base import Repo
|
31
30
|
|
@@ -180,7 +179,7 @@ class LocalGitRepositoryContext(LocalRepositoryContext):
|
|
180
179
|
# Branch doesn't exist on remote
|
181
180
|
return True
|
182
181
|
|
183
|
-
return
|
182
|
+
return remote_commit_object != local_commit_object
|
184
183
|
|
185
184
|
@property
|
186
185
|
def current_commit(self) -> str:
|
@@ -189,4 +188,4 @@ class LocalGitRepositoryContext(LocalRepositoryContext):
|
|
189
188
|
Returns:
|
190
189
|
The current commit sha.
|
191
190
|
"""
|
192
|
-
return
|
191
|
+
return self.git_repo.head.object.hexsha
|
zenml/constants.py
CHANGED
@@ -181,6 +181,9 @@ ENV_ZENML_PIPELINE_RUN_API_TOKEN_EXPIRATION = (
|
|
181
181
|
ENV_ZENML_CODE_REPOSITORY_IGNORE_UNTRACKED_FILES = (
|
182
182
|
"ZENML_CODE_REPOSITORY_IGNORE_UNTRACKED_FILES"
|
183
183
|
)
|
184
|
+
# Environment variable that indicates whether the current environment is running
|
185
|
+
# a step operator.
|
186
|
+
ENV_ZENML_STEP_OPERATOR = "ZENML_STEP_OPERATOR"
|
184
187
|
|
185
188
|
# Materializer environment variables
|
186
189
|
ENV_ZENML_MATERIALIZER_ALLOW_NON_ASCII_JSON_DUMPS = (
|
@@ -1490,7 +1490,8 @@ class AzureServiceConnector(ServiceConnector):
|
|
1490
1490
|
aks_clusters = [
|
1491
1491
|
cluster
|
1492
1492
|
for cluster in aks_clusters
|
1493
|
-
if
|
1493
|
+
if cluster.id
|
1494
|
+
and self._get_resource_group(cluster.id)
|
1494
1495
|
== self.config.resource_group
|
1495
1496
|
]
|
1496
1497
|
|
@@ -1507,7 +1508,8 @@ class AzureServiceConnector(ServiceConnector):
|
|
1507
1508
|
clusters = [
|
1508
1509
|
(cluster.name, self._get_resource_group(cluster.id))
|
1509
1510
|
for cluster in aks_clusters
|
1510
|
-
if cluster.
|
1511
|
+
if cluster.id
|
1512
|
+
and cluster.name
|
1511
1513
|
and (not cluster_name or cluster.name == cluster_name)
|
1512
1514
|
]
|
1513
1515
|
|
@@ -1809,16 +1811,25 @@ class AzureServiceConnector(ServiceConnector):
|
|
1809
1811
|
cluster_name, resource_group = clusters[0]
|
1810
1812
|
|
1811
1813
|
try:
|
1812
|
-
|
1814
|
+
cs_client = ContainerServiceClient(credential, subscription_id)
|
1813
1815
|
|
1814
|
-
creds =
|
1815
|
-
|
1816
|
-
|
1816
|
+
creds = (
|
1817
|
+
cs_client.managed_clusters.list_cluster_admin_credentials(
|
1818
|
+
resource_group_name=resource_group,
|
1819
|
+
resource_name=cluster_name,
|
1820
|
+
)
|
1817
1821
|
)
|
1818
1822
|
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1823
|
+
if creds.kubeconfigs and creds.kubeconfigs[0].value:
|
1824
|
+
kubeconfig_yaml = creds.kubeconfigs[0].value.decode(
|
1825
|
+
encoding="UTF-8"
|
1826
|
+
)
|
1827
|
+
else:
|
1828
|
+
raise AuthorizationException(
|
1829
|
+
f"failed to list credentials for Azure Kubernetes "
|
1830
|
+
f"Service cluster '{cluster_name}' in resource group "
|
1831
|
+
f"'{resource_group}': no kubeconfig found"
|
1832
|
+
)
|
1822
1833
|
except AzureError as e:
|
1823
1834
|
raise AuthorizationException(
|
1824
1835
|
f"failed to list credentials for Azure Kubernetes "
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Kubernetes orchestrator flavor."""
|
15
15
|
|
16
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional, Type
|
16
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type
|
17
17
|
|
18
18
|
from pydantic import Field, NonNegativeInt, PositiveInt, field_validator
|
19
19
|
|
@@ -131,6 +131,25 @@ class KubernetesOrchestratorSettings(BaseSettings):
|
|
131
131
|
"the chance of the server receiving the maximum amount of retry "
|
132
132
|
"requests.",
|
133
133
|
)
|
134
|
+
fail_on_container_waiting_reasons: Optional[List[str]] = Field(
|
135
|
+
default=[
|
136
|
+
"InvalidImageName",
|
137
|
+
"ErrImagePull",
|
138
|
+
"ImagePullBackOff",
|
139
|
+
"CreateContainerConfigError",
|
140
|
+
],
|
141
|
+
description="List of container waiting reasons that should cause the "
|
142
|
+
"job to fail immediately. This should be set to a list of "
|
143
|
+
"nonrecoverable reasons, which if found in any "
|
144
|
+
"`pod.status.containerStatuses[*].state.waiting.reason` of a job pod, "
|
145
|
+
"should cause the job to fail immediately.",
|
146
|
+
)
|
147
|
+
job_monitoring_interval: int = Field(
|
148
|
+
default=3,
|
149
|
+
description="The interval in seconds to monitor the job. Each interval "
|
150
|
+
"is used to check for container issues and streaming logs for the "
|
151
|
+
"job pods.",
|
152
|
+
)
|
134
153
|
pod_failure_policy: Optional[Dict[str, Any]] = Field(
|
135
154
|
default=None,
|
136
155
|
description="The pod failure policy to use for the job that is "
|
@@ -37,7 +37,7 @@ import json
|
|
37
37
|
import re
|
38
38
|
import time
|
39
39
|
from collections import defaultdict
|
40
|
-
from typing import Any, Callable, Dict, List, Optional, TypeVar, cast
|
40
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, cast
|
41
41
|
|
42
42
|
from kubernetes import client as k8s_client
|
43
43
|
from kubernetes import config as k8s_config
|
@@ -657,6 +657,50 @@ def create_job(
|
|
657
657
|
)
|
658
658
|
|
659
659
|
|
660
|
+
def get_container_status(
|
661
|
+
pod: k8s_client.V1Pod, container_name: str
|
662
|
+
) -> Optional[k8s_client.V1ContainerState]:
|
663
|
+
"""Get the status of a container.
|
664
|
+
|
665
|
+
Args:
|
666
|
+
pod: The pod to get the container status for.
|
667
|
+
container_name: The container name.
|
668
|
+
|
669
|
+
Returns:
|
670
|
+
The container status.
|
671
|
+
"""
|
672
|
+
if not pod.status or not pod.status.container_statuses:
|
673
|
+
return None
|
674
|
+
|
675
|
+
for container_status in pod.status.container_statuses:
|
676
|
+
if container_status.name == container_name:
|
677
|
+
return container_status.state
|
678
|
+
|
679
|
+
return None
|
680
|
+
|
681
|
+
|
682
|
+
def get_container_termination_reason(
|
683
|
+
pod: k8s_client.V1Pod, container_name: str
|
684
|
+
) -> Optional[Tuple[int, str]]:
|
685
|
+
"""Get the termination reason for a container.
|
686
|
+
|
687
|
+
Args:
|
688
|
+
pod: The pod to get the termination reason for.
|
689
|
+
container_name: The container name.
|
690
|
+
|
691
|
+
Returns:
|
692
|
+
The exit code and termination reason for the container.
|
693
|
+
"""
|
694
|
+
container_state = get_container_status(pod, container_name)
|
695
|
+
if not container_state or not container_state.terminated:
|
696
|
+
return None
|
697
|
+
|
698
|
+
return (
|
699
|
+
container_state.terminated.exit_code,
|
700
|
+
container_state.terminated.reason or "Unknown",
|
701
|
+
)
|
702
|
+
|
703
|
+
|
660
704
|
def wait_for_job_to_finish(
|
661
705
|
batch_api: k8s_client.BatchV1Api,
|
662
706
|
core_api: k8s_client.CoreV1Api,
|
@@ -665,8 +709,9 @@ def wait_for_job_to_finish(
|
|
665
709
|
backoff_interval: float = 1,
|
666
710
|
maximum_backoff: float = 32,
|
667
711
|
exponential_backoff: bool = False,
|
668
|
-
|
712
|
+
fail_on_container_waiting_reasons: Optional[List[str]] = None,
|
669
713
|
stream_logs: bool = True,
|
714
|
+
container_name: Optional[str] = None,
|
670
715
|
) -> None:
|
671
716
|
"""Wait for a job to finish.
|
672
717
|
|
@@ -679,6 +724,8 @@ def wait_for_job_to_finish(
|
|
679
724
|
maximum_backoff: The maximum interval to wait between polling the job
|
680
725
|
status.
|
681
726
|
exponential_backoff: Whether to use exponential backoff.
|
727
|
+
fail_on_container_waiting_reasons: List of container waiting reasons
|
728
|
+
that will cause the job to fail.
|
682
729
|
stream_logs: Whether to stream the job logs.
|
683
730
|
container_name: Name of the container to stream logs from.
|
684
731
|
|
@@ -703,9 +750,39 @@ def wait_for_job_to_finish(
|
|
703
750
|
f"{condition.message}"
|
704
751
|
)
|
705
752
|
|
753
|
+
if fail_on_container_waiting_reasons:
|
754
|
+
pod_list: k8s_client.V1PodList = retry_on_api_exception(
|
755
|
+
core_api.list_namespaced_pod
|
756
|
+
)(
|
757
|
+
namespace=namespace,
|
758
|
+
label_selector=f"job-name={job_name}",
|
759
|
+
field_selector="status.phase=Pending",
|
760
|
+
)
|
761
|
+
for pod in pod_list.items:
|
762
|
+
container_state = get_container_status(
|
763
|
+
pod, container_name or "main"
|
764
|
+
)
|
765
|
+
|
766
|
+
if (
|
767
|
+
container_state
|
768
|
+
and (waiting_state := container_state.waiting)
|
769
|
+
and waiting_state.reason
|
770
|
+
in fail_on_container_waiting_reasons
|
771
|
+
):
|
772
|
+
retry_on_api_exception(batch_api.delete_namespaced_job)(
|
773
|
+
name=job_name,
|
774
|
+
namespace=namespace,
|
775
|
+
propagation_policy="Foreground",
|
776
|
+
)
|
777
|
+
raise RuntimeError(
|
778
|
+
f"Job `{namespace}:{job_name}` failed: "
|
779
|
+
f"Detected container in state "
|
780
|
+
f"{waiting_state.reason}"
|
781
|
+
)
|
782
|
+
|
706
783
|
if stream_logs:
|
707
784
|
try:
|
708
|
-
pod_list
|
785
|
+
pod_list = core_api.list_namespaced_pod(
|
709
786
|
namespace=namespace,
|
710
787
|
label_selector=f"job-name={job_name}",
|
711
788
|
)
|
@@ -367,33 +367,37 @@ def main() -> None:
|
|
367
367
|
core_api=core_api,
|
368
368
|
namespace=namespace,
|
369
369
|
job_name=job_name,
|
370
|
+
fail_on_container_waiting_reasons=settings.fail_on_container_waiting_reasons,
|
370
371
|
stream_logs=pipeline_settings.stream_step_logs,
|
372
|
+
backoff_interval=settings.job_monitoring_interval,
|
371
373
|
)
|
372
374
|
|
373
375
|
logger.info(f"Job for step `{step_name}` completed.")
|
374
376
|
except Exception:
|
375
|
-
reason = ""
|
377
|
+
reason = "Unknown"
|
376
378
|
try:
|
377
|
-
|
379
|
+
pods = core_api.list_namespaced_pod(
|
378
380
|
label_selector=f"job-name={job_name}",
|
379
381
|
namespace=namespace,
|
380
382
|
).items
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
383
|
+
# Sort pods by creation timestamp, oldest first
|
384
|
+
pods.sort(
|
385
|
+
key=lambda pod: pod.metadata.creation_timestamp,
|
386
|
+
)
|
387
|
+
if pods:
|
388
|
+
if (
|
389
|
+
termination_reason
|
390
|
+
:= kube_utils.get_container_termination_reason(
|
391
|
+
pods[-1], "main"
|
392
|
+
)
|
393
|
+
):
|
394
|
+
exit_code, reason = termination_reason
|
395
|
+
if exit_code != 0:
|
396
|
+
reason = f"{reason} (exit_code={exit_code})"
|
391
397
|
except Exception:
|
392
398
|
pass
|
393
399
|
logger.error(
|
394
400
|
f"Job for step `{step_name}` failed. Reason: {reason}"
|
395
|
-
if reason
|
396
|
-
else ""
|
397
401
|
)
|
398
402
|
|
399
403
|
raise
|
zenml/models/__init__.py
CHANGED
@@ -435,6 +435,7 @@ from zenml.models.v2.misc.info_models import (
|
|
435
435
|
ServiceConnectorResourcesInfo,
|
436
436
|
ResourcesInfo,
|
437
437
|
)
|
438
|
+
from zenml.models.v2.misc.exception_info import ExceptionInfo
|
438
439
|
|
439
440
|
# ----------------------------- Forward References -----------------------------
|
440
441
|
|
@@ -840,4 +841,5 @@ __all__ = [
|
|
840
841
|
"RunMetadataResource",
|
841
842
|
"ProjectStatistics",
|
842
843
|
"PipelineRunDAG",
|
844
|
+
"ExceptionInfo",
|
843
845
|
]
|
zenml/models/v2/core/step_run.py
CHANGED
@@ -48,6 +48,7 @@ from zenml.models.v2.base.scoped import (
|
|
48
48
|
)
|
49
49
|
from zenml.models.v2.core.artifact_version import ArtifactVersionResponse
|
50
50
|
from zenml.models.v2.core.model_version import ModelVersionResponse
|
51
|
+
from zenml.models.v2.misc.exception_info import ExceptionInfo
|
51
52
|
|
52
53
|
if TYPE_CHECKING:
|
53
54
|
from sqlalchemy.sql.elements import ColumnElement
|
@@ -143,6 +144,10 @@ class StepRunRequest(ProjectScopedRequest):
|
|
143
144
|
title="Logs associated with this step run.",
|
144
145
|
default=None,
|
145
146
|
)
|
147
|
+
exception_info: Optional[ExceptionInfo] = Field(
|
148
|
+
default=None,
|
149
|
+
title="The exception information of the step run.",
|
150
|
+
)
|
146
151
|
|
147
152
|
model_config = ConfigDict(protected_namespaces=())
|
148
153
|
|
@@ -169,6 +174,10 @@ class StepRunUpdate(BaseUpdate):
|
|
169
174
|
title="The end time of the step run.",
|
170
175
|
default=None,
|
171
176
|
)
|
177
|
+
exception_info: Optional[ExceptionInfo] = Field(
|
178
|
+
default=None,
|
179
|
+
title="The exception information of the step run.",
|
180
|
+
)
|
172
181
|
model_config = ConfigDict(protected_namespaces=())
|
173
182
|
|
174
183
|
|
@@ -237,6 +246,10 @@ class StepRunResponseMetadata(ProjectScopedResponseMetadata):
|
|
237
246
|
default=None,
|
238
247
|
max_length=TEXT_FIELD_MAX_LENGTH,
|
239
248
|
)
|
249
|
+
exception_info: Optional[ExceptionInfo] = Field(
|
250
|
+
default=None,
|
251
|
+
title="The exception information of the step run.",
|
252
|
+
)
|
240
253
|
|
241
254
|
# References
|
242
255
|
logs: Optional["LogsResponse"] = Field(
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (c) ZenML GmbH 2025. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at:
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
12
|
+
# or implied. See the License for the specific language governing
|
13
|
+
# permissions and limitations under the License.
|
14
|
+
"""Exception information models."""
|
15
|
+
|
16
|
+
from typing import Optional
|
17
|
+
|
18
|
+
from pydantic import BaseModel, Field
|
19
|
+
|
20
|
+
|
21
|
+
class ExceptionInfo(BaseModel):
|
22
|
+
"""Exception information."""
|
23
|
+
|
24
|
+
traceback: str = Field(
|
25
|
+
title="The traceback of the exception.",
|
26
|
+
)
|
27
|
+
step_code_line: Optional[int] = Field(
|
28
|
+
default=None,
|
29
|
+
title="The line number of the step code that raised the exception.",
|
30
|
+
)
|
@@ -13,12 +13,14 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Utilities to publish pipeline and step runs."""
|
15
15
|
|
16
|
+
from contextvars import ContextVar
|
16
17
|
from datetime import datetime
|
17
18
|
from typing import TYPE_CHECKING, Dict, List, Optional
|
18
19
|
|
19
20
|
from zenml.client import Client
|
20
21
|
from zenml.enums import ExecutionStatus, MetadataResourceTypes
|
21
22
|
from zenml.models import (
|
23
|
+
ExceptionInfo,
|
22
24
|
PipelineRunResponse,
|
23
25
|
PipelineRunUpdate,
|
24
26
|
RunMetadataResource,
|
@@ -32,6 +34,10 @@ if TYPE_CHECKING:
|
|
32
34
|
|
33
35
|
from zenml.metadata.metadata_types import MetadataType
|
34
36
|
|
37
|
+
step_exception_info: ContextVar[Optional[ExceptionInfo]] = ContextVar(
|
38
|
+
"step_exception_info", default=None
|
39
|
+
)
|
40
|
+
|
35
41
|
|
36
42
|
def publish_successful_step_run(
|
37
43
|
step_run_id: "UUID", output_artifact_ids: Dict[str, List["UUID"]]
|
@@ -59,6 +65,7 @@ def publish_step_run_status_update(
|
|
59
65
|
step_run_id: "UUID",
|
60
66
|
status: "ExecutionStatus",
|
61
67
|
end_time: Optional[datetime] = None,
|
68
|
+
exception_info: Optional[ExceptionInfo] = None,
|
62
69
|
) -> "StepRunResponse":
|
63
70
|
"""Publishes a step run update.
|
64
71
|
|
@@ -66,6 +73,7 @@ def publish_step_run_status_update(
|
|
66
73
|
step_run_id: ID of the step run.
|
67
74
|
status: New status of the step run.
|
68
75
|
end_time: New end time of the step run.
|
76
|
+
exception_info: Exception information of the step run.
|
69
77
|
|
70
78
|
Returns:
|
71
79
|
The updated step run.
|
@@ -83,6 +91,7 @@ def publish_step_run_status_update(
|
|
83
91
|
step_run_update=StepRunUpdate(
|
84
92
|
status=status,
|
85
93
|
end_time=end_time,
|
94
|
+
exception_info=exception_info,
|
86
95
|
),
|
87
96
|
)
|
88
97
|
|
@@ -102,6 +111,7 @@ def publish_failed_step_run(step_run_id: "UUID") -> "StepRunResponse":
|
|
102
111
|
step_run_id=step_run_id,
|
103
112
|
status=ExecutionStatus.FAILED,
|
104
113
|
end_time=utc_now(),
|
114
|
+
exception_info=step_exception_info.get(),
|
105
115
|
)
|
106
116
|
|
107
117
|
|
@@ -24,6 +24,7 @@ from zenml.config.step_configurations import Step
|
|
24
24
|
from zenml.config.step_run_info import StepRunInfo
|
25
25
|
from zenml.constants import (
|
26
26
|
ENV_ZENML_DISABLE_STEP_LOGS_STORAGE,
|
27
|
+
ENV_ZENML_STEP_OPERATOR,
|
27
28
|
handle_bool_env_var,
|
28
29
|
)
|
29
30
|
from zenml.enums import ExecutionStatus
|
@@ -43,7 +44,7 @@ from zenml.orchestrators import output_utils, publish_utils, step_run_utils
|
|
43
44
|
from zenml.orchestrators import utils as orchestrator_utils
|
44
45
|
from zenml.orchestrators.step_runner import StepRunner
|
45
46
|
from zenml.stack import Stack
|
46
|
-
from zenml.utils import string_utils
|
47
|
+
from zenml.utils import exception_utils, string_utils
|
47
48
|
from zenml.utils.time_utils import utc_now
|
48
49
|
|
49
50
|
if TYPE_CHECKING:
|
@@ -211,7 +212,9 @@ class StepLauncher:
|
|
211
212
|
|
212
213
|
Raises:
|
213
214
|
RunStoppedException: If the pipeline run is stopped by the user.
|
215
|
+
BaseException: If the step preparation or execution fails.
|
214
216
|
"""
|
217
|
+
publish_utils.step_exception_info.set(None)
|
215
218
|
pipeline_run, run_was_created = self._create_or_reuse_run()
|
216
219
|
|
217
220
|
# Enable or disable step logs storage
|
@@ -269,10 +272,13 @@ class StepLauncher:
|
|
269
272
|
|
270
273
|
try:
|
271
274
|
request_factory.populate_request(request=step_run_request)
|
272
|
-
except:
|
275
|
+
except BaseException as e:
|
273
276
|
logger.exception(f"Failed preparing step `{self._step_name}`.")
|
274
277
|
step_run_request.status = ExecutionStatus.FAILED
|
275
278
|
step_run_request.end_time = utc_now()
|
279
|
+
step_run_request.exception_info = (
|
280
|
+
exception_utils.collect_exception_information(e)
|
281
|
+
)
|
276
282
|
raise
|
277
283
|
finally:
|
278
284
|
step_run = Client().zen_store.create_run_step(step_run_request)
|
@@ -453,6 +459,7 @@ class StepLauncher:
|
|
453
459
|
environment = orchestrator_utils.get_config_environment_vars(
|
454
460
|
pipeline_run_id=step_run_info.run_id,
|
455
461
|
)
|
462
|
+
environment[ENV_ZENML_STEP_OPERATOR] = "True"
|
456
463
|
logger.info(
|
457
464
|
"Using step operator `%s` to run step `%s`.",
|
458
465
|
step_operator.name,
|
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
import copy
|
18
18
|
import inspect
|
19
|
+
import os
|
19
20
|
from contextlib import nullcontext
|
20
21
|
from typing import (
|
21
22
|
TYPE_CHECKING,
|
@@ -34,6 +35,7 @@ from zenml.config.step_configurations import StepConfiguration
|
|
34
35
|
from zenml.config.step_run_info import StepRunInfo
|
35
36
|
from zenml.constants import (
|
36
37
|
ENV_ZENML_DISABLE_STEP_LOGS_STORAGE,
|
38
|
+
ENV_ZENML_STEP_OPERATOR,
|
37
39
|
handle_bool_env_var,
|
38
40
|
)
|
39
41
|
from zenml.enums import ArtifactSaveType
|
@@ -41,10 +43,14 @@ from zenml.exceptions import StepInterfaceError
|
|
41
43
|
from zenml.logger import get_logger
|
42
44
|
from zenml.logging.step_logging import PipelineLogsStorageContext, redirected
|
43
45
|
from zenml.materializers.base_materializer import BaseMaterializer
|
44
|
-
from zenml.models.v2.core.step_run import
|
46
|
+
from zenml.models.v2.core.step_run import (
|
47
|
+
StepRunInputResponse,
|
48
|
+
StepRunUpdate,
|
49
|
+
)
|
45
50
|
from zenml.orchestrators.publish_utils import (
|
46
51
|
publish_step_run_metadata,
|
47
52
|
publish_successful_step_run,
|
53
|
+
step_exception_info,
|
48
54
|
)
|
49
55
|
from zenml.orchestrators.utils import (
|
50
56
|
is_setting_enabled,
|
@@ -56,6 +62,7 @@ from zenml.steps.utils import (
|
|
56
62
|
resolve_type_annotation,
|
57
63
|
)
|
58
64
|
from zenml.utils import (
|
65
|
+
exception_utils,
|
59
66
|
materializer_utils,
|
60
67
|
source_utils,
|
61
68
|
string_utils,
|
@@ -193,6 +200,24 @@ class StepRunner:
|
|
193
200
|
)
|
194
201
|
except BaseException as step_exception: # noqa: E722
|
195
202
|
step_failed = True
|
203
|
+
|
204
|
+
exception_info = exception_utils.collect_exception_information(
|
205
|
+
step_exception, step_instance
|
206
|
+
)
|
207
|
+
|
208
|
+
if ENV_ZENML_STEP_OPERATOR in os.environ:
|
209
|
+
# We're running in a step operator environment, so we can't
|
210
|
+
# depend on the step launcher to publish the exception info
|
211
|
+
Client().zen_store.update_run_step(
|
212
|
+
step_run_id=step_run_info.step_run_id,
|
213
|
+
step_run_update=StepRunUpdate(
|
214
|
+
exception_info=exception_info,
|
215
|
+
),
|
216
|
+
)
|
217
|
+
else:
|
218
|
+
# This will be published by the step launcher
|
219
|
+
step_exception_info.set(exception_info)
|
220
|
+
|
196
221
|
if not step_run.is_retriable:
|
197
222
|
if (
|
198
223
|
failure_hook_source
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (c) ZenML GmbH 2025. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at:
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
12
|
+
# or implied. See the License for the specific language governing
|
13
|
+
# permissions and limitations under the License.
|
14
|
+
"""Exception utilities."""
|
15
|
+
|
16
|
+
import inspect
|
17
|
+
import os
|
18
|
+
import re
|
19
|
+
import traceback
|
20
|
+
from typing import TYPE_CHECKING, Optional
|
21
|
+
|
22
|
+
from zenml.constants import MEDIUMTEXT_MAX_LENGTH
|
23
|
+
from zenml.logger import get_logger
|
24
|
+
from zenml.models import (
|
25
|
+
ExceptionInfo,
|
26
|
+
)
|
27
|
+
|
28
|
+
if TYPE_CHECKING:
|
29
|
+
from zenml.steps import BaseStep
|
30
|
+
|
31
|
+
logger = get_logger(__name__)
|
32
|
+
|
33
|
+
|
34
|
+
def collect_exception_information(
|
35
|
+
exception: BaseException, step_instance: Optional["BaseStep"] = None
|
36
|
+
) -> ExceptionInfo:
|
37
|
+
"""Collects the exception information.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
exception: The exception to collect information from.
|
41
|
+
step_instance: The step instance that is currently running.
|
42
|
+
|
43
|
+
Returns:
|
44
|
+
The exception information.
|
45
|
+
"""
|
46
|
+
tb = traceback.format_tb(exception.__traceback__)
|
47
|
+
line_number = None
|
48
|
+
start_index = None
|
49
|
+
|
50
|
+
if step_instance and (
|
51
|
+
source_file := inspect.getsourcefile(step_instance.entrypoint)
|
52
|
+
):
|
53
|
+
try:
|
54
|
+
source_file = os.path.abspath(source_file)
|
55
|
+
|
56
|
+
lines, start_line = inspect.getsourcelines(
|
57
|
+
step_instance.entrypoint
|
58
|
+
)
|
59
|
+
end_line = start_line + len(lines)
|
60
|
+
|
61
|
+
line_pattern = re.compile(f'File "{source_file}", line (\d+),')
|
62
|
+
|
63
|
+
for index, line in enumerate(tb):
|
64
|
+
match = line_pattern.search(line)
|
65
|
+
if match:
|
66
|
+
potential_line_number = int(match.group(1))
|
67
|
+
if (
|
68
|
+
potential_line_number >= start_line
|
69
|
+
and potential_line_number <= end_line
|
70
|
+
):
|
71
|
+
line_number = potential_line_number - start_line
|
72
|
+
start_index = index
|
73
|
+
break
|
74
|
+
except Exception as e:
|
75
|
+
logger.debug("Failed to detect step code line: %s", e)
|
76
|
+
|
77
|
+
if start_index is not None:
|
78
|
+
# If the code failed while executing user code, we remove the initial
|
79
|
+
# part of the traceback that is happening in the ZenML code.
|
80
|
+
tb = tb[start_index:]
|
81
|
+
|
82
|
+
tb_bytes = "\n".join(tb).encode()
|
83
|
+
tb_bytes = tb_bytes[:MEDIUMTEXT_MAX_LENGTH]
|
84
|
+
|
85
|
+
return ExceptionInfo(
|
86
|
+
# Ignore errors when decoding in case we cut off in the middle of an
|
87
|
+
# encoded character.
|
88
|
+
traceback=tb_bytes.decode(errors="ignore"),
|
89
|
+
step_code_line=line_number,
|
90
|
+
)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""Step exception info [d4591f95ac07].
|
2
|
+
|
3
|
+
Revision ID: d4591f95ac07
|
4
|
+
Revises: 0.84.0
|
5
|
+
Create Date: 2025-07-17 14:13:54.731842
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sqlalchemy as sa
|
10
|
+
from alembic import op
|
11
|
+
from sqlalchemy.dialects import mysql
|
12
|
+
|
13
|
+
# revision identifiers, used by Alembic.
|
14
|
+
revision = "d4591f95ac07"
|
15
|
+
down_revision = "0.84.0"
|
16
|
+
branch_labels = None
|
17
|
+
depends_on = None
|
18
|
+
|
19
|
+
|
20
|
+
def upgrade() -> None:
|
21
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
22
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
23
|
+
with op.batch_alter_table("step_run", schema=None) as batch_op:
|
24
|
+
batch_op.add_column(
|
25
|
+
sa.Column(
|
26
|
+
"exception_info",
|
27
|
+
sa.String(length=16777215).with_variant(
|
28
|
+
mysql.MEDIUMTEXT, "mysql"
|
29
|
+
),
|
30
|
+
nullable=True,
|
31
|
+
)
|
32
|
+
)
|
33
|
+
|
34
|
+
# ### end Alembic commands ###
|
35
|
+
|
36
|
+
|
37
|
+
def downgrade() -> None:
|
38
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
39
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
40
|
+
with op.batch_alter_table("step_run", schema=None) as batch_op:
|
41
|
+
batch_op.drop_column("exception_info")
|
42
|
+
|
43
|
+
# ### end Alembic commands ###
|
@@ -34,6 +34,7 @@ from zenml.enums import (
|
|
34
34
|
StepRunInputArtifactType,
|
35
35
|
)
|
36
36
|
from zenml.models import (
|
37
|
+
ExceptionInfo,
|
37
38
|
StepRunRequest,
|
38
39
|
StepRunResponse,
|
39
40
|
StepRunResponseBody,
|
@@ -101,6 +102,14 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
101
102
|
nullable=True,
|
102
103
|
)
|
103
104
|
)
|
105
|
+
exception_info: Optional[str] = Field(
|
106
|
+
sa_column=Column(
|
107
|
+
String(length=MEDIUMTEXT_MAX_LENGTH).with_variant(
|
108
|
+
MEDIUMTEXT, "mysql"
|
109
|
+
),
|
110
|
+
nullable=True,
|
111
|
+
)
|
112
|
+
)
|
104
113
|
|
105
114
|
# Foreign keys
|
106
115
|
original_step_run_id: Optional[UUID] = build_foreign_key_field(
|
@@ -310,6 +319,9 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
310
319
|
source_code=request.source_code,
|
311
320
|
version=version,
|
312
321
|
is_retriable=is_retriable,
|
322
|
+
exception_info=json.dumps(request.exception_info)
|
323
|
+
if request.exception_info
|
324
|
+
else None,
|
313
325
|
)
|
314
326
|
|
315
327
|
def get_step_configuration(self) -> Step:
|
@@ -395,6 +407,11 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
395
407
|
code_hash=self.code_hash,
|
396
408
|
docstring=self.docstring,
|
397
409
|
source_code=self.source_code,
|
410
|
+
exception_info=ExceptionInfo.model_validate_json(
|
411
|
+
self.exception_info
|
412
|
+
)
|
413
|
+
if self.exception_info
|
414
|
+
else None,
|
398
415
|
logs=self.logs.to_model() if self.logs else None,
|
399
416
|
deployment_id=self.deployment_id,
|
400
417
|
pipeline_run_id=self.pipeline_run_id,
|
@@ -458,6 +475,8 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
458
475
|
self.status = value.value
|
459
476
|
if key == "end_time":
|
460
477
|
self.end_time = value
|
478
|
+
if key == "exception_info":
|
479
|
+
self.exception_info = json.dumps(value)
|
461
480
|
|
462
481
|
self.updated = utc_now()
|
463
482
|
|
{zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/RECORD
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
zenml/README.md,sha256=827dekbOWAs1BpW7VF1a4d7EbwPbjwccX-2zdXBENZo,1777
|
2
|
-
zenml/VERSION,sha256=
|
2
|
+
zenml/VERSION,sha256=ig64qkkuwpgtDDUBRHxcjuv0CoEUTgcfKVFR9WA0Wt8,19
|
3
3
|
zenml/__init__.py,sha256=r7JUg2SVDf_dPhS7iU6vudKusEqK4ics7_jFMZhq0o4,2731
|
4
4
|
zenml/actions/__init__.py,sha256=mrt6wPo73iKRxK754_NqsGyJ3buW7RnVeIGXr1xEw8Y,681
|
5
5
|
zenml/actions/base_action.py,sha256=UcaHev6BTuLDwuswnyaPjdA8AgUqB5xPZ-lRtuvf2FU,25553
|
@@ -60,7 +60,7 @@ zenml/client_lazy_loader.py,sha256=oyxKvBWVB7k2pHMavdhNEOfR2Vk4IS3XUu43SBzDPsI,7
|
|
60
60
|
zenml/code_repositories/__init__.py,sha256=W5bDfzAG8OXIKZSV1L-VHuzMcSCYa9qzTdPb3jqfyYw,920
|
61
61
|
zenml/code_repositories/base_code_repository.py,sha256=Id6VjbUu8N3ZpNvBGhOgbahtoMiCAtYXed3G7YQ_iAc,5225
|
62
62
|
zenml/code_repositories/git/__init__.py,sha256=vU8UzMp8sv9n-R2r7VKa9LdQcYER6BhO4O-z8Ppa3kM,824
|
63
|
-
zenml/code_repositories/git/local_git_repository_context.py,sha256=
|
63
|
+
zenml/code_repositories/git/local_git_repository_context.py,sha256=PuD4GOnxBNtkSddc5QwMnnx3F2t4gClUeGmhfoLQHfs,5780
|
64
64
|
zenml/code_repositories/local_repository_context.py,sha256=1VyiYkJBDVg0iGusgRQDToGRPJuu9lx7jTBDpplukDg,2816
|
65
65
|
zenml/config/__init__.py,sha256=NIMS7QQo3-uVkNlzPvR5FbtgPdRibF2xFJB7Vr0fhCM,1826
|
66
66
|
zenml/config/base_settings.py,sha256=itoLqc1cOwEYhgSGdZmSKSaBevQkvYH7NQh7PUamazc,1700
|
@@ -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=t_ULrtJF2eW7TgyYBRobl1fscwwIZXATYky8ER97ev4,860
|
87
87
|
zenml/console.py,sha256=A54wgNv_ntZkU4uGLox00IPVskDapH31xhtgAV5x4-E,1299
|
88
|
-
zenml/constants.py,sha256=
|
88
|
+
zenml/constants.py,sha256=olos1s4CGUzUpTTkcEmwS4iR7GENdgA-B-9pQWsS8gk,16950
|
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=5e-49puqeNgGdsLbfALoV-J8AgnriSvD-DDwBCPCiCs,9709
|
@@ -166,7 +166,7 @@ zenml/integrations/azure/orchestrators/__init__.py,sha256=q4rBPIJHcuUr6dLUBdrTkQ
|
|
166
166
|
zenml/integrations/azure/orchestrators/azureml_orchestrator.py,sha256=zWtRz_ymW6CZfwgcLYUGLCDvWF_SUvgB9jBPkc192A0,21072
|
167
167
|
zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py,sha256=lacOyorsHa-HuD_kxN9M6BUiZDvs5jL9AnJWwrFCtp4,3104
|
168
168
|
zenml/integrations/azure/service_connectors/__init__.py,sha256=yMz6bTCtIZqZwfEM6h7-PSWsd_DB8l0OD9z_bdzomZw,793
|
169
|
-
zenml/integrations/azure/service_connectors/azure_service_connector.py,sha256=
|
169
|
+
zenml/integrations/azure/service_connectors/azure_service_connector.py,sha256=B9YBr-5j2D3UZ6Lo4e7aNMy5Os35W7dR-bno0QUMfUE,81865
|
170
170
|
zenml/integrations/azure/step_operators/__init__.py,sha256=fV4_nAO0cH53x6_-F8-CbDEZwb_Vv64oq1r0-vtigEU,819
|
171
171
|
zenml/integrations/azure/step_operators/azureml_step_operator.py,sha256=bi6cl1PimxZF6D7PVZepC6OqHdGHTcsNGBe0njuiBCM,7397
|
172
172
|
zenml/integrations/bentoml/__init__.py,sha256=vOlziqJ038cS7_ZtbGojWpefdQDigq8mLDALVC_lgbY,1835
|
@@ -334,12 +334,12 @@ zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py,sha256=lPQSQn
|
|
334
334
|
zenml/integrations/kubeflow/orchestrators/local_deployment_utils.py,sha256=qszoOdvBpgIp40XkncphXAr9dRKnyZzGiz2mJ56bYmw,15448
|
335
335
|
zenml/integrations/kubernetes/__init__.py,sha256=k1bfrdI1u5RBnAh7yT4w-m-4SWgZ7b4L5uu7dPRc0SI,1809
|
336
336
|
zenml/integrations/kubernetes/flavors/__init__.py,sha256=a5gU45qCj3FkLwl_uVjlIkL_2F5DHk-w1gdcZrvVjBI,1266
|
337
|
-
zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py,sha256=
|
337
|
+
zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py,sha256=zhcn5d3N4VmlVq-cxtyXtp63AKcwVfKWg-jAlkx2B10,14420
|
338
338
|
zenml/integrations/kubernetes/flavors/kubernetes_step_operator_flavor.py,sha256=Vp7kY9t2TWdWRBNSf_sJKPL5dZnhuHnskPhQ7KBuGPY,6384
|
339
339
|
zenml/integrations/kubernetes/orchestrators/__init__.py,sha256=TJID3OTieZBox36WpQpzD0jdVRA_aZVcs_bNtfXS8ik,811
|
340
|
-
zenml/integrations/kubernetes/orchestrators/kube_utils.py,sha256=
|
340
|
+
zenml/integrations/kubernetes/orchestrators/kube_utils.py,sha256=Gbw1mT0z-F_t2iQKPmLntGhdNTT-CZNHO5sDb-XxE68,27709
|
341
341
|
zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py,sha256=Agx_Thj6nByAd5p61HTf0p6SRDPOcYKSSl-_Km2EdfU,41316
|
342
|
-
zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py,sha256=
|
342
|
+
zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py,sha256=jgxnJdBVFVn6l6gSoygIoScQxyKh5cVbgXF10qFA9Nk,20809
|
343
343
|
zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint_configuration.py,sha256=QOwQnWCfB-t_BQ2eOZN0SakurGUd0GTMCSdUlREhk6I,2324
|
344
344
|
zenml/integrations/kubernetes/orchestrators/manifest_utils.py,sha256=52Ba6MZ4lCo6CpnW0IjnFOJQNpPoVgbvIqR-x32ubew,16085
|
345
345
|
zenml/integrations/kubernetes/pod_settings.py,sha256=s6I0sALXB7PnRqJ-nlU71o3cTm2GM1TfqsE44qhiDJY,8022
|
@@ -618,7 +618,7 @@ zenml/model_deployers/__init__.py,sha256=oVBLtTfrNenl5OI1iqtQUvJ0vpocRVUN_HIt8qp
|
|
618
618
|
zenml/model_deployers/base_model_deployer.py,sha256=Z5-E_zC0Ss5OQhUBz9YKeVgS2MJOzuNz2aBzqI5eo4U,24610
|
619
619
|
zenml/model_registries/__init__.py,sha256=wA9Vzo0w_e9zuXOVURB9w8oMLSnTaimXcxg_Nb7O3b0,1238
|
620
620
|
zenml/model_registries/base_model_registry.py,sha256=NXviKlREKv56JJaS1skG0dXgP0YOzZJN7kTxqw-cw7U,17524
|
621
|
-
zenml/models/__init__.py,sha256=
|
621
|
+
zenml/models/__init__.py,sha256=I-5VZaOFp4-30q1kmOvIo6WUkl6iwkT_DGrvHZ8HtSk,24321
|
622
622
|
zenml/models/v2/__init__.py,sha256=LGMIUJi19sOsvo54roZSQwDp_czNQYtenqd_frTLIhU,613
|
623
623
|
zenml/models/v2/base/__init__.py,sha256=knhroJ2h0uHBCGzAiBBGJEiuhEA3cwI6XYBRIyXdbkQ,613
|
624
624
|
zenml/models/v2/base/base.py,sha256=Oz6iWCaJw1ykoYe2tTvGJqalGmDp0tRS9r1NpBx8WsM,16222
|
@@ -660,7 +660,7 @@ zenml/models/v2/core/service.py,sha256=PeI036PIVG0zX5EiYPsx7h5LTRC8hlmfdeClKff-I
|
|
660
660
|
zenml/models/v2/core/service_account.py,sha256=-1c9Et9Ma4_OHOZxIHjVnLJAaLLxhpoLEyGKkwc1Yx8,6619
|
661
661
|
zenml/models/v2/core/service_connector.py,sha256=V1zWxTpo9ABCxRfK327w7CV21n5XWaPHgIR6CE2zHNk,38628
|
662
662
|
zenml/models/v2/core/stack.py,sha256=3IKofEaKprAtYNbIrKvcYs5IABTbCqxcfJSXC3Q0fYM,13332
|
663
|
-
zenml/models/v2/core/step_run.py,sha256=
|
663
|
+
zenml/models/v2/core/step_run.py,sha256=KnwZMfqxPo0xJSoRv1pkdinze5nagBhcWKcCG6cyEt4,22531
|
664
664
|
zenml/models/v2/core/tag.py,sha256=60hCZuHAHy7lsYFkTDw7hK0zZz2eG7jx8l9VY7Hh-LQ,7100
|
665
665
|
zenml/models/v2/core/tag_resource.py,sha256=H7CPj9oaUpym8vSkwuYSJ6_rWfHMEKVRedPw2kyxmII,2640
|
666
666
|
zenml/models/v2/core/trigger.py,sha256=L6-pzWPM2HFsfA6-6rM1XeHx4UChZrIY58G6ZG1PA10,12782
|
@@ -669,6 +669,7 @@ zenml/models/v2/core/user.py,sha256=jw8HRKhZKJ3ljAbNMiFga-IV04zXhiRS33jLm13b8RA,
|
|
669
669
|
zenml/models/v2/misc/__init__.py,sha256=knhroJ2h0uHBCGzAiBBGJEiuhEA3cwI6XYBRIyXdbkQ,613
|
670
670
|
zenml/models/v2/misc/auth_models.py,sha256=j31CQt9qfH20tyCjY0depqbKP0YZEewcgGKrixqBUbg,3688
|
671
671
|
zenml/models/v2/misc/build_item.py,sha256=66Fywatv8bDY86pf0k530fsHTk_L4IkHL6uJL7-6dAo,1938
|
672
|
+
zenml/models/v2/misc/exception_info.py,sha256=CCTO7HYqsa3poi5hL4HK3ZS67xmkQNYQRHgLzqpUTHs,1016
|
672
673
|
zenml/models/v2/misc/external_user.py,sha256=_prXznyVA3Dc5pCK7nVE72K3tjxslG_e3JxIXLIikBo,944
|
673
674
|
zenml/models/v2/misc/info_models.py,sha256=3X6HFIlFcz5uuT7qgU18HqZBPkgrGZQ7QcM2yBT0qeU,2645
|
674
675
|
zenml/models/v2/misc/loaded_visualization.py,sha256=u6lapDNZDtU9eS-_EMzl00urj0yPNhiqhZcvjIz7DSg,946
|
@@ -692,10 +693,10 @@ zenml/orchestrators/local/local_orchestrator.py,sha256=KCzc901_wrb1DPTDu_IY6HFxT
|
|
692
693
|
zenml/orchestrators/local_docker/__init__.py,sha256=k8J68ydy6HmmvE9tWo32g761H8P_Dw4AxWNf4UMpsbs,669
|
693
694
|
zenml/orchestrators/local_docker/local_docker_orchestrator.py,sha256=dEc1R2_xzFIzvSwPirwtH2noYzPyw0gbdDhpsqAgFMM,10032
|
694
695
|
zenml/orchestrators/output_utils.py,sha256=01vqke1ZfmfuLpgxNerF-QL2wA0VPv1zUdvlMw0OwUY,3508
|
695
|
-
zenml/orchestrators/publish_utils.py,sha256=
|
696
|
-
zenml/orchestrators/step_launcher.py,sha256=
|
696
|
+
zenml/orchestrators/publish_utils.py,sha256=u0jk9Q57fLQE1QDJjrydy5KQ9xtYKUvn3CXBirDH2u8,8485
|
697
|
+
zenml/orchestrators/step_launcher.py,sha256=ipFy7-pGKSmAUySRuBPddSusQ5LaLS0g5t49UlU77YY,18841
|
697
698
|
zenml/orchestrators/step_run_utils.py,sha256=JXlYomV_PmC-cmjk7VWAGauKUXdijXU0ao8HBTZobmY,16802
|
698
|
-
zenml/orchestrators/step_runner.py,sha256=
|
699
|
+
zenml/orchestrators/step_runner.py,sha256=X3sX7f5NBYxT3utFGKcOJlkvCauYyEoo0LB2TB2Pp9U,27435
|
699
700
|
zenml/orchestrators/topsort.py,sha256=D8evz3X47zwpXd90NMLsJD-_uCeXtV6ClzNfDUrq7cM,5784
|
700
701
|
zenml/orchestrators/utils.py,sha256=6bqLc1fmdJTXg8JUwUKs8YNbmxTuMIfWmUbUpg-7hx0,12956
|
701
702
|
zenml/orchestrators/wheeled_orchestrator.py,sha256=eOnMcnd3sCzfhA2l6qRAzF0rOXzaojbjvvYvTkqixQo,4791
|
@@ -775,6 +776,7 @@ zenml/utils/docker_utils.py,sha256=occ364GUasOyiEipCcBHdK1WSvh1oVJIVnc-XXNsrcE,1
|
|
775
776
|
zenml/utils/downloaded_repository_context.py,sha256=GyPOzC8M3SaEGnnbPgEgJhUW-m5hx9rLScnCiGw6_PY,1504
|
776
777
|
zenml/utils/enum_utils.py,sha256=0fA0B9v9Wjutuqlu_owUoOit1utIw2UH5J6YHXSqhLU,1368
|
777
778
|
zenml/utils/env_utils.py,sha256=2--2DDUt3gPOvCNVyobBtAciikQ0OEXs5WWp7NvYuKo,5276
|
779
|
+
zenml/utils/exception_utils.py,sha256=7X--e7ERx2PYzhNwyhFMzKyriBpPPLybS5blpdZe1PE,2965
|
778
780
|
zenml/utils/filesync_model.py,sha256=9ibsIr2HJfkEQ41upQd4uJ79ZhzB0MHS85GOGOAQ19Y,5470
|
779
781
|
zenml/utils/function_utils.py,sha256=bznRrCrQIJ3Joc-QQ8ynDyn9AvyIcR61bzLnaXQV3tc,8109
|
780
782
|
zenml/utils/git_utils.py,sha256=O2f6PUpDuMQrcmkcGXIhbJQpTzLM7p8PyiKWjcIuWqM,1831
|
@@ -1288,6 +1290,7 @@ zenml/zen_stores/migrations/versions/cc9894cb58aa_add_user_metadata.py,sha256=68
|
|
1288
1290
|
zenml/zen_stores/migrations/versions/ccd68b7825ae_add_status_to_pipeline_and_step_run.py,sha256=MUvxaUyzcLtNOVgCgM6nBE3UTPKz5sVKsz-k071zCes,1824
|
1289
1291
|
zenml/zen_stores/migrations/versions/d02b3d3464cf_add_orchestrator_run_id_column.py,sha256=b5KNEC9vWdbWkiMRpPKJDK0xE1HiOdVJT_ab5kynA7M,1157
|
1290
1292
|
zenml/zen_stores/migrations/versions/d26471b6fe8f_update_build_filtering.py,sha256=VVDG2lhPzhejGm4Phzxw8sRCZd-vFXU4J3BtR96aRL0,1993
|
1293
|
+
zenml/zen_stores/migrations/versions/d4591f95ac07_step_exception_info.py,sha256=LAWlgcCgWpo4yz54JIm7ys_DdK8Jd0mOpyhUKsHNjf8,1198
|
1291
1294
|
zenml/zen_stores/migrations/versions/d7b3acf9aa46_create_schedule_table.py,sha256=ntxrMe__pAjvepVi0hznANE3tIHgrfJ1Ml4gtxmmSLU,3329
|
1292
1295
|
zenml/zen_stores/migrations/versions/e1d66d91a099_add_stack_and_component_spec_paths_to_.py,sha256=zAwzy9_n8s2WZ08vVyDG1WihowKpHDf-EOs9dbUmgPg,1543
|
1293
1296
|
zenml/zen_stores/migrations/versions/e5225281b4d3_add_connector_skew_tolerance.py,sha256=nR2h9X_cnbJ7OUwANJuzazhN90_anXF3YRABQPofqX0,1048
|
@@ -1330,7 +1333,7 @@ zenml/zen_stores/schemas/server_settings_schemas.py,sha256=usBE-idRrmK-LeLN0zDtC
|
|
1330
1333
|
zenml/zen_stores/schemas/service_connector_schemas.py,sha256=SpzFZTbfxypFtMLBujPSlGOpt-kzjcHfq3IoBghPizI,11137
|
1331
1334
|
zenml/zen_stores/schemas/service_schemas.py,sha256=Fn_DyGm-PF-qN1TPZA3Q8AhrnUOTSIX0V_MD0laZ2Bk,10685
|
1332
1335
|
zenml/zen_stores/schemas/stack_schemas.py,sha256=DOPoNwblTqN83RpnD6cjyF80VeplA1BGUX8yuulpzKk,6829
|
1333
|
-
zenml/zen_stores/schemas/step_run_schemas.py,sha256=
|
1336
|
+
zenml/zen_stores/schemas/step_run_schemas.py,sha256=lzisqMKUsKmzfl6AiagFlmVADOZowFvyZamltgjXxaE,20740
|
1334
1337
|
zenml/zen_stores/schemas/tag_schemas.py,sha256=pwQ5ogZovtkUuRtAkHakOfMh6ixw6qofvxB4i_Gd4qA,8352
|
1335
1338
|
zenml/zen_stores/schemas/trigger_schemas.py,sha256=LokauFEHdN5UuYeC2kf5PtJ60WMz-E82Ngcwxcv6tDA,11936
|
1336
1339
|
zenml/zen_stores/schemas/user_schemas.py,sha256=wLSHtfjjrYBWnX_PXv5KPz_DRdheTxZVjcgBe-cP__c,11497
|
@@ -1347,8 +1350,8 @@ zenml/zen_stores/secrets_stores/sql_secrets_store.py,sha256=LPFW757WCJLP1S8vrvjs
|
|
1347
1350
|
zenml/zen_stores/sql_zen_store.py,sha256=cXcKBBRKiwM2GtwHzmJb6tiN5NhGWo9n8SWnL1b4_WE,491150
|
1348
1351
|
zenml/zen_stores/template_utils.py,sha256=iCXrXpqzVTY7roqop4Eh9J7DmLW6PQeILZexmw_l3b8,10074
|
1349
1352
|
zenml/zen_stores/zen_store_interface.py,sha256=weiSULdI9AsbCE10a5TcwtybX-BJs9hKhjPJnTapWv4,93023
|
1350
|
-
zenml_nightly-0.84.0.
|
1351
|
-
zenml_nightly-0.84.0.
|
1352
|
-
zenml_nightly-0.84.0.
|
1353
|
-
zenml_nightly-0.84.0.
|
1354
|
-
zenml_nightly-0.84.0.
|
1353
|
+
zenml_nightly-0.84.0.dev20250729.dist-info/LICENSE,sha256=wbnfEnXnafPbqwANHkV6LUsPKOtdpsd-SNw37rogLtc,11359
|
1354
|
+
zenml_nightly-0.84.0.dev20250729.dist-info/METADATA,sha256=0K0W8CmHG1-krP1zg_a1s4uvVVAsJy2TjFAvCo-cG9k,24296
|
1355
|
+
zenml_nightly-0.84.0.dev20250729.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
1356
|
+
zenml_nightly-0.84.0.dev20250729.dist-info/entry_points.txt,sha256=QK3ETQE0YswAM2mWypNMOv8TLtr7EjnqAFq1br_jEFE,43
|
1357
|
+
zenml_nightly-0.84.0.dev20250729.dist-info/RECORD,,
|
{zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/LICENSE
RENAMED
File without changes
|
{zenml_nightly-0.84.0.dev20250727.dist-info → zenml_nightly-0.84.0.dev20250729.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|