zenml-nightly 0.70.0.dev20241125__py3-none-any.whl → 0.70.0.dev20241201__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/artifact_stores/base_artifact_store.py +2 -2
- zenml/artifacts/artifact_config.py +7 -1
- zenml/artifacts/utils.py +56 -31
- zenml/cli/__init__.py +18 -0
- zenml/cli/base.py +4 -4
- zenml/cli/login.py +26 -0
- zenml/cli/pipeline.py +80 -0
- zenml/cli/server.py +1 -1
- zenml/cli/service_connectors.py +3 -3
- zenml/cli/stack.py +0 -3
- zenml/cli/stack_components.py +0 -1
- zenml/cli/utils.py +0 -5
- zenml/client.py +8 -18
- zenml/config/compiler.py +12 -3
- zenml/config/pipeline_configurations.py +20 -0
- zenml/config/pipeline_run_configuration.py +1 -0
- zenml/config/step_configurations.py +21 -0
- zenml/enums.py +1 -0
- zenml/image_builders/local_image_builder.py +13 -3
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +14 -6
- zenml/integrations/constants.py +1 -0
- zenml/integrations/feast/__init__.py +1 -1
- zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -9
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +46 -2
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +13 -2
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +3 -1
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +3 -2
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +3 -1
- zenml/integrations/modal/__init__.py +46 -0
- zenml/integrations/modal/flavors/__init__.py +26 -0
- zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
- zenml/integrations/modal/step_operators/__init__.py +22 -0
- zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
- zenml/io/filesystem.py +2 -2
- zenml/io/local_filesystem.py +3 -3
- zenml/materializers/built_in_materializer.py +18 -1
- zenml/materializers/structured_string_materializer.py +8 -3
- zenml/model/model.py +11 -85
- zenml/model/utils.py +18 -16
- zenml/models/__init__.py +6 -0
- zenml/models/v2/core/artifact_version.py +6 -3
- zenml/models/v2/core/component.py +0 -22
- zenml/models/v2/core/model_version.py +6 -3
- zenml/models/v2/core/pipeline_run.py +19 -3
- zenml/models/v2/core/run_metadata.py +30 -9
- zenml/models/v2/core/step_run.py +6 -4
- zenml/models/v2/misc/run_metadata.py +38 -0
- zenml/orchestrators/input_utils.py +19 -6
- zenml/orchestrators/publish_utils.py +12 -5
- zenml/orchestrators/step_launcher.py +7 -3
- zenml/orchestrators/step_run_utils.py +26 -9
- zenml/orchestrators/step_runner.py +40 -3
- zenml/orchestrators/utils.py +24 -23
- zenml/pipelines/pipeline_decorator.py +4 -0
- zenml/pipelines/pipeline_definition.py +26 -8
- zenml/pipelines/run_utils.py +9 -5
- zenml/steps/base_step.py +11 -1
- zenml/steps/entrypoint_function_utils.py +7 -3
- zenml/steps/step_decorator.py +4 -0
- zenml/steps/utils.py +23 -7
- zenml/types.py +4 -0
- zenml/utils/metadata_utils.py +186 -153
- zenml/utils/string_utils.py +41 -16
- zenml/utils/visualization_utils.py +4 -1
- zenml/zen_server/cloud_utils.py +3 -1
- zenml/zen_server/rbac/endpoint_utils.py +6 -4
- zenml/zen_server/rbac/models.py +3 -2
- zenml/zen_server/rbac/utils.py +4 -7
- zenml/zen_server/routers/users_endpoints.py +35 -37
- zenml/zen_server/routers/workspaces_endpoints.py +44 -55
- zenml/zen_server/template_execution/utils.py +1 -0
- zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
- zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +7 -6
- zenml/zen_stores/schemas/__init__.py +5 -1
- zenml/zen_stores/schemas/artifact_schemas.py +12 -11
- zenml/zen_stores/schemas/component_schemas.py +0 -3
- zenml/zen_stores/schemas/model_schemas.py +13 -11
- zenml/zen_stores/schemas/pipeline_run_schemas.py +44 -16
- zenml/zen_stores/schemas/run_metadata_schemas.py +66 -31
- zenml/zen_stores/schemas/step_run_schemas.py +32 -12
- zenml/zen_stores/schemas/utils.py +47 -3
- zenml/zen_stores/sql_zen_store.py +130 -34
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/METADATA +1 -1
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/RECORD +90 -83
- zenml/utils/cloud_utils.py +0 -40
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.70.0.dev20241125.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/entry_points.txt +0 -0
zenml/zen_server/rbac/utils.py
CHANGED
@@ -413,8 +413,6 @@ def get_resource_type_for_model(
|
|
413
413
|
TagResponse,
|
414
414
|
TriggerExecutionResponse,
|
415
415
|
TriggerResponse,
|
416
|
-
UserResponse,
|
417
|
-
WorkspaceResponse,
|
418
416
|
)
|
419
417
|
|
420
418
|
mapping: Dict[
|
@@ -434,8 +432,8 @@ def get_resource_type_for_model(
|
|
434
432
|
ModelVersionResponse: ResourceType.MODEL_VERSION,
|
435
433
|
ArtifactResponse: ResourceType.ARTIFACT,
|
436
434
|
ArtifactVersionResponse: ResourceType.ARTIFACT_VERSION,
|
437
|
-
WorkspaceResponse: ResourceType.WORKSPACE,
|
438
|
-
UserResponse: ResourceType.USER,
|
435
|
+
# WorkspaceResponse: ResourceType.WORKSPACE,
|
436
|
+
# UserResponse: ResourceType.USER,
|
439
437
|
PipelineDeploymentResponse: ResourceType.PIPELINE_DEPLOYMENT,
|
440
438
|
PipelineBuildResponse: ResourceType.PIPELINE_BUILD,
|
441
439
|
PipelineRunResponse: ResourceType.PIPELINE_RUN,
|
@@ -570,7 +568,6 @@ def get_schema_for_resource_type(
|
|
570
568
|
TriggerExecutionSchema,
|
571
569
|
TriggerSchema,
|
572
570
|
UserSchema,
|
573
|
-
WorkspaceSchema,
|
574
571
|
)
|
575
572
|
|
576
573
|
mapping: Dict[ResourceType, Type["BaseSchema"]] = {
|
@@ -588,13 +585,13 @@ def get_schema_for_resource_type(
|
|
588
585
|
ResourceType.SERVICE: ServiceSchema,
|
589
586
|
ResourceType.TAG: TagSchema,
|
590
587
|
ResourceType.SERVICE_ACCOUNT: UserSchema,
|
591
|
-
ResourceType.WORKSPACE: WorkspaceSchema,
|
588
|
+
# ResourceType.WORKSPACE: WorkspaceSchema,
|
592
589
|
ResourceType.PIPELINE_RUN: PipelineRunSchema,
|
593
590
|
ResourceType.PIPELINE_DEPLOYMENT: PipelineDeploymentSchema,
|
594
591
|
ResourceType.PIPELINE_BUILD: PipelineBuildSchema,
|
595
592
|
ResourceType.RUN_TEMPLATE: RunTemplateSchema,
|
596
593
|
ResourceType.RUN_METADATA: RunMetadataSchema,
|
597
|
-
ResourceType.USER: UserSchema,
|
594
|
+
# ResourceType.USER: UserSchema,
|
598
595
|
ResourceType.ACTION: ActionSchema,
|
599
596
|
ResourceType.EVENT_SOURCE: EventSourceSchema,
|
600
597
|
ResourceType.TRIGGER: TriggerSchema,
|
@@ -46,14 +46,10 @@ from zenml.zen_server.auth import (
|
|
46
46
|
)
|
47
47
|
from zenml.zen_server.exceptions import error_response
|
48
48
|
from zenml.zen_server.rate_limit import RequestLimiter
|
49
|
-
from zenml.zen_server.rbac.endpoint_utils import (
|
50
|
-
verify_permissions_and_create_entity,
|
51
|
-
)
|
52
49
|
from zenml.zen_server.rbac.models import Action, Resource, ResourceType
|
53
50
|
from zenml.zen_server.rbac.utils import (
|
54
51
|
dehydrate_page,
|
55
52
|
dehydrate_response_model,
|
56
|
-
get_allowed_resource_ids,
|
57
53
|
get_schema_for_resource_type,
|
58
54
|
update_resource_membership,
|
59
55
|
verify_permission_for_model,
|
@@ -112,17 +108,18 @@ def list_users(
|
|
112
108
|
Returns:
|
113
109
|
A list of all users.
|
114
110
|
"""
|
115
|
-
allowed_ids = get_allowed_resource_ids(resource_type=ResourceType.USER)
|
116
|
-
if allowed_ids is not None:
|
117
|
-
|
118
|
-
|
119
|
-
else:
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
111
|
+
# allowed_ids = get_allowed_resource_ids(resource_type=ResourceType.USER)
|
112
|
+
# if allowed_ids is not None:
|
113
|
+
# # Make sure users can see themselves
|
114
|
+
# allowed_ids.add(auth_context.user.id)
|
115
|
+
# else:
|
116
|
+
# if not auth_context.user.is_admin and not server_config().rbac_enabled:
|
117
|
+
# allowed_ids = {auth_context.user.id}
|
118
|
+
if not auth_context.user.is_admin and not server_config().rbac_enabled:
|
119
|
+
user_filter_model.configure_rbac(
|
120
|
+
authenticated_user_id=auth_context.user.id,
|
121
|
+
id={auth_context.user.id},
|
122
|
+
)
|
126
123
|
|
127
124
|
page = zen_store().list_users(
|
128
125
|
user_filter_model=user_filter_model, hydrate=hydrate
|
@@ -175,11 +172,12 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
175
172
|
auth_context.user.is_admin, "create user"
|
176
173
|
)
|
177
174
|
|
178
|
-
new_user = verify_permissions_and_create_entity(
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
)
|
175
|
+
# new_user = verify_permissions_and_create_entity(
|
176
|
+
# request_model=user,
|
177
|
+
# resource_type=ResourceType.USER,
|
178
|
+
# create_method=zen_store().create_user,
|
179
|
+
# )
|
180
|
+
new_user = zen_store().create_user(user)
|
183
181
|
|
184
182
|
# add back the original unhashed activation token, if generated, to
|
185
183
|
# send it back to the client
|
@@ -217,10 +215,10 @@ def get_user(
|
|
217
215
|
verify_admin_status_if_no_rbac(
|
218
216
|
auth_context.user.is_admin, "get other user"
|
219
217
|
)
|
220
|
-
verify_permission_for_model(
|
221
|
-
|
222
|
-
|
223
|
-
)
|
218
|
+
# verify_permission_for_model(
|
219
|
+
# user,
|
220
|
+
# action=Action.READ,
|
221
|
+
# )
|
224
222
|
|
225
223
|
return dehydrate_response_model(user)
|
226
224
|
|
@@ -304,10 +302,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
304
302
|
verify_admin_status_if_no_rbac(
|
305
303
|
auth_context.user.is_admin, "update other user account"
|
306
304
|
)
|
307
|
-
verify_permission_for_model(
|
308
|
-
|
309
|
-
|
310
|
-
)
|
305
|
+
# verify_permission_for_model(
|
306
|
+
# user,
|
307
|
+
# action=Action.UPDATE,
|
308
|
+
# )
|
311
309
|
|
312
310
|
# Validate a password change
|
313
311
|
if user_update.password is not None:
|
@@ -497,10 +495,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
497
495
|
verify_admin_status_if_no_rbac(
|
498
496
|
auth_context.user.is_admin, "deactivate user"
|
499
497
|
)
|
500
|
-
verify_permission_for_model(
|
501
|
-
|
502
|
-
|
503
|
-
)
|
498
|
+
# verify_permission_for_model(
|
499
|
+
# user,
|
500
|
+
# action=Action.UPDATE,
|
501
|
+
# )
|
504
502
|
|
505
503
|
user_update = UserUpdate(
|
506
504
|
active=False,
|
@@ -548,10 +546,10 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
548
546
|
verify_admin_status_if_no_rbac(
|
549
547
|
auth_context.user.is_admin, "delete user"
|
550
548
|
)
|
551
|
-
verify_permission_for_model(
|
552
|
-
|
553
|
-
|
554
|
-
)
|
549
|
+
# verify_permission_for_model(
|
550
|
+
# user,
|
551
|
+
# action=Action.DELETE,
|
552
|
+
# )
|
555
553
|
|
556
554
|
zen_store().delete_user(user_name_or_id=user_name_or_id)
|
557
555
|
|
@@ -746,7 +744,7 @@ if server_config().rbac_enabled:
|
|
746
744
|
KeyError: If no resource with the given type and ID exists.
|
747
745
|
"""
|
748
746
|
user = zen_store().get_user(user_name_or_id)
|
749
|
-
verify_permission_for_model(user, action=Action.READ)
|
747
|
+
# verify_permission_for_model(user, action=Action.READ)
|
750
748
|
|
751
749
|
if user.id == auth_context.user.id:
|
752
750
|
raise ValueError(
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for workspaces."""
|
15
15
|
|
16
|
-
from typing import Dict, List, Optional, Tuple, Union
|
16
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -98,13 +98,13 @@ from zenml.zen_server.feature_gate.endpoint_utils import (
|
|
98
98
|
)
|
99
99
|
from zenml.zen_server.rbac.endpoint_utils import (
|
100
100
|
verify_permissions_and_create_entity,
|
101
|
-
verify_permissions_and_delete_entity,
|
102
|
-
verify_permissions_and_get_entity,
|
103
101
|
verify_permissions_and_list_entities,
|
104
|
-
verify_permissions_and_update_entity,
|
105
102
|
)
|
106
103
|
from zenml.zen_server.rbac.models import Action, ResourceType
|
107
104
|
from zenml.zen_server.rbac.utils import (
|
105
|
+
batch_verify_permissions_for_models,
|
106
|
+
dehydrate_page,
|
107
|
+
dehydrate_response_model,
|
108
108
|
get_allowed_resource_ids,
|
109
109
|
verify_permission,
|
110
110
|
verify_permission_for_model,
|
@@ -146,12 +146,10 @@ def list_workspaces(
|
|
146
146
|
Returns:
|
147
147
|
A list of workspaces.
|
148
148
|
"""
|
149
|
-
|
150
|
-
|
151
|
-
resource_type=ResourceType.WORKSPACE,
|
152
|
-
list_method=zen_store().list_workspaces,
|
153
|
-
hydrate=hydrate,
|
149
|
+
workspaces = zen_store().list_workspaces(
|
150
|
+
workspace_filter_model, hydrate=hydrate
|
154
151
|
)
|
152
|
+
return dehydrate_page(workspaces)
|
155
153
|
|
156
154
|
|
157
155
|
@router.post(
|
@@ -160,7 +158,7 @@ def list_workspaces(
|
|
160
158
|
)
|
161
159
|
@handle_exceptions
|
162
160
|
def create_workspace(
|
163
|
-
|
161
|
+
workspace_request: WorkspaceRequest,
|
164
162
|
_: AuthContext = Security(authorize),
|
165
163
|
) -> WorkspaceResponse:
|
166
164
|
"""Creates a workspace based on the requestBody.
|
@@ -168,16 +166,13 @@ def create_workspace(
|
|
168
166
|
# noqa: DAR401
|
169
167
|
|
170
168
|
Args:
|
171
|
-
|
169
|
+
workspace_request: Workspace to create.
|
172
170
|
|
173
171
|
Returns:
|
174
172
|
The created workspace.
|
175
173
|
"""
|
176
|
-
|
177
|
-
|
178
|
-
resource_type=ResourceType.WORKSPACE,
|
179
|
-
create_method=zen_store().create_workspace,
|
180
|
-
)
|
174
|
+
workspace = zen_store().create_workspace(workspace_request)
|
175
|
+
return dehydrate_response_model(workspace)
|
181
176
|
|
182
177
|
|
183
178
|
@router.get(
|
@@ -203,11 +198,10 @@ def get_workspace(
|
|
203
198
|
Returns:
|
204
199
|
The requested workspace.
|
205
200
|
"""
|
206
|
-
|
207
|
-
|
208
|
-
get_method=zen_store().get_workspace,
|
209
|
-
hydrate=hydrate,
|
201
|
+
workspace = zen_store().get_workspace(
|
202
|
+
workspace_name_or_id, hydrate=hydrate
|
210
203
|
)
|
204
|
+
return dehydrate_response_model(workspace)
|
211
205
|
|
212
206
|
|
213
207
|
@router.put(
|
@@ -231,12 +225,11 @@ def update_workspace(
|
|
231
225
|
Returns:
|
232
226
|
The updated workspace.
|
233
227
|
"""
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
get_method=zen_store().get_workspace,
|
238
|
-
update_method=zen_store().update_workspace,
|
228
|
+
workspace = zen_store().get_workspace(workspace_name_or_id, hydrate=False)
|
229
|
+
updated_workspace = zen_store().update_workspace(
|
230
|
+
workspace_id=workspace.id, workspace_update=workspace_update
|
239
231
|
)
|
232
|
+
return dehydrate_response_model(updated_workspace)
|
240
233
|
|
241
234
|
|
242
235
|
@router.delete(
|
@@ -253,11 +246,7 @@ def delete_workspace(
|
|
253
246
|
Args:
|
254
247
|
workspace_name_or_id: Name or ID of the workspace.
|
255
248
|
"""
|
256
|
-
|
257
|
-
id=workspace_name_or_id,
|
258
|
-
get_method=zen_store().get_workspace,
|
259
|
-
delete_method=zen_store().delete_workspace,
|
260
|
-
)
|
249
|
+
zen_store().delete_workspace(workspace_name_or_id)
|
261
250
|
|
262
251
|
|
263
252
|
@router.get(
|
@@ -951,20 +940,21 @@ def get_or_create_pipeline_run(
|
|
951
940
|
"is not supported."
|
952
941
|
)
|
953
942
|
|
954
|
-
|
955
|
-
|
956
|
-
|
943
|
+
def _pre_creation_hook() -> None:
|
944
|
+
verify_permission(
|
945
|
+
resource_type=ResourceType.PIPELINE_RUN, action=Action.CREATE
|
946
|
+
)
|
947
|
+
check_entitlement(resource_type=ResourceType.PIPELINE_RUN)
|
957
948
|
|
958
949
|
run, created = zen_store().get_or_create_run(
|
959
|
-
pipeline_run=pipeline_run,
|
960
|
-
pre_creation_hook=lambda: check_entitlement(
|
961
|
-
resource_type=ResourceType.PIPELINE_RUN
|
962
|
-
),
|
950
|
+
pipeline_run=pipeline_run, pre_creation_hook=_pre_creation_hook
|
963
951
|
)
|
964
952
|
if created:
|
965
953
|
report_usage(
|
966
954
|
resource_type=ResourceType.PIPELINE_RUN, resource_id=run.id
|
967
955
|
)
|
956
|
+
else:
|
957
|
+
verify_permission_for_model(run, action=Action.READ)
|
968
958
|
|
969
959
|
return run, created
|
970
960
|
|
@@ -1009,24 +999,23 @@ def create_run_metadata(
|
|
1009
999
|
"is not supported."
|
1010
1000
|
)
|
1011
1001
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
)
|
1002
|
+
verify_models: List[Any] = []
|
1003
|
+
for resource in run_metadata.resources:
|
1004
|
+
if resource.type == MetadataResourceTypes.PIPELINE_RUN:
|
1005
|
+
verify_models.append(zen_store().get_run(resource.id))
|
1006
|
+
elif resource.type == MetadataResourceTypes.STEP_RUN:
|
1007
|
+
verify_models.append(zen_store().get_run_step(resource.id))
|
1008
|
+
elif resource.type == MetadataResourceTypes.ARTIFACT_VERSION:
|
1009
|
+
verify_models.append(zen_store().get_artifact_version(resource.id))
|
1010
|
+
elif resource.type == MetadataResourceTypes.MODEL_VERSION:
|
1011
|
+
verify_models.append(zen_store().get_model_version(resource.id))
|
1012
|
+
else:
|
1013
|
+
raise RuntimeError(f"Unknown resource type: {resource.type}")
|
1014
|
+
|
1015
|
+
batch_verify_permissions_for_models(
|
1016
|
+
models=verify_models,
|
1017
|
+
action=Action.UPDATE,
|
1018
|
+
)
|
1030
1019
|
|
1031
1020
|
verify_permission(
|
1032
1021
|
resource_type=ResourceType.RUN_METADATA, action=Action.CREATE
|
@@ -0,0 +1,36 @@
|
|
1
|
+
"""Remove component spec path [b73bc71f1106].
|
2
|
+
|
3
|
+
Revision ID: b73bc71f1106
|
4
|
+
Revises: ec6307720f92
|
5
|
+
Create Date: 2024-11-29 09:36:33.089945
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sqlalchemy as sa
|
10
|
+
from alembic import op
|
11
|
+
|
12
|
+
# revision identifiers, used by Alembic.
|
13
|
+
revision = "b73bc71f1106"
|
14
|
+
down_revision = "ec6307720f92"
|
15
|
+
branch_labels = None
|
16
|
+
depends_on = None
|
17
|
+
|
18
|
+
|
19
|
+
def upgrade() -> None:
|
20
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
22
|
+
with op.batch_alter_table("stack_component", schema=None) as batch_op:
|
23
|
+
batch_op.drop_column("component_spec_path")
|
24
|
+
|
25
|
+
# ### end Alembic commands ###
|
26
|
+
|
27
|
+
|
28
|
+
def downgrade() -> None:
|
29
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
30
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
31
|
+
with op.batch_alter_table("stack_component", schema=None) as batch_op:
|
32
|
+
batch_op.add_column(
|
33
|
+
sa.Column("component_spec_path", sa.VARCHAR(), nullable=True)
|
34
|
+
)
|
35
|
+
|
36
|
+
# ### end Alembic commands ###
|
@@ -0,0 +1,135 @@
|
|
1
|
+
"""Separate run metadata into resource link table with new UUIDs.
|
2
|
+
|
3
|
+
Revision ID: cc269488e5a9
|
4
|
+
Revises: b73bc71f1106
|
5
|
+
Create Date: 2024-11-12 09:46:46.587478
|
6
|
+
"""
|
7
|
+
|
8
|
+
import uuid
|
9
|
+
|
10
|
+
import sqlalchemy as sa
|
11
|
+
import sqlmodel
|
12
|
+
from alembic import op
|
13
|
+
|
14
|
+
# revision identifiers, used by Alembic.
|
15
|
+
revision = "cc269488e5a9"
|
16
|
+
down_revision = "b73bc71f1106"
|
17
|
+
branch_labels = None
|
18
|
+
depends_on = None
|
19
|
+
|
20
|
+
|
21
|
+
def upgrade() -> None:
|
22
|
+
"""Creates the 'run_metadata_resource' table and migrates data."""
|
23
|
+
op.create_table(
|
24
|
+
"run_metadata_resource",
|
25
|
+
sa.Column(
|
26
|
+
"id",
|
27
|
+
sqlmodel.sql.sqltypes.GUID(),
|
28
|
+
nullable=False,
|
29
|
+
primary_key=True,
|
30
|
+
),
|
31
|
+
sa.Column("resource_id", sqlmodel.sql.sqltypes.GUID(), nullable=False),
|
32
|
+
sa.Column("resource_type", sa.String(length=255), nullable=False),
|
33
|
+
sa.Column(
|
34
|
+
"run_metadata_id",
|
35
|
+
sqlmodel.sql.sqltypes.GUID(),
|
36
|
+
sa.ForeignKey("run_metadata.id", ondelete="CASCADE"),
|
37
|
+
nullable=False,
|
38
|
+
),
|
39
|
+
)
|
40
|
+
|
41
|
+
connection = op.get_bind()
|
42
|
+
|
43
|
+
run_metadata_data = connection.execute(
|
44
|
+
sa.text("""
|
45
|
+
SELECT id, resource_id, resource_type
|
46
|
+
FROM run_metadata
|
47
|
+
""")
|
48
|
+
).fetchall()
|
49
|
+
|
50
|
+
# Prepare data with new UUIDs for bulk insert
|
51
|
+
resource_data = [
|
52
|
+
{
|
53
|
+
"id": str(uuid.uuid4()), # Generate a new UUID for each row
|
54
|
+
"resource_id": row.resource_id,
|
55
|
+
"resource_type": row.resource_type,
|
56
|
+
"run_metadata_id": row.id,
|
57
|
+
}
|
58
|
+
for row in run_metadata_data
|
59
|
+
]
|
60
|
+
|
61
|
+
# Perform bulk insert into `run_metadata_resource`
|
62
|
+
if resource_data: # Only perform insert if there's data to migrate
|
63
|
+
op.bulk_insert(
|
64
|
+
sa.table(
|
65
|
+
"run_metadata_resource",
|
66
|
+
sa.Column("id", sqlmodel.sql.sqltypes.GUID(), nullable=False),
|
67
|
+
sa.Column(
|
68
|
+
"resource_id", sqlmodel.sql.sqltypes.GUID(), nullable=False
|
69
|
+
),
|
70
|
+
sa.Column(
|
71
|
+
"resource_type", sa.String(length=255), nullable=False
|
72
|
+
),
|
73
|
+
sa.Column(
|
74
|
+
"run_metadata_id",
|
75
|
+
sqlmodel.sql.sqltypes.GUID(),
|
76
|
+
nullable=False,
|
77
|
+
), # Changed to BIGINT
|
78
|
+
),
|
79
|
+
resource_data,
|
80
|
+
)
|
81
|
+
|
82
|
+
op.drop_column("run_metadata", "resource_id")
|
83
|
+
op.drop_column("run_metadata", "resource_type")
|
84
|
+
|
85
|
+
op.add_column(
|
86
|
+
"run_metadata",
|
87
|
+
sa.Column(
|
88
|
+
"publisher_step_id", sqlmodel.sql.sqltypes.GUID(), nullable=True
|
89
|
+
),
|
90
|
+
)
|
91
|
+
|
92
|
+
|
93
|
+
def downgrade() -> None:
|
94
|
+
"""Reverts the 'run_metadata_resource' table and migrates data back."""
|
95
|
+
# Recreate the `resource_id` and `resource_type` columns in `run_metadata`
|
96
|
+
op.add_column(
|
97
|
+
"run_metadata",
|
98
|
+
sa.Column("resource_id", sqlmodel.sql.sqltypes.GUID(), nullable=True),
|
99
|
+
)
|
100
|
+
op.add_column(
|
101
|
+
"run_metadata",
|
102
|
+
sa.Column("resource_type", sa.String(length=255), nullable=True),
|
103
|
+
)
|
104
|
+
|
105
|
+
# Migrate data back from `run_metadata_resource` to `run_metadata`
|
106
|
+
connection = op.get_bind()
|
107
|
+
|
108
|
+
# Fetch data from `run_metadata_resource`
|
109
|
+
run_metadata_resource_data = connection.execute(
|
110
|
+
sa.text("""
|
111
|
+
SELECT resource_id, resource_type, run_metadata_id
|
112
|
+
FROM run_metadata_resource
|
113
|
+
""")
|
114
|
+
).fetchall()
|
115
|
+
|
116
|
+
# Update `run_metadata` with the data from `run_metadata_resource`
|
117
|
+
for row in run_metadata_resource_data:
|
118
|
+
connection.execute(
|
119
|
+
sa.text("""
|
120
|
+
UPDATE run_metadata
|
121
|
+
SET resource_id = :resource_id, resource_type = :resource_type
|
122
|
+
WHERE id = :run_metadata_id
|
123
|
+
"""),
|
124
|
+
{
|
125
|
+
"resource_id": row.resource_id,
|
126
|
+
"resource_type": row.resource_type,
|
127
|
+
"run_metadata_id": row.run_metadata_id,
|
128
|
+
},
|
129
|
+
)
|
130
|
+
|
131
|
+
# Drop the `run_metadata_resource` table
|
132
|
+
op.drop_table("run_metadata_resource")
|
133
|
+
|
134
|
+
# Drop the cached column
|
135
|
+
op.drop_column("run_metadata", "publisher_step_id")
|
@@ -59,12 +59,13 @@ def _migrate_artifact_type() -> None:
|
|
59
59
|
{"id_": artifact_version_id, "type": "ServiceArtifact"}
|
60
60
|
)
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
if updates:
|
63
|
+
connection.execute(
|
64
|
+
sa.update(artifact_version_table).where(
|
65
|
+
artifact_version_table.c.id == sa.bindparam("id_")
|
66
|
+
),
|
67
|
+
updates,
|
68
|
+
)
|
68
69
|
|
69
70
|
|
70
71
|
def upgrade() -> None:
|
@@ -39,7 +39,10 @@ from zenml.zen_stores.schemas.pipeline_deployment_schemas import (
|
|
39
39
|
from zenml.zen_stores.schemas.pipeline_run_schemas import PipelineRunSchema
|
40
40
|
from zenml.zen_stores.schemas.pipeline_schemas import PipelineSchema
|
41
41
|
from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
|
42
|
-
from zenml.zen_stores.schemas.run_metadata_schemas import
|
42
|
+
from zenml.zen_stores.schemas.run_metadata_schemas import (
|
43
|
+
RunMetadataResourceSchema,
|
44
|
+
RunMetadataSchema,
|
45
|
+
)
|
43
46
|
from zenml.zen_stores.schemas.schedule_schema import ScheduleSchema
|
44
47
|
from zenml.zen_stores.schemas.secret_schemas import SecretSchema
|
45
48
|
from zenml.zen_stores.schemas.service_schemas import ServiceSchema
|
@@ -90,6 +93,7 @@ __all__ = [
|
|
90
93
|
"PipelineDeploymentSchema",
|
91
94
|
"PipelineRunSchema",
|
92
95
|
"PipelineSchema",
|
96
|
+
"RunMetadataResourceSchema",
|
93
97
|
"RunMetadataSchema",
|
94
98
|
"ScheduleSchema",
|
95
99
|
"SecretSchema",
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""SQLModel implementation of artifact table."""
|
15
15
|
|
16
|
-
import json
|
17
16
|
from datetime import datetime
|
18
17
|
from typing import TYPE_CHECKING, Any, List, Optional
|
19
18
|
from uuid import UUID
|
@@ -50,6 +49,7 @@ from zenml.zen_stores.schemas.step_run_schemas import (
|
|
50
49
|
StepRunOutputArtifactSchema,
|
51
50
|
)
|
52
51
|
from zenml.zen_stores.schemas.user_schemas import UserSchema
|
52
|
+
from zenml.zen_stores.schemas.utils import RunMetadataInterface
|
53
53
|
from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
|
54
54
|
|
55
55
|
if TYPE_CHECKING:
|
@@ -59,7 +59,9 @@ if TYPE_CHECKING:
|
|
59
59
|
from zenml.zen_stores.schemas.model_schemas import (
|
60
60
|
ModelVersionArtifactSchema,
|
61
61
|
)
|
62
|
-
from zenml.zen_stores.schemas.run_metadata_schemas import
|
62
|
+
from zenml.zen_stores.schemas.run_metadata_schemas import (
|
63
|
+
RunMetadataResourceSchema,
|
64
|
+
)
|
63
65
|
from zenml.zen_stores.schemas.tag_schemas import TagResourceSchema
|
64
66
|
|
65
67
|
|
@@ -171,7 +173,7 @@ class ArtifactSchema(NamedSchema, table=True):
|
|
171
173
|
return self
|
172
174
|
|
173
175
|
|
174
|
-
class ArtifactVersionSchema(BaseSchema, table=True):
|
176
|
+
class ArtifactVersionSchema(BaseSchema, RunMetadataInterface, table=True):
|
175
177
|
"""SQL Model for artifact versions."""
|
176
178
|
|
177
179
|
__tablename__ = "artifact_version"
|
@@ -242,12 +244,12 @@ class ArtifactVersionSchema(BaseSchema, table=True):
|
|
242
244
|
workspace: "WorkspaceSchema" = Relationship(
|
243
245
|
back_populates="artifact_versions"
|
244
246
|
)
|
245
|
-
|
246
|
-
back_populates="
|
247
|
+
run_metadata_resources: List["RunMetadataResourceSchema"] = Relationship(
|
248
|
+
back_populates="artifact_versions",
|
247
249
|
sa_relationship_kwargs=dict(
|
248
|
-
primaryjoin=f"and_(
|
250
|
+
primaryjoin=f"and_(RunMetadataResourceSchema.resource_type=='{MetadataResourceTypes.ARTIFACT_VERSION.value}', foreign(RunMetadataResourceSchema.resource_id)==ArtifactVersionSchema.id)",
|
249
251
|
cascade="delete",
|
250
|
-
overlaps="
|
252
|
+
overlaps="run_metadata_resources",
|
251
253
|
),
|
252
254
|
)
|
253
255
|
output_of_step_runs: List["StepRunOutputArtifactSchema"] = Relationship(
|
@@ -352,8 +354,9 @@ class ArtifactVersionSchema(BaseSchema, table=True):
|
|
352
354
|
producer_step_run_id = step_run.original_step_run_id
|
353
355
|
|
354
356
|
# Create the body of the model
|
357
|
+
artifact = self.artifact.to_model()
|
355
358
|
body = ArtifactVersionResponseBody(
|
356
|
-
artifact=
|
359
|
+
artifact=artifact,
|
357
360
|
version=self.version or str(self.version_number),
|
358
361
|
user=self.user.to_model() if self.user else None,
|
359
362
|
uri=self.uri,
|
@@ -375,9 +378,7 @@ class ArtifactVersionSchema(BaseSchema, table=True):
|
|
375
378
|
workspace=self.workspace.to_model(),
|
376
379
|
producer_step_run_id=producer_step_run_id,
|
377
380
|
visualizations=[v.to_model() for v in self.visualizations],
|
378
|
-
run_metadata=
|
379
|
-
m.key: json.loads(m.value) for m in self.run_metadata
|
380
|
-
},
|
381
|
+
run_metadata=self.fetch_metadata(),
|
381
382
|
)
|
382
383
|
|
383
384
|
resources = None
|
@@ -56,7 +56,6 @@ class StackComponentSchema(NamedSchema, table=True):
|
|
56
56
|
flavor: str
|
57
57
|
configuration: bytes
|
58
58
|
labels: Optional[bytes]
|
59
|
-
component_spec_path: Optional[str]
|
60
59
|
|
61
60
|
workspace_id: UUID = build_foreign_key_field(
|
62
61
|
source=__tablename__,
|
@@ -135,7 +134,6 @@ class StackComponentSchema(NamedSchema, table=True):
|
|
135
134
|
name=request.name,
|
136
135
|
workspace_id=request.workspace,
|
137
136
|
user_id=request.user,
|
138
|
-
component_spec_path=request.component_spec_path,
|
139
137
|
type=request.type,
|
140
138
|
flavor=request.flavor,
|
141
139
|
configuration=base64.b64encode(
|
@@ -218,7 +216,6 @@ class StackComponentSchema(NamedSchema, table=True):
|
|
218
216
|
labels=json.loads(base64.b64decode(self.labels).decode())
|
219
217
|
if self.labels
|
220
218
|
else None,
|
221
|
-
component_spec_path=self.component_spec_path,
|
222
219
|
connector_resource_id=self.connector_resource_id,
|
223
220
|
connector=self.connector.to_model()
|
224
221
|
if self.connector
|