zenml-nightly 0.73.0.dev20250123__py3-none-any.whl → 0.73.0.dev20250125__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/analytics/context.py +2 -6
- zenml/cli/annotator.py +1 -1
- zenml/cli/login.py +17 -6
- zenml/cli/server.py +1 -0
- zenml/cli/service_connectors.py +5 -5
- zenml/cli/stack.py +2 -2
- zenml/cli/utils.py +2 -54
- zenml/config/pipeline_configurations.py +3 -2
- zenml/config/schedule.py +0 -24
- zenml/enums.py +1 -0
- zenml/event_hub/base_event_hub.py +3 -4
- zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +3 -4
- zenml/integrations/aws/__init__.py +2 -1
- zenml/integrations/aws/flavors/sagemaker_orchestrator_flavor.py +15 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +310 -70
- zenml/integrations/aws/service_connectors/aws_service_connector.py +8 -13
- zenml/integrations/azure/service_connectors/azure_service_connector.py +4 -10
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +3 -3
- zenml/integrations/huggingface/__init__.py +1 -6
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +3 -3
- zenml/integrations/kubernetes/service_connectors/kubernetes_service_connector.py +6 -2
- zenml/integrations/whylogs/data_validators/whylogs_data_validator.py +2 -3
- zenml/logging/step_logging.py +7 -7
- zenml/login/credentials.py +6 -5
- zenml/login/credentials_store.py +4 -3
- zenml/models/v2/core/api_key.py +5 -2
- zenml/models/v2/core/schedule.py +19 -3
- zenml/orchestrators/publish_utils.py +4 -4
- zenml/orchestrators/step_launcher.py +3 -3
- zenml/orchestrators/step_run_utils.py +2 -2
- zenml/pipelines/run_utils.py +2 -2
- zenml/service_connectors/service_connector.py +7 -4
- zenml/stack/stack.py +5 -4
- zenml/stack/stack_component.py +10 -2
- zenml/stack_deployments/stack_deployment.py +2 -3
- zenml/utils/string_utils.py +2 -2
- zenml/utils/time_utils.py +138 -0
- zenml/zen_server/auth.py +8 -9
- zenml/zen_server/cloud_utils.py +4 -6
- zenml/zen_server/routers/devices_endpoints.py +2 -4
- zenml/zen_server/routers/workspaces_endpoints.py +2 -0
- zenml/zen_server/zen_server_api.py +9 -8
- zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +3 -2
- zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +3 -3
- zenml/zen_stores/migrations/versions/46506f72f0ed_add_server_settings.py +3 -2
- zenml/zen_stores/migrations/versions/5994f9ad0489_introduce_role_permissions.py +10 -7
- zenml/zen_stores/migrations/versions/7500f434b71c_remove_shared_columns.py +3 -2
- zenml/zen_stores/migrations/versions/a91762e6be36_artifact_version_table.py +5 -3
- zenml/zen_stores/schemas/action_schemas.py +2 -2
- zenml/zen_stores/schemas/api_key_schemas.py +5 -4
- zenml/zen_stores/schemas/artifact_schemas.py +3 -3
- zenml/zen_stores/schemas/base_schemas.py +5 -7
- zenml/zen_stores/schemas/code_repository_schemas.py +2 -2
- zenml/zen_stores/schemas/component_schemas.py +2 -2
- zenml/zen_stores/schemas/device_schemas.py +5 -4
- zenml/zen_stores/schemas/event_source_schemas.py +2 -2
- zenml/zen_stores/schemas/flavor_schemas.py +2 -2
- zenml/zen_stores/schemas/model_schemas.py +3 -3
- zenml/zen_stores/schemas/pipeline_run_schemas.py +11 -3
- zenml/zen_stores/schemas/pipeline_schemas.py +2 -2
- zenml/zen_stores/schemas/run_template_schemas.py +2 -2
- zenml/zen_stores/schemas/schedule_schema.py +20 -4
- zenml/zen_stores/schemas/secret_schemas.py +2 -2
- zenml/zen_stores/schemas/server_settings_schemas.py +6 -9
- zenml/zen_stores/schemas/service_connector_schemas.py +3 -2
- zenml/zen_stores/schemas/service_schemas.py +2 -2
- zenml/zen_stores/schemas/stack_schemas.py +2 -2
- zenml/zen_stores/schemas/step_run_schemas.py +3 -2
- zenml/zen_stores/schemas/tag_schemas.py +2 -2
- zenml/zen_stores/schemas/trigger_schemas.py +2 -2
- zenml/zen_stores/schemas/user_schemas.py +3 -3
- zenml/zen_stores/schemas/workspace_schemas.py +2 -2
- zenml/zen_stores/sql_zen_store.py +6 -14
- {zenml_nightly-0.73.0.dev20250123.dist-info → zenml_nightly-0.73.0.dev20250125.dist-info}/METADATA +2 -2
- {zenml_nightly-0.73.0.dev20250123.dist-info → zenml_nightly-0.73.0.dev20250125.dist-info}/RECORD +79 -78
- {zenml_nightly-0.73.0.dev20250123.dist-info → zenml_nightly-0.73.0.dev20250125.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.73.0.dev20250123.dist-info → zenml_nightly-0.73.0.dev20250125.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.73.0.dev20250123.dist-info → zenml_nightly-0.73.0.dev20250125.dist-info}/entry_points.txt +0 -0
@@ -31,7 +31,6 @@ Internal interface: no backwards compatibility guarantees.
|
|
31
31
|
Adjusted from https://github.com/tensorflow/tfx/blob/master/tfx/utils/kube_utils.py.
|
32
32
|
"""
|
33
33
|
|
34
|
-
import datetime
|
35
34
|
import enum
|
36
35
|
import re
|
37
36
|
import time
|
@@ -47,6 +46,7 @@ from zenml.integrations.kubernetes.orchestrators.manifest_utils import (
|
|
47
46
|
build_service_account_manifest,
|
48
47
|
)
|
49
48
|
from zenml.logger import get_logger
|
49
|
+
from zenml.utils.time_utils import utc_now
|
50
50
|
|
51
51
|
logger = get_logger(__name__)
|
52
52
|
|
@@ -248,7 +248,7 @@ def wait_pod(
|
|
248
248
|
Returns:
|
249
249
|
The pod object which meets the exit condition.
|
250
250
|
"""
|
251
|
-
start_time =
|
251
|
+
start_time = utc_now()
|
252
252
|
|
253
253
|
# Link to exponential back-off algorithm used here:
|
254
254
|
# https://cloud.google.com/storage/docs/exponential-backoff
|
@@ -288,7 +288,7 @@ def wait_pod(
|
|
288
288
|
return resp
|
289
289
|
|
290
290
|
# Check if wait timed out.
|
291
|
-
elapse_time =
|
291
|
+
elapse_time = utc_now() - start_time
|
292
292
|
if elapse_time.seconds >= timeout_sec and timeout_sec != 0:
|
293
293
|
raise RuntimeError(
|
294
294
|
f"Waiting for pod `{namespace}:{pod_name}` timed out after "
|
@@ -504,13 +504,17 @@ class KubernetesServiceConnector(ServiceConnector):
|
|
504
504
|
).decode("utf-8")
|
505
505
|
if kube_config.ssl_ca_cert
|
506
506
|
else None,
|
507
|
-
cluster_name=kube_config.host.
|
507
|
+
cluster_name=kube_config.host.removeprefix("https://").split(
|
508
|
+
":"
|
509
|
+
)[0],
|
508
510
|
insecure=kube_config.verify_ssl is False,
|
509
511
|
)
|
510
512
|
else:
|
511
513
|
token: Optional[str] = None
|
512
514
|
if kube_config.api_key:
|
513
|
-
token = kube_config.api_key["authorization"].
|
515
|
+
token = kube_config.api_key["authorization"].removeprefix(
|
516
|
+
"Bearer "
|
517
|
+
)
|
514
518
|
|
515
519
|
auth_method = KubernetesAuthenticationMethods.TOKEN
|
516
520
|
auth_config = KubernetesTokenConfig(
|
@@ -34,6 +34,7 @@ from zenml.integrations.whylogs.secret_schemas.whylabs_secret_schema import (
|
|
34
34
|
)
|
35
35
|
from zenml.logger import get_logger
|
36
36
|
from zenml.stack.authentication_mixin import AuthenticationMixin
|
37
|
+
from zenml.utils.time_utils import utc_now
|
37
38
|
|
38
39
|
logger = get_logger(__name__)
|
39
40
|
|
@@ -97,9 +98,7 @@ class WhylogsDataValidator(BaseDataValidator, AuthenticationMixin):
|
|
97
98
|
"""
|
98
99
|
results = why.log(pandas=dataset)
|
99
100
|
profile = results.profile()
|
100
|
-
dataset_timestamp = dataset_timestamp or
|
101
|
-
datetime.timezone.utc
|
102
|
-
)
|
101
|
+
dataset_timestamp = dataset_timestamp or utc_now()
|
103
102
|
profile.set_dataset_timestamp(dataset_timestamp=dataset_timestamp)
|
104
103
|
return profile.view()
|
105
104
|
|
zenml/logging/step_logging.py
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""ZenML logging handler."""
|
15
15
|
|
16
|
-
import datetime
|
17
16
|
import os
|
18
17
|
import re
|
19
18
|
import sys
|
@@ -35,6 +34,7 @@ from zenml.logging import (
|
|
35
34
|
STEP_LOGS_STORAGE_MAX_MESSAGES,
|
36
35
|
STEP_LOGS_STORAGE_MERGE_INTERVAL_SECONDS,
|
37
36
|
)
|
37
|
+
from zenml.utils.time_utils import utc_now
|
38
38
|
from zenml.zen_stores.base_zen_store import BaseZenStore
|
39
39
|
|
40
40
|
# Get the logger
|
@@ -303,9 +303,9 @@ class StepLogsStorage:
|
|
303
303
|
"w",
|
304
304
|
) as file:
|
305
305
|
for message in self.buffer:
|
306
|
-
timestamp =
|
307
|
-
|
308
|
-
)
|
306
|
+
timestamp = utc_now().strftime(
|
307
|
+
"%Y-%m-%d %H:%M:%S"
|
308
|
+
)
|
309
309
|
file.write(
|
310
310
|
f"[{timestamp} UTC] {remove_ansi_escape_codes(message)}\n"
|
311
311
|
)
|
@@ -314,9 +314,9 @@ class StepLogsStorage:
|
|
314
314
|
self.logs_uri, "a"
|
315
315
|
) as file:
|
316
316
|
for message in self.buffer:
|
317
|
-
timestamp =
|
318
|
-
|
319
|
-
)
|
317
|
+
timestamp = utc_now().strftime(
|
318
|
+
"%Y-%m-%d %H:%M:%S"
|
319
|
+
)
|
320
320
|
file.write(
|
321
321
|
f"[{timestamp} UTC] {remove_ansi_escape_codes(message)}\n"
|
322
322
|
)
|
zenml/login/credentials.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""ZenML login credentials models."""
|
15
15
|
|
16
|
-
from datetime import datetime, timedelta
|
16
|
+
from datetime import datetime, timedelta
|
17
17
|
from typing import Any, Dict, Optional, Union
|
18
18
|
from urllib.parse import urlparse
|
19
19
|
from uuid import UUID
|
@@ -27,6 +27,7 @@ from zenml.models.v2.misc.server_models import ServerDeploymentType
|
|
27
27
|
from zenml.services.service_status import ServiceState
|
28
28
|
from zenml.utils.enum_utils import StrEnum
|
29
29
|
from zenml.utils.string_utils import get_human_readable_time
|
30
|
+
from zenml.utils.time_utils import to_local_tz, utc_now
|
30
31
|
|
31
32
|
|
32
33
|
class ServerType(StrEnum):
|
@@ -71,7 +72,7 @@ class APIToken(BaseModel):
|
|
71
72
|
expires_at = self.expires_at_with_leeway
|
72
73
|
if not expires_at:
|
73
74
|
return False
|
74
|
-
return expires_at <
|
75
|
+
return expires_at < utc_now(tz_aware=expires_at)
|
75
76
|
|
76
77
|
model_config = ConfigDict(
|
77
78
|
# Allow extra attributes to allow backwards compatibility
|
@@ -223,7 +224,7 @@ class ServerCredentials(BaseModel):
|
|
223
224
|
expires_at = self.api_token.expires_at_with_leeway
|
224
225
|
if not expires_at:
|
225
226
|
return "never expires"
|
226
|
-
if expires_at <
|
227
|
+
if expires_at < utc_now(tz_aware=expires_at):
|
227
228
|
return "expired at " + self.expires_at
|
228
229
|
|
229
230
|
return f"valid until {self.expires_at} (in {self.expires_in})"
|
@@ -242,7 +243,7 @@ class ServerCredentials(BaseModel):
|
|
242
243
|
return "never"
|
243
244
|
|
244
245
|
# Convert the date in the local timezone
|
245
|
-
local_expires_at = expires_at
|
246
|
+
local_expires_at = to_local_tz(expires_at)
|
246
247
|
return local_expires_at.strftime("%Y-%m-%d %H:%M:%S %Z")
|
247
248
|
|
248
249
|
@property
|
@@ -259,7 +260,7 @@ class ServerCredentials(BaseModel):
|
|
259
260
|
return "never"
|
260
261
|
|
261
262
|
# Get the time remaining until the token expires
|
262
|
-
expires_in = expires_at -
|
263
|
+
expires_in = expires_at - utc_now(tz_aware=expires_at)
|
263
264
|
return get_human_readable_time(expires_in.total_seconds())
|
264
265
|
|
265
266
|
@property
|
zenml/login/credentials_store.py
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
"""ZenML login credentials store support."""
|
15
15
|
|
16
16
|
import os
|
17
|
-
from datetime import
|
17
|
+
from datetime import timedelta
|
18
18
|
from typing import Dict, List, Optional, Tuple, Union, cast
|
19
19
|
|
20
20
|
from zenml.config.global_config import GlobalConfiguration
|
@@ -29,6 +29,7 @@ from zenml.login.pro.tenant.models import TenantRead
|
|
29
29
|
from zenml.models import OAuthTokenResponse, ServerModel
|
30
30
|
from zenml.utils import yaml_utils
|
31
31
|
from zenml.utils.singleton import SingletonMetaClass
|
32
|
+
from zenml.utils.time_utils import utc_now_tz_aware
|
32
33
|
|
33
34
|
logger = get_logger(__name__)
|
34
35
|
|
@@ -190,7 +191,7 @@ class CredentialsStore(metaclass=SingletonMetaClass):
|
|
190
191
|
not credential.api_token.expires_at
|
191
192
|
or credential.api_token.expires_at
|
192
193
|
+ timedelta(seconds=TOKEN_STORE_EVICTION_TIME)
|
193
|
-
>
|
194
|
+
> utc_now_tz_aware()
|
194
195
|
)
|
195
196
|
}
|
196
197
|
yaml_utils.write_yaml(credentials_file, credentials_store)
|
@@ -477,7 +478,7 @@ class CredentialsStore(metaclass=SingletonMetaClass):
|
|
477
478
|
"""
|
478
479
|
self.check_and_reload_from_file()
|
479
480
|
if token_response.expires_in:
|
480
|
-
expires_at =
|
481
|
+
expires_at = utc_now_tz_aware() + timedelta(
|
481
482
|
seconds=token_response.expires_in
|
482
483
|
)
|
483
484
|
# Best practice to calculate the leeway depending on the token
|
zenml/models/v2/core/api_key.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing API keys."""
|
15
15
|
|
16
|
-
from datetime import datetime, timedelta
|
16
|
+
from datetime import datetime, timedelta
|
17
17
|
from typing import TYPE_CHECKING, ClassVar, List, Optional, Type, Union
|
18
18
|
from uuid import UUID
|
19
19
|
|
@@ -35,6 +35,7 @@ from zenml.models.v2.base.base import (
|
|
35
35
|
)
|
36
36
|
from zenml.models.v2.base.filter import AnyQuery, BaseFilter
|
37
37
|
from zenml.utils.string_utils import b64_decode, b64_encode
|
38
|
+
from zenml.utils.time_utils import utc_now
|
38
39
|
|
39
40
|
if TYPE_CHECKING:
|
40
41
|
from zenml.models.v2.base.filter import AnySchema
|
@@ -319,7 +320,9 @@ class APIKeyInternalResponse(APIKeyResponse):
|
|
319
320
|
and self.retain_period_minutes > 0
|
320
321
|
):
|
321
322
|
# check if the previous key is still valid
|
322
|
-
if
|
323
|
+
if utc_now(
|
324
|
+
tz_aware=self.last_rotated
|
325
|
+
) - self.last_rotated < timedelta(
|
323
326
|
minutes=self.retain_period_minutes
|
324
327
|
):
|
325
328
|
key_hash = self.previous_key
|
zenml/models/v2/core/schedule.py
CHANGED
@@ -14,13 +14,14 @@
|
|
14
14
|
"""Models representing schedules."""
|
15
15
|
|
16
16
|
import datetime
|
17
|
-
from typing import Optional, Union
|
17
|
+
from typing import Dict, Optional, Union
|
18
18
|
from uuid import UUID
|
19
19
|
|
20
20
|
from pydantic import Field, model_validator
|
21
21
|
|
22
22
|
from zenml.constants import STR_FIELD_MAX_LENGTH
|
23
23
|
from zenml.logger import get_logger
|
24
|
+
from zenml.metadata.metadata_types import MetadataType
|
24
25
|
from zenml.models.v2.base.base import BaseUpdate
|
25
26
|
from zenml.models.v2.base.scoped import (
|
26
27
|
WorkspaceScopedFilter,
|
@@ -30,6 +31,7 @@ from zenml.models.v2.base.scoped import (
|
|
30
31
|
WorkspaceScopedResponseMetadata,
|
31
32
|
WorkspaceScopedResponseResources,
|
32
33
|
)
|
34
|
+
from zenml.utils.time_utils import to_utc_timezone
|
33
35
|
|
34
36
|
logger = get_logger(__name__)
|
35
37
|
|
@@ -136,6 +138,11 @@ class ScheduleResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
136
138
|
orchestrator_id: Optional[UUID]
|
137
139
|
pipeline_id: Optional[UUID]
|
138
140
|
|
141
|
+
run_metadata: Dict[str, MetadataType] = Field(
|
142
|
+
title="Metadata associated with this schedule.",
|
143
|
+
default={},
|
144
|
+
)
|
145
|
+
|
139
146
|
|
140
147
|
class ScheduleResponseResources(WorkspaceScopedResponseResources):
|
141
148
|
"""Class for all resource models associated with the schedule entity."""
|
@@ -176,7 +183,7 @@ class ScheduleResponse(
|
|
176
183
|
if not self.start_time:
|
177
184
|
return None
|
178
185
|
|
179
|
-
return self.start_time
|
186
|
+
return to_utc_timezone(self.start_time).isoformat()
|
180
187
|
|
181
188
|
@property
|
182
189
|
def utc_end_time(self) -> Optional[str]:
|
@@ -188,7 +195,7 @@ class ScheduleResponse(
|
|
188
195
|
if not self.end_time:
|
189
196
|
return None
|
190
197
|
|
191
|
-
return self.end_time
|
198
|
+
return to_utc_timezone(self.end_time).isoformat()
|
192
199
|
|
193
200
|
# Body and metadata properties
|
194
201
|
@property
|
@@ -272,6 +279,15 @@ class ScheduleResponse(
|
|
272
279
|
"""
|
273
280
|
return self.get_metadata().pipeline_id
|
274
281
|
|
282
|
+
@property
|
283
|
+
def run_metadata(self) -> Dict[str, MetadataType]:
|
284
|
+
"""The `run_metadata` property.
|
285
|
+
|
286
|
+
Returns:
|
287
|
+
the value of the property.
|
288
|
+
"""
|
289
|
+
return self.get_metadata().run_metadata
|
290
|
+
|
275
291
|
|
276
292
|
# ------------------ Filter Model ------------------
|
277
293
|
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Utilities to publish pipeline and step runs."""
|
15
15
|
|
16
|
-
from datetime import datetime, timezone
|
17
16
|
from typing import TYPE_CHECKING, Dict, List
|
18
17
|
|
19
18
|
from zenml.client import Client
|
@@ -25,6 +24,7 @@ from zenml.models import (
|
|
25
24
|
StepRunResponse,
|
26
25
|
StepRunUpdate,
|
27
26
|
)
|
27
|
+
from zenml.utils.time_utils import utc_now
|
28
28
|
|
29
29
|
if TYPE_CHECKING:
|
30
30
|
from uuid import UUID
|
@@ -48,7 +48,7 @@ def publish_successful_step_run(
|
|
48
48
|
step_run_id=step_run_id,
|
49
49
|
step_run_update=StepRunUpdate(
|
50
50
|
status=ExecutionStatus.COMPLETED,
|
51
|
-
end_time=
|
51
|
+
end_time=utc_now(),
|
52
52
|
outputs=output_artifact_ids,
|
53
53
|
),
|
54
54
|
)
|
@@ -67,7 +67,7 @@ def publish_failed_step_run(step_run_id: "UUID") -> "StepRunResponse":
|
|
67
67
|
step_run_id=step_run_id,
|
68
68
|
step_run_update=StepRunUpdate(
|
69
69
|
status=ExecutionStatus.FAILED,
|
70
|
-
end_time=
|
70
|
+
end_time=utc_now(),
|
71
71
|
),
|
72
72
|
)
|
73
73
|
|
@@ -87,7 +87,7 @@ def publish_failed_pipeline_run(
|
|
87
87
|
run_id=pipeline_run_id,
|
88
88
|
run_update=PipelineRunUpdate(
|
89
89
|
status=ExecutionStatus.FAILED,
|
90
|
-
end_time=
|
90
|
+
end_time=utc_now(),
|
91
91
|
),
|
92
92
|
)
|
93
93
|
|
@@ -16,7 +16,6 @@
|
|
16
16
|
import os
|
17
17
|
import time
|
18
18
|
from contextlib import nullcontext
|
19
|
-
from datetime import datetime, timezone
|
20
19
|
from functools import partial
|
21
20
|
from typing import TYPE_CHECKING, Any, Callable, Dict, Tuple
|
22
21
|
|
@@ -45,6 +44,7 @@ from zenml.orchestrators import utils as orchestrator_utils
|
|
45
44
|
from zenml.orchestrators.step_runner import StepRunner
|
46
45
|
from zenml.stack import Stack
|
47
46
|
from zenml.utils import string_utils
|
47
|
+
from zenml.utils.time_utils import utc_now
|
48
48
|
|
49
49
|
if TYPE_CHECKING:
|
50
50
|
from zenml.step_operators import BaseStepOperator
|
@@ -201,7 +201,7 @@ class StepLauncher:
|
|
201
201
|
f"Failed preparing step `{self._step_name}`."
|
202
202
|
)
|
203
203
|
step_run_request.status = ExecutionStatus.FAILED
|
204
|
-
step_run_request.end_time =
|
204
|
+
step_run_request.end_time = utc_now()
|
205
205
|
raise
|
206
206
|
finally:
|
207
207
|
step_run = Client().zen_store.create_run_step(
|
@@ -305,7 +305,7 @@ class StepLauncher:
|
|
305
305
|
The created or existing pipeline run,
|
306
306
|
and a boolean indicating whether the run was created or reused.
|
307
307
|
"""
|
308
|
-
start_time =
|
308
|
+
start_time = utc_now()
|
309
309
|
run_name = string_utils.format_name_template(
|
310
310
|
name_template=self._deployment.run_name_template,
|
311
311
|
substitutions=self._deployment.pipeline_configuration._get_full_substitutions(
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Utilities for creating step runs."""
|
15
15
|
|
16
|
-
from datetime import datetime, timezone
|
17
16
|
from typing import Dict, List, Optional, Set, Tuple
|
18
17
|
|
19
18
|
from zenml.client import Client
|
@@ -31,6 +30,7 @@ from zenml.models import (
|
|
31
30
|
)
|
32
31
|
from zenml.orchestrators import cache_utils, input_utils, utils
|
33
32
|
from zenml.stack import Stack
|
33
|
+
from zenml.utils.time_utils import utc_now
|
34
34
|
|
35
35
|
logger = get_logger(__name__)
|
36
36
|
|
@@ -75,7 +75,7 @@ class StepRunRequestFactory:
|
|
75
75
|
pipeline_run_id=self.pipeline_run.id,
|
76
76
|
deployment=self.deployment.id,
|
77
77
|
status=ExecutionStatus.RUNNING,
|
78
|
-
start_time=
|
78
|
+
start_time=utc_now(),
|
79
79
|
user=Client().active_user.id,
|
80
80
|
workspace=Client().active_workspace.id,
|
81
81
|
)
|
zenml/pipelines/run_utils.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
"""Utility functions for running pipelines."""
|
2
2
|
|
3
3
|
import time
|
4
|
-
from datetime import datetime, timezone
|
5
4
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Union
|
6
5
|
from uuid import UUID
|
7
6
|
|
@@ -25,6 +24,7 @@ from zenml.models import (
|
|
25
24
|
from zenml.orchestrators.publish_utils import publish_failed_pipeline_run
|
26
25
|
from zenml.stack import Flavor, Stack
|
27
26
|
from zenml.utils import code_utils, notebook_utils, source_utils, string_utils
|
27
|
+
from zenml.utils.time_utils import utc_now
|
28
28
|
from zenml.zen_stores.base_zen_store import BaseZenStore
|
29
29
|
|
30
30
|
if TYPE_CHECKING:
|
@@ -65,7 +65,7 @@ def create_placeholder_run(
|
|
65
65
|
|
66
66
|
if deployment.schedule:
|
67
67
|
return None
|
68
|
-
start_time =
|
68
|
+
start_time = utc_now()
|
69
69
|
run_request = PipelineRunRequest(
|
70
70
|
name=string_utils.format_name_template(
|
71
71
|
name_template=deployment.run_name_template,
|
@@ -55,6 +55,7 @@ from zenml.models import (
|
|
55
55
|
UserResponse,
|
56
56
|
WorkspaceResponse,
|
57
57
|
)
|
58
|
+
from zenml.utils.time_utils import utc_now
|
58
59
|
|
59
60
|
logger = get_logger(__name__)
|
60
61
|
|
@@ -794,13 +795,14 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
|
|
794
795
|
"connector configuration is not valid: name and ID must be set"
|
795
796
|
)
|
796
797
|
|
798
|
+
now = utc_now()
|
797
799
|
model = ServiceConnectorResponse(
|
798
800
|
id=id,
|
799
801
|
name=name,
|
800
802
|
body=ServiceConnectorResponseBody(
|
801
803
|
user=user,
|
802
|
-
created=
|
803
|
-
updated=
|
804
|
+
created=now,
|
805
|
+
updated=now,
|
804
806
|
description=description,
|
805
807
|
connector_type=self.get_type(),
|
806
808
|
auth_method=self.auth_method,
|
@@ -845,14 +847,15 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
|
|
845
847
|
if self.expires_skew_tolerance is not None
|
846
848
|
else SERVICE_CONNECTOR_SKEW_TOLERANCE_SECONDS
|
847
849
|
)
|
848
|
-
|
850
|
+
now = utc_now(tz_aware=expires_at)
|
851
|
+
delta = expires_at - now
|
849
852
|
result = delta < timedelta(seconds=0)
|
850
853
|
|
851
854
|
logger.debug(
|
852
855
|
f"Checking if connector {self.name} has expired.\n"
|
853
856
|
f"Expires at: {self.expires_at}\n"
|
854
857
|
f"Expires at (+skew): {expires_at}\n"
|
855
|
-
f"Current UTC time: {
|
858
|
+
f"Current UTC time: {now}\n"
|
856
859
|
f"Delta: {delta}\n"
|
857
860
|
f"Result: {result}\n"
|
858
861
|
)
|
zenml/stack/stack.py
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
import itertools
|
17
17
|
import json
|
18
18
|
import os
|
19
|
-
from datetime import datetime
|
19
|
+
from datetime import datetime
|
20
20
|
from typing import (
|
21
21
|
TYPE_CHECKING,
|
22
22
|
AbstractSet,
|
@@ -45,6 +45,7 @@ from zenml.logger import get_logger
|
|
45
45
|
from zenml.metadata.metadata_types import MetadataType
|
46
46
|
from zenml.models import StackResponse
|
47
47
|
from zenml.utils import pagination_utils, settings_utils
|
48
|
+
from zenml.utils.time_utils import utc_now
|
48
49
|
|
49
50
|
if TYPE_CHECKING:
|
50
51
|
from zenml.alerter import BaseAlerter
|
@@ -732,7 +733,6 @@ class Stack:
|
|
732
733
|
and not skip_default_image_builder
|
733
734
|
and not self.image_builder
|
734
735
|
):
|
735
|
-
from datetime import datetime
|
736
736
|
from uuid import uuid4
|
737
737
|
|
738
738
|
from zenml.image_builders import (
|
@@ -743,6 +743,7 @@ class Stack:
|
|
743
743
|
|
744
744
|
flavor = LocalImageBuilderFlavor()
|
745
745
|
|
746
|
+
now = utc_now()
|
746
747
|
image_builder = LocalImageBuilder(
|
747
748
|
id=uuid4(),
|
748
749
|
name="temporary_default",
|
@@ -751,8 +752,8 @@ class Stack:
|
|
751
752
|
config=LocalImageBuilderConfig(),
|
752
753
|
user=Client().active_user.id,
|
753
754
|
workspace=Client().active_workspace.id,
|
754
|
-
created=
|
755
|
-
updated=
|
755
|
+
created=now,
|
756
|
+
updated=now,
|
756
757
|
)
|
757
758
|
|
758
759
|
self._image_builder = image_builder
|
zenml/stack/stack_component.py
CHANGED
@@ -29,7 +29,11 @@ from zenml.config.step_run_info import StepRunInfo
|
|
29
29
|
from zenml.enums import StackComponentType
|
30
30
|
from zenml.exceptions import AuthorizationException
|
31
31
|
from zenml.logger import get_logger
|
32
|
-
from zenml.models import
|
32
|
+
from zenml.models import (
|
33
|
+
PipelineRunResponse,
|
34
|
+
ServiceConnectorRequirements,
|
35
|
+
StepRunResponse,
|
36
|
+
)
|
33
37
|
from zenml.utils import (
|
34
38
|
pydantic_utils,
|
35
39
|
secret_utils,
|
@@ -496,6 +500,7 @@ class StackComponent:
|
|
496
500
|
"StepRunInfo",
|
497
501
|
"PipelineDeploymentBase",
|
498
502
|
"PipelineDeploymentResponse",
|
503
|
+
"PipelineRunResponse",
|
499
504
|
],
|
500
505
|
) -> "BaseSettings":
|
501
506
|
"""Gets settings for this stack component.
|
@@ -527,7 +532,10 @@ class StackComponent:
|
|
527
532
|
|
528
533
|
all_settings = (
|
529
534
|
container.config.settings
|
530
|
-
if isinstance(
|
535
|
+
if isinstance(
|
536
|
+
container,
|
537
|
+
(Step, StepRunResponse, StepRunInfo, PipelineRunResponse),
|
538
|
+
)
|
531
539
|
else container.pipeline_configuration.settings
|
532
540
|
)
|
533
541
|
|
@@ -26,6 +26,7 @@ from zenml.models import (
|
|
26
26
|
StackDeploymentConfig,
|
27
27
|
StackDeploymentInfo,
|
28
28
|
)
|
29
|
+
from zenml.utils.time_utils import to_utc_timezone
|
29
30
|
|
30
31
|
STACK_DEPLOYMENT_TERRAFORM = "terraform"
|
31
32
|
|
@@ -199,9 +200,7 @@ class ZenMLCloudStackDeployment(BaseModel):
|
|
199
200
|
# Get all stacks created after the start date
|
200
201
|
|
201
202
|
if date_start and date_start.tzinfo:
|
202
|
-
date_start = date_start
|
203
|
-
tzinfo=None
|
204
|
-
)
|
203
|
+
date_start = to_utc_timezone(date_start).replace(tzinfo=None)
|
205
204
|
stacks = client.list_stacks(
|
206
205
|
created=f"gt:{str(date_start.replace(microsecond=0))}"
|
207
206
|
if date_start
|
zenml/utils/string_utils.py
CHANGED
@@ -17,12 +17,12 @@ import base64
|
|
17
17
|
import functools
|
18
18
|
import random
|
19
19
|
import string
|
20
|
-
from datetime import datetime, timezone
|
21
20
|
from typing import Any, Callable, Dict, Optional, TypeVar, cast
|
22
21
|
|
23
22
|
from pydantic import BaseModel
|
24
23
|
|
25
24
|
from zenml.constants import BANNED_NAME_CHARACTERS
|
25
|
+
from zenml.utils.time_utils import utc_now
|
26
26
|
|
27
27
|
V = TypeVar("V", bound=Any)
|
28
28
|
|
@@ -180,7 +180,7 @@ def format_name_template(
|
|
180
180
|
start_time = None
|
181
181
|
|
182
182
|
if start_time is None:
|
183
|
-
start_time =
|
183
|
+
start_time = utc_now()
|
184
184
|
substitutions.setdefault("date", start_time.strftime("%Y_%m_%d"))
|
185
185
|
substitutions.setdefault("time", start_time.strftime("%H_%M_%S_%f"))
|
186
186
|
|