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
@@ -0,0 +1,138 @@
|
|
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
|
+
"""Time utils."""
|
15
|
+
|
16
|
+
from datetime import datetime, timedelta, timezone
|
17
|
+
from typing import Optional, Union
|
18
|
+
|
19
|
+
|
20
|
+
def utc_now(tz_aware: Union[bool, datetime] = False) -> datetime:
|
21
|
+
"""Get the current time in the UTC timezone.
|
22
|
+
|
23
|
+
Args:
|
24
|
+
tz_aware: Use this flag to control whether the returned datetime is
|
25
|
+
timezone-aware or timezone-naive. If a datetime is provided, the
|
26
|
+
returned datetime will be timezone-aware if and only if the input
|
27
|
+
datetime is also timezone-aware.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
The current UTC time. If tz_aware is a datetime, the returned datetime
|
31
|
+
will be timezone-aware only if the input datetime is also timezone-aware.
|
32
|
+
If tz_aware is a boolean, the returned datetime will be timezone-aware
|
33
|
+
if True, and timezone-naive if False.
|
34
|
+
"""
|
35
|
+
now = datetime.now(timezone.utc)
|
36
|
+
if (
|
37
|
+
isinstance(tz_aware, bool)
|
38
|
+
and tz_aware is False
|
39
|
+
or isinstance(tz_aware, datetime)
|
40
|
+
and tz_aware.tzinfo is None
|
41
|
+
):
|
42
|
+
return now.replace(tzinfo=None)
|
43
|
+
|
44
|
+
return now
|
45
|
+
|
46
|
+
|
47
|
+
def utc_now_tz_aware() -> datetime:
|
48
|
+
"""Get the current timezone-aware UTC time.
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
The current UTC time.
|
52
|
+
"""
|
53
|
+
return utc_now(tz_aware=True)
|
54
|
+
|
55
|
+
|
56
|
+
def to_local_tz(dt: datetime) -> datetime:
|
57
|
+
"""Convert a datetime to the local timezone.
|
58
|
+
|
59
|
+
If the input datetime is timezone-naive, it will be assumed to be in the UTC
|
60
|
+
timezone.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
dt: datetime to convert.
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
Datetime in the local timezone.
|
67
|
+
"""
|
68
|
+
if dt.tzinfo is None:
|
69
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
70
|
+
return dt.astimezone()
|
71
|
+
|
72
|
+
|
73
|
+
def to_utc_timezone(dt: datetime) -> datetime:
|
74
|
+
"""Convert a datetime to the UTC timezone.
|
75
|
+
|
76
|
+
If the input datetime is timezone-naive, it will be assumed to be in the UTC
|
77
|
+
timezone.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
dt: datetime to convert.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
Datetime in the UTC timezone.
|
84
|
+
"""
|
85
|
+
if dt.tzinfo is None:
|
86
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
87
|
+
return dt.astimezone(timezone.utc)
|
88
|
+
|
89
|
+
|
90
|
+
def seconds_to_human_readable(time_seconds: int) -> str:
|
91
|
+
"""Converts seconds to human-readable format.
|
92
|
+
|
93
|
+
Args:
|
94
|
+
time_seconds: Seconds to convert.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
Human readable string.
|
98
|
+
"""
|
99
|
+
seconds = time_seconds % 60
|
100
|
+
minutes = (time_seconds // 60) % 60
|
101
|
+
hours = (time_seconds // 3600) % 24
|
102
|
+
days = time_seconds // 86400
|
103
|
+
tokens = []
|
104
|
+
if days:
|
105
|
+
tokens.append(f"{days}d")
|
106
|
+
if hours:
|
107
|
+
tokens.append(f"{hours}h")
|
108
|
+
if minutes:
|
109
|
+
tokens.append(f"{minutes}m")
|
110
|
+
if seconds:
|
111
|
+
tokens.append(f"{seconds}s")
|
112
|
+
|
113
|
+
return "".join(tokens)
|
114
|
+
|
115
|
+
|
116
|
+
def expires_in(
|
117
|
+
expires_at: datetime,
|
118
|
+
expired_str: str,
|
119
|
+
skew_tolerance: Optional[int] = None,
|
120
|
+
) -> str:
|
121
|
+
"""Returns a human-readable string of the time until an expiration.
|
122
|
+
|
123
|
+
Args:
|
124
|
+
expires_at: Expiration time.
|
125
|
+
expired_str: String to return if the expiration is in the past.
|
126
|
+
skew_tolerance: Seconds of skew tolerance to subtract from the
|
127
|
+
expiration time. If the expiration is within the skew tolerance,
|
128
|
+
the function will return the expired string.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
Human readable string.
|
132
|
+
"""
|
133
|
+
now = utc_now(tz_aware=expires_at)
|
134
|
+
if skew_tolerance:
|
135
|
+
expires_at -= timedelta(seconds=skew_tolerance)
|
136
|
+
if expires_at < now:
|
137
|
+
return expired_str
|
138
|
+
return seconds_to_human_readable(int((expires_at - now).total_seconds()))
|
zenml/zen_server/auth.py
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
"""Authentication module for ZenML server."""
|
15
15
|
|
16
16
|
from contextvars import ContextVar
|
17
|
-
from datetime import datetime, timedelta
|
17
|
+
from datetime import datetime, timedelta
|
18
18
|
from typing import Callable, Optional, Union
|
19
19
|
from urllib.parse import urlencode, urlparse
|
20
20
|
from uuid import UUID, uuid4
|
@@ -62,6 +62,7 @@ from zenml.models import (
|
|
62
62
|
UserResponse,
|
63
63
|
UserUpdate,
|
64
64
|
)
|
65
|
+
from zenml.utils.time_utils import utc_now
|
65
66
|
from zenml.zen_server.cache import cache_result
|
66
67
|
from zenml.zen_server.csrf import CSRFToken
|
67
68
|
from zenml.zen_server.exceptions import http_exception_from_error
|
@@ -350,7 +351,8 @@ def authenticate_credentials(
|
|
350
351
|
|
351
352
|
if (
|
352
353
|
device_model.expires
|
353
|
-
and
|
354
|
+
and utc_now(tz_aware=device_model.expires)
|
355
|
+
>= device_model.expires
|
354
356
|
):
|
355
357
|
error = (
|
356
358
|
f"Authentication error: device {decoded_token.device_id} "
|
@@ -589,7 +591,7 @@ def authenticate_device(client_id: UUID, device_code: str) -> AuthContext:
|
|
589
591
|
|
590
592
|
if (
|
591
593
|
device_model.expires
|
592
|
-
and
|
594
|
+
and utc_now(tz_aware=device_model.expires) >= device_model.expires
|
593
595
|
):
|
594
596
|
error = (
|
595
597
|
f"Authentication error: device for client ID {client_id} has "
|
@@ -892,21 +894,18 @@ def generate_access_token(
|
|
892
894
|
if expires_in == 0:
|
893
895
|
expires_in = None
|
894
896
|
elif expires_in is not None:
|
895
|
-
expires =
|
897
|
+
expires = utc_now() + timedelta(seconds=expires_in)
|
896
898
|
elif device:
|
897
899
|
# If a device was used for authentication, the token will expire
|
898
900
|
# at the same time as the device.
|
899
901
|
expires = device.expires
|
900
902
|
if expires:
|
901
903
|
expires_in = max(
|
902
|
-
int(
|
903
|
-
expires.timestamp()
|
904
|
-
- datetime.now(timezone.utc).timestamp()
|
905
|
-
),
|
904
|
+
int(expires.timestamp() - utc_now().timestamp()),
|
906
905
|
0,
|
907
906
|
)
|
908
907
|
elif config.jwt_token_expire_minutes:
|
909
|
-
expires =
|
908
|
+
expires = utc_now() + timedelta(
|
910
909
|
minutes=config.jwt_token_expire_minutes
|
911
910
|
)
|
912
911
|
expires_in = config.jwt_token_expire_minutes * 60
|
zenml/zen_server/cloud_utils.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Utils concerning anything concerning the cloud control plane backend."""
|
2
2
|
|
3
|
-
from datetime import datetime, timedelta
|
3
|
+
from datetime import datetime, timedelta
|
4
4
|
from typing import Any, Dict, Optional
|
5
5
|
|
6
6
|
import requests
|
@@ -8,6 +8,7 @@ from requests.adapters import HTTPAdapter, Retry
|
|
8
8
|
|
9
9
|
from zenml.config.server_config import ServerProConfiguration
|
10
10
|
from zenml.exceptions import SubscriptionUpgradeRequiredError
|
11
|
+
from zenml.utils.time_utils import utc_now
|
11
12
|
from zenml.zen_server.utils import get_zenml_headers, server_config
|
12
13
|
|
13
14
|
_cloud_connection: Optional["ZenMLCloudConnection"] = None
|
@@ -185,8 +186,7 @@ class ZenMLCloudConnection:
|
|
185
186
|
if (
|
186
187
|
self._token is not None
|
187
188
|
and self._token_expires_at is not None
|
188
|
-
and
|
189
|
-
< self._token_expires_at
|
189
|
+
and utc_now() + timedelta(minutes=5) < self._token_expires_at
|
190
190
|
):
|
191
191
|
return self._token
|
192
192
|
|
@@ -227,9 +227,7 @@ class ZenMLCloudConnection:
|
|
227
227
|
)
|
228
228
|
|
229
229
|
self._token = access_token
|
230
|
-
self._token_expires_at =
|
231
|
-
seconds=expires_in
|
232
|
-
)
|
230
|
+
self._token_expires_at = utc_now() + timedelta(seconds=expires_in)
|
233
231
|
|
234
232
|
assert self._token is not None
|
235
233
|
return self._token
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for code repositories."""
|
15
15
|
|
16
|
-
from datetime import datetime, timezone
|
17
16
|
from typing import Optional
|
18
17
|
from uuid import UUID
|
19
18
|
|
@@ -36,6 +35,7 @@ from zenml.models import (
|
|
36
35
|
OAuthDeviceVerificationRequest,
|
37
36
|
Page,
|
38
37
|
)
|
38
|
+
from zenml.utils.time_utils import utc_now
|
39
39
|
from zenml.zen_server.auth import AuthContext, authorize
|
40
40
|
from zenml.zen_server.exceptions import error_response
|
41
41
|
from zenml.zen_server.utils import (
|
@@ -219,9 +219,7 @@ def verify_authorized_device(
|
|
219
219
|
)
|
220
220
|
|
221
221
|
# Check if the device verification has expired.
|
222
|
-
if device_model.expires and device_model.expires <
|
223
|
-
timezone.utc
|
224
|
-
):
|
222
|
+
if device_model.expires and device_model.expires < utc_now():
|
225
223
|
raise ValueError(
|
226
224
|
"Invalid request: device verification expired.",
|
227
225
|
)
|
@@ -1009,6 +1009,8 @@ def create_run_metadata(
|
|
1009
1009
|
verify_models.append(zen_store().get_artifact_version(resource.id))
|
1010
1010
|
elif resource.type == MetadataResourceTypes.MODEL_VERSION:
|
1011
1011
|
verify_models.append(zen_store().get_model_version(resource.id))
|
1012
|
+
elif resource.type == MetadataResourceTypes.SCHEDULE:
|
1013
|
+
verify_models.append(zen_store().get_schedule(resource.id))
|
1012
1014
|
else:
|
1013
1015
|
raise RuntimeError(f"Unknown resource type: {resource.type}")
|
1014
1016
|
|
@@ -22,7 +22,7 @@ To run this file locally, execute:
|
|
22
22
|
|
23
23
|
import os
|
24
24
|
from asyncio.log import logger
|
25
|
-
from datetime import datetime, timedelta
|
25
|
+
from datetime import datetime, timedelta
|
26
26
|
from genericpath import isfile
|
27
27
|
from typing import Any, List, Set
|
28
28
|
|
@@ -54,6 +54,7 @@ from zenml.constants import (
|
|
54
54
|
)
|
55
55
|
from zenml.enums import AuthScheme, SourceContextTypes
|
56
56
|
from zenml.models import ServerDeploymentType
|
57
|
+
from zenml.utils.time_utils import utc_now
|
57
58
|
from zenml.zen_server.cloud_utils import send_pro_tenant_status_update
|
58
59
|
from zenml.zen_server.exceptions import error_detail
|
59
60
|
from zenml.zen_server.routers import (
|
@@ -129,8 +130,8 @@ app = FastAPI(
|
|
129
130
|
)
|
130
131
|
|
131
132
|
# Initialize last_user_activity
|
132
|
-
last_user_activity: datetime =
|
133
|
-
last_user_activity_reported: datetime =
|
133
|
+
last_user_activity: datetime = utc_now()
|
134
|
+
last_user_activity_reported: datetime = last_user_activity + timedelta(
|
134
135
|
seconds=-DEFAULT_ZENML_SERVER_REPORT_USER_ACTIVITY_TO_DB_SECONDS
|
135
136
|
)
|
136
137
|
|
@@ -306,20 +307,20 @@ async def track_last_user_activity(request: Request, call_next: Any) -> Any:
|
|
306
307
|
global last_user_activity
|
307
308
|
global last_user_activity_reported
|
308
309
|
|
310
|
+
now = utc_now()
|
311
|
+
|
309
312
|
try:
|
310
313
|
if is_user_request(request):
|
311
|
-
last_user_activity =
|
314
|
+
last_user_activity = now
|
312
315
|
except Exception as e:
|
313
316
|
logger.debug(
|
314
317
|
f"An unexpected error occurred while checking user activity: {e}"
|
315
318
|
)
|
316
319
|
if (
|
317
|
-
(
|
318
|
-
datetime.now(timezone.utc) - last_user_activity_reported
|
319
|
-
).total_seconds()
|
320
|
+
(now - last_user_activity_reported).total_seconds()
|
320
321
|
> DEFAULT_ZENML_SERVER_REPORT_USER_ACTIVITY_TO_DB_SECONDS
|
321
322
|
):
|
322
|
-
last_user_activity_reported =
|
323
|
+
last_user_activity_reported = now
|
323
324
|
zen_store()._update_last_user_activity_timestamp(
|
324
325
|
last_user_activity=last_user_activity
|
325
326
|
)
|
@@ -6,13 +6,14 @@ Create Date: 2024-05-16 11:29:53.341275
|
|
6
6
|
|
7
7
|
"""
|
8
8
|
|
9
|
-
from datetime import datetime, timezone
|
10
9
|
from uuid import uuid4
|
11
10
|
|
12
11
|
import sqlalchemy as sa
|
13
12
|
import sqlmodel
|
14
13
|
from alembic import op
|
15
14
|
|
15
|
+
from zenml.utils.time_utils import utc_now
|
16
|
+
|
16
17
|
# revision identifiers, used by Alembic.
|
17
18
|
revision = "25155145c545"
|
18
19
|
down_revision = "0.58.2"
|
@@ -42,7 +43,7 @@ def migrate_actions() -> None:
|
|
42
43
|
)
|
43
44
|
).fetchall()
|
44
45
|
|
45
|
-
now =
|
46
|
+
now = utc_now()
|
46
47
|
|
47
48
|
actions_to_insert = []
|
48
49
|
trigger_updates = {}
|
@@ -6,12 +6,12 @@ Create Date: 2024-08-07 14:49:07.623500
|
|
6
6
|
|
7
7
|
"""
|
8
8
|
|
9
|
-
from datetime import datetime, timezone
|
10
|
-
|
11
9
|
import sqlalchemy as sa
|
12
10
|
import sqlmodel
|
13
11
|
from alembic import op
|
14
12
|
|
13
|
+
from zenml.utils.time_utils import utc_now
|
14
|
+
|
15
15
|
# revision identifiers, used by Alembic.
|
16
16
|
revision = "3dcc5d20e82f"
|
17
17
|
down_revision = "026d4577b6a0"
|
@@ -36,7 +36,7 @@ def upgrade() -> None:
|
|
36
36
|
SET last_user_activity = :last_user_activity
|
37
37
|
"""
|
38
38
|
),
|
39
|
-
params=(dict(last_user_activity=
|
39
|
+
params=(dict(last_user_activity=utc_now())),
|
40
40
|
)
|
41
41
|
|
42
42
|
with op.batch_alter_table("server_settings", schema=None) as batch_op:
|
@@ -6,13 +6,14 @@ Create Date: 2024-04-17 14:17:08.142652
|
|
6
6
|
|
7
7
|
"""
|
8
8
|
|
9
|
-
from datetime import datetime, timezone
|
10
9
|
from uuid import UUID
|
11
10
|
|
12
11
|
import sqlalchemy as sa
|
13
12
|
import sqlmodel
|
14
13
|
from alembic import op
|
15
14
|
|
15
|
+
from zenml.utils.time_utils import utc_now
|
16
|
+
|
16
17
|
# revision identifiers, used by Alembic.
|
17
18
|
revision = "46506f72f0ed"
|
18
19
|
down_revision = "cc9894cb58aa"
|
@@ -76,7 +77,7 @@ def upgrade() -> None:
|
|
76
77
|
"display_announcements": True,
|
77
78
|
"display_updates": True,
|
78
79
|
# Set the updated timestamp to the current time
|
79
|
-
"updated":
|
80
|
+
"updated": utc_now(),
|
80
81
|
},
|
81
82
|
],
|
82
83
|
)
|
@@ -6,7 +6,6 @@ Create Date: 2022-10-25 23:52:25.935344
|
|
6
6
|
|
7
7
|
"""
|
8
8
|
|
9
|
-
import datetime
|
10
9
|
import uuid
|
11
10
|
|
12
11
|
import sqlalchemy as sa
|
@@ -14,6 +13,8 @@ import sqlmodel
|
|
14
13
|
from alembic import op
|
15
14
|
from sqlalchemy import or_, select
|
16
15
|
|
16
|
+
from zenml.utils.time_utils import utc_now
|
17
|
+
|
17
18
|
# revision identifiers, used by Alembic.
|
18
19
|
revision = "5994f9ad0489"
|
19
20
|
down_revision = "0.21.1"
|
@@ -100,6 +101,7 @@ def upgrade() -> None:
|
|
100
101
|
guest_id = str(uuid.uuid4()).replace("-", "")
|
101
102
|
|
102
103
|
# Prefill the roles table with the admin and guest role
|
104
|
+
now = utc_now()
|
103
105
|
op.bulk_insert(
|
104
106
|
sa.Table(
|
105
107
|
"roleschema",
|
@@ -109,14 +111,14 @@ def upgrade() -> None:
|
|
109
111
|
{
|
110
112
|
"id": admin_id,
|
111
113
|
"name": "admin",
|
112
|
-
"created":
|
113
|
-
"updated":
|
114
|
+
"created": now,
|
115
|
+
"updated": now,
|
114
116
|
},
|
115
117
|
{
|
116
118
|
"id": guest_id,
|
117
119
|
"name": "guest",
|
118
|
-
"created":
|
119
|
-
"updated":
|
120
|
+
"created": now,
|
121
|
+
"updated": now,
|
120
122
|
},
|
121
123
|
],
|
122
124
|
)
|
@@ -148,6 +150,7 @@ def upgrade() -> None:
|
|
148
150
|
res = conn.execute(select(userschema.c.id)).fetchall()
|
149
151
|
user_ids = [i[0] for i in res]
|
150
152
|
|
153
|
+
now = utc_now()
|
151
154
|
for user_id in user_ids:
|
152
155
|
op.bulk_insert(
|
153
156
|
sa.Table(
|
@@ -159,8 +162,8 @@ def upgrade() -> None:
|
|
159
162
|
"id": str(uuid.uuid4()).replace("-", ""),
|
160
163
|
"role_id": admin_id,
|
161
164
|
"user_id": user_id,
|
162
|
-
"created":
|
163
|
-
"updated":
|
165
|
+
"created": now,
|
166
|
+
"updated": now,
|
164
167
|
}
|
165
168
|
],
|
166
169
|
)
|
@@ -8,13 +8,14 @@ Create Date: 2023-10-16 15:15:34.865337
|
|
8
8
|
|
9
9
|
import base64
|
10
10
|
from collections import defaultdict
|
11
|
-
from datetime import datetime, timezone
|
12
11
|
from typing import Dict, Optional, Set
|
13
12
|
from uuid import uuid4
|
14
13
|
|
15
14
|
import sqlalchemy as sa
|
16
15
|
from alembic import op
|
17
16
|
|
17
|
+
from zenml.utils.time_utils import utc_now
|
18
|
+
|
18
19
|
# revision identifiers, used by Alembic.
|
19
20
|
revision = "7500f434b71c"
|
20
21
|
down_revision = "14d687c8fa1c"
|
@@ -123,7 +124,7 @@ def resolve_duplicate_names() -> None:
|
|
123
124
|
_rename_duplicate_entities(service_connector_table)
|
124
125
|
|
125
126
|
workspace_query = sa.select(workspace_table.c.id)
|
126
|
-
utcnow =
|
127
|
+
utcnow = utc_now()
|
127
128
|
|
128
129
|
stack_components = []
|
129
130
|
stacks = []
|
@@ -6,13 +6,14 @@ Create Date: 2023-11-25 11:01:09.217299
|
|
6
6
|
|
7
7
|
"""
|
8
8
|
|
9
|
-
from datetime import datetime, timezone
|
10
9
|
from uuid import uuid4
|
11
10
|
|
12
11
|
import sqlalchemy as sa
|
13
12
|
import sqlmodel
|
14
13
|
from alembic import op
|
15
14
|
|
15
|
+
from zenml.utils.time_utils import utc_now
|
16
|
+
|
16
17
|
# revision identifiers, used by Alembic.
|
17
18
|
revision = "a91762e6be36"
|
18
19
|
down_revision = "0.50.0"
|
@@ -58,12 +59,13 @@ def upgrade() -> None:
|
|
58
59
|
unique_artifact_names = {
|
59
60
|
name: has_custom_name for name, has_custom_name in artifact_names
|
60
61
|
}
|
62
|
+
now = utc_now()
|
61
63
|
for name, has_custom_name in unique_artifact_names.items():
|
62
64
|
conn.execute(
|
63
65
|
artifacts.insert().values(
|
64
66
|
id=uuid4().hex,
|
65
|
-
created=
|
66
|
-
updated=
|
67
|
+
created=now,
|
68
|
+
updated=now,
|
67
69
|
name=name,
|
68
70
|
has_custom_name=has_custom_name,
|
69
71
|
)
|
@@ -15,7 +15,6 @@
|
|
15
15
|
|
16
16
|
import base64
|
17
17
|
import json
|
18
|
-
from datetime import datetime, timezone
|
19
18
|
from typing import TYPE_CHECKING, Any, List, Optional
|
20
19
|
from uuid import UUID
|
21
20
|
|
@@ -31,6 +30,7 @@ from zenml.models import (
|
|
31
30
|
ActionResponseResources,
|
32
31
|
ActionUpdate,
|
33
32
|
)
|
33
|
+
from zenml.utils.time_utils import utc_now
|
34
34
|
from zenml.zen_stores.schemas.base_schemas import NamedSchema
|
35
35
|
from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
|
36
36
|
from zenml.zen_stores.schemas.user_schemas import UserSchema
|
@@ -140,7 +140,7 @@ class ActionSchema(NamedSchema, table=True):
|
|
140
140
|
else:
|
141
141
|
setattr(self, field, value)
|
142
142
|
|
143
|
-
self.updated =
|
143
|
+
self.updated = utc_now()
|
144
144
|
return self
|
145
145
|
|
146
146
|
def to_model(
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""SQLModel implementation of user tables."""
|
15
15
|
|
16
|
-
from datetime import datetime
|
16
|
+
from datetime import datetime
|
17
17
|
from secrets import token_hex
|
18
18
|
from typing import Any, Optional, Tuple
|
19
19
|
from uuid import UUID
|
@@ -32,6 +32,7 @@ from zenml.models import (
|
|
32
32
|
APIKeyRotateRequest,
|
33
33
|
APIKeyUpdate,
|
34
34
|
)
|
35
|
+
from zenml.utils.time_utils import utc_now
|
35
36
|
from zenml.zen_stores.schemas.base_schemas import NamedSchema
|
36
37
|
from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
|
37
38
|
from zenml.zen_stores.schemas.user_schemas import UserSchema
|
@@ -100,7 +101,7 @@ class APIKeySchema(NamedSchema, table=True):
|
|
100
101
|
"""
|
101
102
|
key = cls._generate_jwt_secret_key()
|
102
103
|
hashed_key = cls._get_hashed_key(key)
|
103
|
-
now =
|
104
|
+
now = utc_now()
|
104
105
|
return (
|
105
106
|
cls(
|
106
107
|
name=request.name,
|
@@ -197,7 +198,7 @@ class APIKeySchema(NamedSchema, table=True):
|
|
197
198
|
if hasattr(self, field):
|
198
199
|
setattr(self, field, value)
|
199
200
|
|
200
|
-
self.updated =
|
201
|
+
self.updated = utc_now()
|
201
202
|
return self
|
202
203
|
|
203
204
|
def internal_update(self, update: APIKeyInternalUpdate) -> "APIKeySchema":
|
@@ -230,7 +231,7 @@ class APIKeySchema(NamedSchema, table=True):
|
|
230
231
|
Returns:
|
231
232
|
The updated `APIKeySchema` and the new un-hashed key.
|
232
233
|
"""
|
233
|
-
self.updated =
|
234
|
+
self.updated = utc_now()
|
234
235
|
self.previous_key = self.key
|
235
236
|
self.retain_period = rotate_request.retain_period_minutes
|
236
237
|
new_key = self._generate_jwt_secret_key()
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""SQLModel implementation of artifact table."""
|
15
15
|
|
16
|
-
from datetime import datetime, timezone
|
17
16
|
from typing import TYPE_CHECKING, Any, List, Optional
|
18
17
|
from uuid import UUID
|
19
18
|
|
@@ -41,6 +40,7 @@ from zenml.models import (
|
|
41
40
|
ArtifactVersionUpdate,
|
42
41
|
)
|
43
42
|
from zenml.models.v2.core.artifact import ArtifactRequest
|
43
|
+
from zenml.utils.time_utils import utc_now
|
44
44
|
from zenml.zen_stores.schemas.base_schemas import BaseSchema, NamedSchema
|
45
45
|
from zenml.zen_stores.schemas.component_schemas import StackComponentSchema
|
46
46
|
from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
|
@@ -163,7 +163,7 @@ class ArtifactSchema(NamedSchema, table=True):
|
|
163
163
|
Returns:
|
164
164
|
The updated `ArtifactSchema`.
|
165
165
|
"""
|
166
|
-
self.updated =
|
166
|
+
self.updated = utc_now()
|
167
167
|
if artifact_update.name:
|
168
168
|
self.name = artifact_update.name
|
169
169
|
self.has_custom_name = True
|
@@ -401,5 +401,5 @@ class ArtifactVersionSchema(BaseSchema, RunMetadataInterface, table=True):
|
|
401
401
|
Returns:
|
402
402
|
The updated `ArtifactVersionSchema`.
|
403
403
|
"""
|
404
|
-
self.updated =
|
404
|
+
self.updated = utc_now()
|
405
405
|
return self
|
@@ -13,12 +13,14 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Base classes for SQLModel schemas."""
|
15
15
|
|
16
|
-
from datetime import datetime
|
16
|
+
from datetime import datetime
|
17
17
|
from typing import TYPE_CHECKING, Any, TypeVar
|
18
18
|
from uuid import UUID, uuid4
|
19
19
|
|
20
20
|
from sqlmodel import Field, SQLModel
|
21
21
|
|
22
|
+
from zenml.utils.time_utils import utc_now
|
23
|
+
|
22
24
|
if TYPE_CHECKING:
|
23
25
|
from zenml.models.v2.base.base import BaseResponse
|
24
26
|
|
@@ -29,12 +31,8 @@ class BaseSchema(SQLModel):
|
|
29
31
|
"""Base SQL Model for ZenML entities."""
|
30
32
|
|
31
33
|
id: UUID = Field(default_factory=uuid4, primary_key=True)
|
32
|
-
created: datetime = Field(
|
33
|
-
|
34
|
-
)
|
35
|
-
updated: datetime = Field(
|
36
|
-
default_factory=lambda: datetime.now(timezone.utc)
|
37
|
-
)
|
34
|
+
created: datetime = Field(default_factory=utc_now)
|
35
|
+
updated: datetime = Field(default_factory=utc_now)
|
38
36
|
|
39
37
|
def to_model(
|
40
38
|
self,
|
@@ -14,7 +14,6 @@
|
|
14
14
|
"""SQL Model Implementations for code repositories."""
|
15
15
|
|
16
16
|
import json
|
17
|
-
from datetime import datetime, timezone
|
18
17
|
from typing import Any, Optional
|
19
18
|
from uuid import UUID
|
20
19
|
|
@@ -32,6 +31,7 @@ from zenml.models import (
|
|
32
31
|
CodeRepositoryResponseMetadata,
|
33
32
|
CodeRepositoryUpdate,
|
34
33
|
)
|
34
|
+
from zenml.utils.time_utils import utc_now
|
35
35
|
from zenml.zen_stores.schemas.base_schemas import BaseSchema, NamedSchema
|
36
36
|
from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
|
37
37
|
from zenml.zen_stores.schemas.user_schemas import UserSchema
|
@@ -151,7 +151,7 @@ class CodeRepositorySchema(NamedSchema, table=True):
|
|
151
151
|
if update.logo_url:
|
152
152
|
self.logo_url = update.logo_url
|
153
153
|
|
154
|
-
self.updated =
|
154
|
+
self.updated = utc_now()
|
155
155
|
return self
|
156
156
|
|
157
157
|
|