zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250313__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/__init__.py +2 -0
- zenml/analytics/context.py +7 -0
- zenml/artifacts/utils.py +0 -2
- zenml/cli/login.py +6 -0
- zenml/cli/model.py +7 -15
- zenml/cli/secret.py +47 -44
- zenml/cli/service_connectors.py +0 -1
- zenml/cli/stack.py +0 -1
- zenml/cli/tag.py +3 -5
- zenml/cli/utils.py +25 -23
- zenml/cli/workspace.py +79 -5
- zenml/client.py +615 -348
- zenml/config/global_config.py +16 -3
- zenml/config/pipeline_configurations.py +3 -2
- zenml/config/pipeline_run_configuration.py +2 -1
- zenml/config/secret_reference_mixin.py +1 -1
- zenml/constants.py +1 -3
- zenml/enums.py +0 -7
- zenml/event_hub/event_hub.py +3 -1
- zenml/exceptions.py +0 -24
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
- zenml/integrations/mlflow/steps/mlflow_registry.py +1 -1
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +3 -3
- zenml/model/model.py +8 -8
- zenml/models/__init__.py +18 -1
- zenml/models/v2/base/base.py +0 -5
- zenml/models/v2/base/filter.py +1 -1
- zenml/models/v2/base/scoped.py +104 -121
- zenml/models/v2/core/api_key.py +1 -1
- zenml/models/v2/core/artifact.py +31 -18
- zenml/models/v2/core/artifact_version.py +42 -25
- zenml/models/v2/core/component.py +22 -33
- zenml/models/v2/core/device.py +3 -2
- zenml/models/v2/core/event_source.py +2 -2
- zenml/models/v2/core/flavor.py +19 -47
- zenml/models/v2/core/logs.py +1 -2
- zenml/models/v2/core/model.py +7 -4
- zenml/models/v2/core/model_version.py +36 -27
- zenml/models/v2/core/pipeline.py +1 -1
- zenml/models/v2/core/pipeline_run.py +5 -13
- zenml/models/v2/core/run_template.py +1 -2
- zenml/models/v2/core/schedule.py +0 -9
- zenml/models/v2/core/secret.py +93 -127
- zenml/models/v2/core/server_settings.py +2 -2
- zenml/models/v2/core/service.py +43 -12
- zenml/models/v2/core/service_connector.py +14 -16
- zenml/models/v2/core/stack.py +24 -26
- zenml/models/v2/core/step_run.py +3 -15
- zenml/models/v2/core/tag.py +41 -15
- zenml/models/v2/core/user.py +19 -2
- zenml/models/v2/misc/statistics.py +45 -0
- zenml/models/v2/misc/tag.py +27 -0
- zenml/orchestrators/cache_utils.py +1 -1
- zenml/orchestrators/input_utils.py +1 -0
- zenml/orchestrators/step_launcher.py +0 -1
- zenml/orchestrators/step_run_utils.py +0 -2
- zenml/orchestrators/step_runner.py +10 -1
- zenml/pipelines/build_utils.py +0 -2
- zenml/pipelines/pipeline_decorator.py +3 -2
- zenml/pipelines/pipeline_definition.py +4 -5
- zenml/pipelines/run_utils.py +3 -3
- zenml/service_connectors/service_connector.py +0 -7
- zenml/service_connectors/service_connector_utils.py +0 -1
- zenml/stack/authentication_mixin.py +1 -1
- zenml/stack/flavor.py +3 -14
- zenml/stack/stack_component.py +1 -5
- zenml/steps/step_context.py +19 -0
- zenml/utils/string_utils.py +1 -1
- zenml/utils/tag_utils.py +642 -0
- zenml/zen_server/cloud_utils.py +21 -0
- zenml/zen_server/exceptions.py +0 -6
- zenml/zen_server/rbac/endpoint_utils.py +134 -46
- zenml/zen_server/rbac/models.py +65 -3
- zenml/zen_server/rbac/rbac_interface.py +9 -0
- zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
- zenml/zen_server/rbac/utils.py +156 -29
- zenml/zen_server/rbac/zenml_cloud_rbac.py +43 -11
- zenml/zen_server/routers/actions_endpoints.py +3 -5
- zenml/zen_server/routers/artifact_endpoint.py +0 -5
- zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
- zenml/zen_server/routers/auth_endpoints.py +22 -7
- zenml/zen_server/routers/code_repositories_endpoints.py +56 -3
- zenml/zen_server/routers/devices_endpoints.py +0 -4
- zenml/zen_server/routers/event_source_endpoints.py +0 -5
- zenml/zen_server/routers/flavors_endpoints.py +0 -5
- zenml/zen_server/routers/logs_endpoints.py +0 -1
- zenml/zen_server/routers/model_versions_endpoints.py +102 -23
- zenml/zen_server/routers/models_endpoints.py +51 -68
- zenml/zen_server/routers/pipeline_builds_endpoints.py +58 -4
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +58 -4
- zenml/zen_server/routers/pipelines_endpoints.py +73 -4
- zenml/zen_server/routers/plugin_endpoints.py +0 -1
- zenml/zen_server/routers/run_metadata_endpoints.py +99 -0
- zenml/zen_server/routers/run_templates_endpoints.py +66 -3
- zenml/zen_server/routers/runs_endpoints.py +60 -8
- zenml/zen_server/routers/schedule_endpoints.py +69 -6
- zenml/zen_server/routers/secrets_endpoints.py +40 -4
- zenml/zen_server/routers/server_endpoints.py +53 -1
- zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
- zenml/zen_server/routers/service_connectors_endpoints.py +96 -14
- zenml/zen_server/routers/service_endpoints.py +20 -7
- zenml/zen_server/routers/stack_components_endpoints.py +68 -7
- zenml/zen_server/routers/stacks_endpoints.py +98 -7
- zenml/zen_server/routers/steps_endpoints.py +17 -11
- zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
- zenml/zen_server/routers/tags_endpoints.py +6 -17
- zenml/zen_server/routers/triggers_endpoints.py +5 -8
- zenml/zen_server/routers/users_endpoints.py +47 -12
- zenml/zen_server/routers/workspaces_endpoints.py +56 -1285
- zenml/zen_server/template_execution/utils.py +5 -4
- zenml/zen_server/utils.py +21 -0
- zenml/zen_server/zen_server_api.py +4 -0
- zenml/zen_stores/base_zen_store.py +29 -44
- zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
- zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
- zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
- zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
- zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
- zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
- zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
- zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
- zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
- zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
- zenml/zen_stores/rest_zen_store.py +172 -171
- zenml/zen_stores/schemas/action_schemas.py +8 -1
- zenml/zen_stores/schemas/api_key_schemas.py +8 -1
- zenml/zen_stores/schemas/artifact_schemas.py +28 -1
- zenml/zen_stores/schemas/code_repository_schemas.py +8 -1
- zenml/zen_stores/schemas/component_schemas.py +9 -14
- zenml/zen_stores/schemas/event_source_schemas.py +8 -1
- zenml/zen_stores/schemas/flavor_schemas.py +14 -20
- zenml/zen_stores/schemas/model_schemas.py +3 -0
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -1
- zenml/zen_stores/schemas/pipeline_run_schemas.py +0 -3
- zenml/zen_stores/schemas/run_template_schemas.py +8 -4
- zenml/zen_stores/schemas/schedule_schema.py +9 -14
- zenml/zen_stores/schemas/secret_schemas.py +15 -25
- zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
- zenml/zen_stores/schemas/service_schemas.py +0 -1
- zenml/zen_stores/schemas/stack_schemas.py +12 -15
- zenml/zen_stores/schemas/step_run_schemas.py +7 -8
- zenml/zen_stores/schemas/tag_schemas.py +30 -2
- zenml/zen_stores/schemas/trigger_schemas.py +8 -1
- zenml/zen_stores/schemas/user_schemas.py +24 -2
- zenml/zen_stores/schemas/utils.py +16 -0
- zenml/zen_stores/schemas/workspace_schemas.py +7 -25
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
- zenml/zen_stores/sql_zen_store.py +2905 -2280
- zenml/zen_stores/template_utils.py +1 -1
- zenml/zen_stores/zen_store_interface.py +82 -58
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +160 -147
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
zenml/models/v2/core/secret.py
CHANGED
@@ -13,43 +13,52 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing secrets."""
|
15
15
|
|
16
|
-
from
|
17
|
-
|
16
|
+
from typing import (
|
17
|
+
TYPE_CHECKING,
|
18
|
+
ClassVar,
|
19
|
+
Dict,
|
20
|
+
List,
|
21
|
+
Optional,
|
22
|
+
Type,
|
23
|
+
TypeVar,
|
24
|
+
)
|
18
25
|
|
19
26
|
from pydantic import Field, SecretStr
|
20
27
|
|
21
28
|
from zenml.constants import STR_FIELD_MAX_LENGTH
|
22
|
-
from zenml.enums import (
|
23
|
-
GenericFilterOps,
|
24
|
-
LogicalOperators,
|
25
|
-
SecretScope,
|
26
|
-
SorterOps,
|
27
|
-
)
|
28
29
|
from zenml.models.v2.base.base import BaseUpdate
|
30
|
+
from zenml.models.v2.base.filter import AnyQuery
|
29
31
|
from zenml.models.v2.base.scoped import (
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
UserScopedFilter,
|
33
|
+
UserScopedRequest,
|
34
|
+
UserScopedResponse,
|
35
|
+
UserScopedResponseBody,
|
36
|
+
UserScopedResponseMetadata,
|
37
|
+
UserScopedResponseResources,
|
36
38
|
)
|
37
39
|
from zenml.utils.secret_utils import PlainSerializedSecretStr
|
38
40
|
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
from zenml.zen_stores.schemas.base_schemas import BaseSchema
|
43
|
+
|
44
|
+
AnySchema = TypeVar("AnySchema", bound=BaseSchema)
|
45
|
+
|
39
46
|
# ------------------ Request Model ------------------
|
40
47
|
|
41
48
|
|
42
|
-
class SecretRequest(
|
43
|
-
"""Request
|
49
|
+
class SecretRequest(UserScopedRequest):
|
50
|
+
"""Request model for secrets."""
|
44
51
|
|
45
|
-
ANALYTICS_FIELDS: ClassVar[List[str]] = ["
|
52
|
+
ANALYTICS_FIELDS: ClassVar[List[str]] = ["private"]
|
46
53
|
|
47
54
|
name: str = Field(
|
48
55
|
title="The name of the secret.",
|
49
56
|
max_length=STR_FIELD_MAX_LENGTH,
|
50
57
|
)
|
51
|
-
|
52
|
-
|
58
|
+
private: bool = Field(
|
59
|
+
False,
|
60
|
+
title="Whether the secret is private. A private secret is only "
|
61
|
+
"accessible to the user who created it.",
|
53
62
|
)
|
54
63
|
values: Dict[str, Optional[PlainSerializedSecretStr]] = Field(
|
55
64
|
default_factory=dict, title="The values stored in this secret."
|
@@ -78,17 +87,19 @@ class SecretRequest(WorkspaceScopedRequest):
|
|
78
87
|
|
79
88
|
|
80
89
|
class SecretUpdate(BaseUpdate):
|
81
|
-
"""
|
90
|
+
"""Update model for secrets."""
|
82
91
|
|
83
|
-
ANALYTICS_FIELDS: ClassVar[List[str]] = ["
|
92
|
+
ANALYTICS_FIELDS: ClassVar[List[str]] = ["private"]
|
84
93
|
|
85
94
|
name: Optional[str] = Field(
|
86
95
|
title="The name of the secret.",
|
87
96
|
max_length=STR_FIELD_MAX_LENGTH,
|
88
97
|
default=None,
|
89
98
|
)
|
90
|
-
|
91
|
-
default=None,
|
99
|
+
private: Optional[bool] = Field(
|
100
|
+
default=None,
|
101
|
+
title="Whether the secret is private. A private secret is only "
|
102
|
+
"accessible to the user who created it.",
|
92
103
|
)
|
93
104
|
values: Optional[Dict[str, Optional[PlainSerializedSecretStr]]] = Field(
|
94
105
|
title="The values stored in this secret.",
|
@@ -113,33 +124,37 @@ class SecretUpdate(BaseUpdate):
|
|
113
124
|
# ------------------ Response Model ------------------
|
114
125
|
|
115
126
|
|
116
|
-
class SecretResponseBody(
|
127
|
+
class SecretResponseBody(UserScopedResponseBody):
|
117
128
|
"""Response body for secrets."""
|
118
129
|
|
119
|
-
|
120
|
-
|
130
|
+
private: bool = Field(
|
131
|
+
False,
|
132
|
+
title="Whether the secret is private. A private secret is only "
|
133
|
+
"accessible to the user who created it.",
|
121
134
|
)
|
122
135
|
values: Dict[str, Optional[PlainSerializedSecretStr]] = Field(
|
123
136
|
default_factory=dict, title="The values stored in this secret."
|
124
137
|
)
|
125
138
|
|
126
139
|
|
127
|
-
class SecretResponseMetadata(
|
140
|
+
class SecretResponseMetadata(UserScopedResponseMetadata):
|
128
141
|
"""Response metadata for secrets."""
|
129
142
|
|
130
143
|
|
131
|
-
class SecretResponseResources(
|
132
|
-
"""
|
144
|
+
class SecretResponseResources(UserScopedResponseResources):
|
145
|
+
"""Response resources for secrets."""
|
133
146
|
|
134
147
|
|
135
148
|
class SecretResponse(
|
136
|
-
|
137
|
-
SecretResponseBody,
|
149
|
+
UserScopedResponse[
|
150
|
+
SecretResponseBody,
|
151
|
+
SecretResponseMetadata,
|
152
|
+
SecretResponseResources,
|
138
153
|
]
|
139
154
|
):
|
140
155
|
"""Response model for secrets."""
|
141
156
|
|
142
|
-
ANALYTICS_FIELDS: ClassVar[List[str]] = ["
|
157
|
+
ANALYTICS_FIELDS: ClassVar[List[str]] = ["private"]
|
143
158
|
|
144
159
|
name: str = Field(
|
145
160
|
title="The name of the secret.",
|
@@ -159,13 +174,13 @@ class SecretResponse(
|
|
159
174
|
# Body and metadata properties
|
160
175
|
|
161
176
|
@property
|
162
|
-
def
|
163
|
-
"""The `
|
177
|
+
def private(self) -> bool:
|
178
|
+
"""The `private` property.
|
164
179
|
|
165
180
|
Returns:
|
166
181
|
the value of the property.
|
167
182
|
"""
|
168
|
-
return self.get_body().
|
183
|
+
return self.get_body().private
|
169
184
|
|
170
185
|
@property
|
171
186
|
def values(self) -> Dict[str, Optional[SecretStr]]:
|
@@ -240,11 +255,11 @@ class SecretResponse(
|
|
240
255
|
# ------------------ Filter Model ------------------
|
241
256
|
|
242
257
|
|
243
|
-
class SecretFilter(
|
244
|
-
"""Model to enable advanced filtering
|
258
|
+
class SecretFilter(UserScopedFilter):
|
259
|
+
"""Model to enable advanced secret filtering."""
|
245
260
|
|
246
261
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
247
|
-
*
|
262
|
+
*UserScopedFilter.FILTER_EXCLUDE_FIELDS,
|
248
263
|
"values",
|
249
264
|
]
|
250
265
|
|
@@ -252,103 +267,54 @@ class SecretFilter(WorkspaceScopedFilter):
|
|
252
267
|
default=None,
|
253
268
|
description="Name of the secret",
|
254
269
|
)
|
255
|
-
|
270
|
+
private: Optional[bool] = Field(
|
256
271
|
default=None,
|
257
|
-
description="
|
258
|
-
union_mode="left_to_right",
|
272
|
+
description="Whether to filter secrets by private status",
|
259
273
|
)
|
260
274
|
|
261
|
-
|
262
|
-
|
263
|
-
|
275
|
+
def apply_filter(
|
276
|
+
self,
|
277
|
+
query: AnyQuery,
|
278
|
+
table: Type["AnySchema"],
|
279
|
+
) -> AnyQuery:
|
280
|
+
"""Applies the filter to a query.
|
264
281
|
|
265
282
|
Args:
|
266
|
-
|
283
|
+
query: The query to which to apply the filter.
|
284
|
+
table: The query table.
|
267
285
|
|
268
286
|
Returns:
|
269
|
-
The
|
270
|
-
lexicographical sorting and filtering.
|
287
|
+
The query with filter applied.
|
271
288
|
"""
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
if
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
289
|
+
# The secret user scoping works a bit differently than the other
|
290
|
+
# scoped filters. We have to filter out all private secrets that are
|
291
|
+
# not owned by the current user.
|
292
|
+
if not self.scope_user:
|
293
|
+
return super().apply_filter(query=query, table=table)
|
294
|
+
|
295
|
+
scope_user = self.scope_user
|
296
|
+
|
297
|
+
# First we apply the inherited filters without the user scoping
|
298
|
+
# applied.
|
299
|
+
self.scope_user = None
|
300
|
+
query = super().apply_filter(query=query, table=table)
|
301
|
+
self.scope_user = scope_user
|
302
|
+
|
303
|
+
# Then we apply the user scoping filter.
|
304
|
+
if self.scope_user:
|
305
|
+
from sqlmodel import and_, or_
|
306
|
+
|
307
|
+
query = query.where(
|
308
|
+
or_(
|
309
|
+
and_(
|
310
|
+
getattr(table, "user_id") == self.scope_user,
|
311
|
+
getattr(table, "private") == True, # noqa: E712
|
312
|
+
),
|
313
|
+
getattr(table, "private") == False, # noqa: E712
|
314
|
+
)
|
315
|
+
)
|
284
316
|
|
285
|
-
Returns:
|
286
|
-
True if the secret matches the filter criteria, False otherwise.
|
287
|
-
"""
|
288
|
-
for filter in self.list_of_filters:
|
289
|
-
column_value: Optional[Any] = None
|
290
|
-
if filter.column == "workspace_id":
|
291
|
-
column_value = secret.workspace.id
|
292
|
-
elif filter.column == "user_id":
|
293
|
-
column_value = secret.user.id if secret.user else None
|
294
|
-
else:
|
295
|
-
column_value = getattr(secret, filter.column)
|
296
|
-
|
297
|
-
# Convert the values to strings for lexicographical comparison.
|
298
|
-
str_column_value = self._get_filtering_value(column_value)
|
299
|
-
str_filter_value = self._get_filtering_value(filter.value)
|
300
|
-
|
301
|
-
# Compare the lexicographical values according to the operation.
|
302
|
-
if filter.operation == GenericFilterOps.EQUALS:
|
303
|
-
result = str_column_value == str_filter_value
|
304
|
-
elif filter.operation == GenericFilterOps.CONTAINS:
|
305
|
-
result = str_filter_value in str_column_value
|
306
|
-
elif filter.operation == GenericFilterOps.STARTSWITH:
|
307
|
-
result = str_column_value.startswith(str_filter_value)
|
308
|
-
elif filter.operation == GenericFilterOps.ENDSWITH:
|
309
|
-
result = str_column_value.endswith(str_filter_value)
|
310
|
-
elif filter.operation == GenericFilterOps.GT:
|
311
|
-
result = str_column_value > str_filter_value
|
312
|
-
elif filter.operation == GenericFilterOps.GTE:
|
313
|
-
result = str_column_value >= str_filter_value
|
314
|
-
elif filter.operation == GenericFilterOps.LT:
|
315
|
-
result = str_column_value < str_filter_value
|
316
|
-
elif filter.operation == GenericFilterOps.LTE:
|
317
|
-
result = str_column_value <= str_filter_value
|
318
|
-
|
319
|
-
# Exit early if the result is False for AND, and True for OR
|
320
|
-
if self.logical_operator == LogicalOperators.AND:
|
321
|
-
if not result:
|
322
|
-
return False
|
323
|
-
else:
|
324
|
-
if result:
|
325
|
-
return True
|
326
|
-
|
327
|
-
# If we get here, all filters have been checked and the result is
|
328
|
-
# True for AND, and False for OR
|
329
|
-
if self.logical_operator == LogicalOperators.AND:
|
330
|
-
return True
|
331
317
|
else:
|
332
|
-
|
318
|
+
query = query.where(getattr(table, "private") == False) # noqa: E712
|
333
319
|
|
334
|
-
|
335
|
-
self, secrets: List[SecretResponse]
|
336
|
-
) -> List[SecretResponse]:
|
337
|
-
"""Sorts a list of secrets according to the filter criteria.
|
338
|
-
|
339
|
-
Args:
|
340
|
-
secrets: The list of secrets to sort.
|
341
|
-
|
342
|
-
Returns:
|
343
|
-
The sorted list of secrets.
|
344
|
-
"""
|
345
|
-
column, sort_op = self.sorting_params
|
346
|
-
sorted_secrets = sorted(
|
347
|
-
secrets,
|
348
|
-
key=lambda secret: self._get_filtering_value(
|
349
|
-
getattr(secret, column)
|
350
|
-
),
|
351
|
-
reverse=sort_op == SorterOps.DESCENDING,
|
352
|
-
)
|
353
|
-
|
354
|
-
return sorted_secrets
|
320
|
+
return query
|
@@ -26,7 +26,7 @@ from zenml.models.v2.base.base import (
|
|
26
26
|
BaseResponseBody,
|
27
27
|
BaseResponseMetadata,
|
28
28
|
BaseResponseResources,
|
29
|
-
|
29
|
+
BaseUpdate,
|
30
30
|
)
|
31
31
|
|
32
32
|
# ------------------ Base Model ------------------
|
@@ -34,7 +34,7 @@ from zenml.models.v2.base.base import (
|
|
34
34
|
# ------------------ Update Model ------------------
|
35
35
|
|
36
36
|
|
37
|
-
class ServerSettingsUpdate(
|
37
|
+
class ServerSettingsUpdate(BaseUpdate):
|
38
38
|
"""Model for updating server settings."""
|
39
39
|
|
40
40
|
server_name: Optional[str] = Field(
|
zenml/models/v2/core/service.py
CHANGED
@@ -27,10 +27,11 @@ from typing import (
|
|
27
27
|
)
|
28
28
|
from uuid import UUID
|
29
29
|
|
30
|
-
from pydantic import
|
30
|
+
from pydantic import ConfigDict, Field
|
31
31
|
from sqlalchemy.sql.elements import ColumnElement
|
32
32
|
|
33
33
|
from zenml.constants import STR_FIELD_MAX_LENGTH
|
34
|
+
from zenml.models.v2.base.base import BaseUpdate
|
34
35
|
from zenml.models.v2.base.scoped import (
|
35
36
|
WorkspaceScopedFilter,
|
36
37
|
WorkspaceScopedRequest,
|
@@ -43,6 +44,8 @@ from zenml.services.service_status import ServiceState
|
|
43
44
|
from zenml.services.service_type import ServiceType
|
44
45
|
|
45
46
|
if TYPE_CHECKING:
|
47
|
+
from zenml.models.v2.core.model_version import ModelVersionResponse
|
48
|
+
from zenml.models.v2.core.pipeline_run import PipelineRunResponse
|
46
49
|
from zenml.zen_stores.schemas import BaseSchema
|
47
50
|
|
48
51
|
AnySchema = TypeVar("AnySchema", bound=BaseSchema)
|
@@ -101,10 +104,9 @@ class ServiceRequest(WorkspaceScopedRequest):
|
|
101
104
|
default=None,
|
102
105
|
title="The model version id linked to the service.",
|
103
106
|
)
|
104
|
-
pipeline_run_id: Optional[
|
107
|
+
pipeline_run_id: Optional[UUID] = Field(
|
105
108
|
default=None,
|
106
|
-
|
107
|
-
union_mode="left_to_right",
|
109
|
+
title="The pipeline run id linked to the service.",
|
108
110
|
)
|
109
111
|
|
110
112
|
# TODO: In Pydantic v2, the `model_` is a protected namespaces for all
|
@@ -119,7 +121,7 @@ class ServiceRequest(WorkspaceScopedRequest):
|
|
119
121
|
# ------------------ Update Model ------------------
|
120
122
|
|
121
123
|
|
122
|
-
class ServiceUpdate(
|
124
|
+
class ServiceUpdate(BaseUpdate):
|
123
125
|
"""Update model for stack components."""
|
124
126
|
|
125
127
|
name: Optional[str] = Field(
|
@@ -230,6 +232,23 @@ class ServiceResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
230
232
|
class ServiceResponseResources(WorkspaceScopedResponseResources):
|
231
233
|
"""Class for all resource models associated with the service entity."""
|
232
234
|
|
235
|
+
pipeline_run: Optional["PipelineRunResponse"] = Field(
|
236
|
+
default=None,
|
237
|
+
title="The pipeline run associated with the service.",
|
238
|
+
)
|
239
|
+
model_version: Optional["ModelVersionResponse"] = Field(
|
240
|
+
default=None,
|
241
|
+
title="The model version associated with the service.",
|
242
|
+
)
|
243
|
+
|
244
|
+
# TODO: In Pydantic v2, the `model_` is a protected namespaces for all
|
245
|
+
# fields defined under base models. If not handled, this raises a warning.
|
246
|
+
# It is possible to suppress this warning message with the following
|
247
|
+
# configuration, however the ultimate solution is to rename these fields.
|
248
|
+
# Even though they do not cause any problems right now, if we are not
|
249
|
+
# careful we might overwrite some fields protected by pydantic.
|
250
|
+
model_config = ConfigDict(protected_namespaces=())
|
251
|
+
|
233
252
|
|
234
253
|
class ServiceResponse(
|
235
254
|
WorkspaceScopedResponse[
|
@@ -363,18 +382,30 @@ class ServiceResponse(
|
|
363
382
|
"""
|
364
383
|
return self.get_body().state
|
365
384
|
|
385
|
+
@property
|
386
|
+
def pipeline_run(self) -> Optional["PipelineRunResponse"]:
|
387
|
+
"""The `pipeline_run` property.
|
388
|
+
|
389
|
+
Returns:
|
390
|
+
the value of the property.
|
391
|
+
"""
|
392
|
+
return self.get_resources().pipeline_run
|
393
|
+
|
394
|
+
@property
|
395
|
+
def model_version(self) -> Optional["ModelVersionResponse"]:
|
396
|
+
"""The `model_version` property.
|
397
|
+
|
398
|
+
Returns:
|
399
|
+
the value of the property.
|
400
|
+
"""
|
401
|
+
return self.get_resources().model_version
|
402
|
+
|
366
403
|
|
367
404
|
# ------------------ Filter Model ------------------
|
368
405
|
|
369
406
|
|
370
407
|
class ServiceFilter(WorkspaceScopedFilter):
|
371
|
-
"""Model to enable advanced filtering of services.
|
372
|
-
|
373
|
-
The Service needs additional scoping. As such the `_scope_user` field
|
374
|
-
can be set to the user that is doing the filtering. The
|
375
|
-
`generate_filter()` method of the baseclass is overwritten to include the
|
376
|
-
scoping.
|
377
|
-
"""
|
408
|
+
"""Model to enable advanced filtering of services."""
|
378
409
|
|
379
410
|
name: Optional[str] = Field(
|
380
411
|
default=None,
|
@@ -24,12 +24,12 @@ from zenml.constants import STR_FIELD_MAX_LENGTH
|
|
24
24
|
from zenml.logger import get_logger
|
25
25
|
from zenml.models.v2.base.base import BaseUpdate
|
26
26
|
from zenml.models.v2.base.scoped import (
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
UserScopedFilter,
|
28
|
+
UserScopedRequest,
|
29
|
+
UserScopedResponse,
|
30
|
+
UserScopedResponseBody,
|
31
|
+
UserScopedResponseMetadata,
|
32
|
+
UserScopedResponseResources,
|
33
33
|
)
|
34
34
|
from zenml.models.v2.misc.service_connector_type import (
|
35
35
|
ServiceConnectorTypeModel,
|
@@ -41,7 +41,7 @@ logger = get_logger(__name__)
|
|
41
41
|
# ------------------ Request Model ------------------
|
42
42
|
|
43
43
|
|
44
|
-
class ServiceConnectorRequest(
|
44
|
+
class ServiceConnectorRequest(UserScopedRequest):
|
45
45
|
"""Request model for service connectors."""
|
46
46
|
|
47
47
|
name: str = Field(
|
@@ -223,8 +223,6 @@ class ServiceConnectorUpdate(BaseUpdate):
|
|
223
223
|
valid configuration update, not just a partial update. If either is
|
224
224
|
set (i.e. not None) in the update, their values are merged together and
|
225
225
|
will replace the existing configuration and secrets values.
|
226
|
-
* the `secret_id` field value in the update is ignored, given that
|
227
|
-
secrets are managed internally by the ZenML store.
|
228
226
|
* the `labels` field is also a full labels update: if set (i.e. not
|
229
227
|
`None`), all existing labels are removed and replaced by the new labels
|
230
228
|
in the update.
|
@@ -400,7 +398,7 @@ class ServiceConnectorUpdate(BaseUpdate):
|
|
400
398
|
# ------------------ Response Model ------------------
|
401
399
|
|
402
400
|
|
403
|
-
class ServiceConnectorResponseBody(
|
401
|
+
class ServiceConnectorResponseBody(UserScopedResponseBody):
|
404
402
|
"""Response body for service connectors."""
|
405
403
|
|
406
404
|
description: str = Field(
|
@@ -446,7 +444,7 @@ class ServiceConnectorResponseBody(WorkspaceScopedResponseBody):
|
|
446
444
|
)
|
447
445
|
|
448
446
|
|
449
|
-
class ServiceConnectorResponseMetadata(
|
447
|
+
class ServiceConnectorResponseMetadata(UserScopedResponseMetadata):
|
450
448
|
"""Response metadata for service connectors."""
|
451
449
|
|
452
450
|
configuration: Dict[str, Any] = Field(
|
@@ -475,12 +473,12 @@ class ServiceConnectorResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
475
473
|
)
|
476
474
|
|
477
475
|
|
478
|
-
class ServiceConnectorResponseResources(
|
476
|
+
class ServiceConnectorResponseResources(UserScopedResponseResources):
|
479
477
|
"""Class for all resource models associated with the service connector entity."""
|
480
478
|
|
481
479
|
|
482
480
|
class ServiceConnectorResponse(
|
483
|
-
|
481
|
+
UserScopedResponse[
|
484
482
|
ServiceConnectorResponseBody,
|
485
483
|
ServiceConnectorResponseMetadata,
|
486
484
|
ServiceConnectorResponseResources,
|
@@ -781,18 +779,18 @@ class ServiceConnectorResponse(
|
|
781
779
|
# ------------------ Filter Model ------------------
|
782
780
|
|
783
781
|
|
784
|
-
class ServiceConnectorFilter(
|
782
|
+
class ServiceConnectorFilter(UserScopedFilter):
|
785
783
|
"""Model to enable advanced filtering of service connectors."""
|
786
784
|
|
787
785
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
788
|
-
*
|
786
|
+
*UserScopedFilter.FILTER_EXCLUDE_FIELDS,
|
789
787
|
"scope_type",
|
790
788
|
"resource_type",
|
791
789
|
"labels_str",
|
792
790
|
"labels",
|
793
791
|
]
|
794
792
|
CLI_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
795
|
-
*
|
793
|
+
*UserScopedFilter.CLI_EXCLUDE_FIELDS,
|
796
794
|
"scope_type",
|
797
795
|
"labels_str",
|
798
796
|
"labels",
|
zenml/models/v2/core/stack.py
CHANGED
@@ -32,13 +32,14 @@ from sqlmodel import and_
|
|
32
32
|
|
33
33
|
from zenml.constants import STR_FIELD_MAX_LENGTH
|
34
34
|
from zenml.enums import StackComponentType
|
35
|
-
from zenml.models.v2.base.base import
|
35
|
+
from zenml.models.v2.base.base import BaseUpdate
|
36
36
|
from zenml.models.v2.base.scoped import (
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
UserScopedFilter,
|
38
|
+
UserScopedRequest,
|
39
|
+
UserScopedResponse,
|
40
|
+
UserScopedResponseBody,
|
41
|
+
UserScopedResponseMetadata,
|
42
|
+
UserScopedResponseResources,
|
42
43
|
)
|
43
44
|
from zenml.models.v2.misc.info_models import (
|
44
45
|
ComponentInfo,
|
@@ -57,11 +58,8 @@ if TYPE_CHECKING:
|
|
57
58
|
# ------------------ Request Model ------------------
|
58
59
|
|
59
60
|
|
60
|
-
class StackRequest(
|
61
|
-
"""Request model for
|
62
|
-
|
63
|
-
user: Optional[UUID] = None
|
64
|
-
workspace: Optional[UUID] = None
|
61
|
+
class StackRequest(UserScopedRequest):
|
62
|
+
"""Request model for stack creation."""
|
65
63
|
|
66
64
|
name: str = Field(
|
67
65
|
title="The name of the stack.", max_length=STR_FIELD_MAX_LENGTH
|
@@ -131,6 +129,10 @@ class StackRequest(BaseRequest):
|
|
131
129
|
return self
|
132
130
|
|
133
131
|
|
132
|
+
class DefaultStackRequest(StackRequest):
|
133
|
+
"""Internal stack request model used only for default stacks."""
|
134
|
+
|
135
|
+
|
134
136
|
# ------------------ Update Model ------------------
|
135
137
|
|
136
138
|
|
@@ -165,11 +167,11 @@ class StackUpdate(BaseUpdate):
|
|
165
167
|
# ------------------ Response Model ------------------
|
166
168
|
|
167
169
|
|
168
|
-
class StackResponseBody(
|
170
|
+
class StackResponseBody(UserScopedResponseBody):
|
169
171
|
"""Response body for stacks."""
|
170
172
|
|
171
173
|
|
172
|
-
class StackResponseMetadata(
|
174
|
+
class StackResponseMetadata(UserScopedResponseMetadata):
|
173
175
|
"""Response metadata for stacks."""
|
174
176
|
|
175
177
|
components: Dict[StackComponentType, List["ComponentResponse"]] = Field(
|
@@ -191,13 +193,15 @@ class StackResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
191
193
|
)
|
192
194
|
|
193
195
|
|
194
|
-
class StackResponseResources(
|
195
|
-
"""
|
196
|
+
class StackResponseResources(UserScopedResponseResources):
|
197
|
+
"""Response resources for stacks."""
|
196
198
|
|
197
199
|
|
198
200
|
class StackResponse(
|
199
|
-
|
200
|
-
StackResponseBody,
|
201
|
+
UserScopedResponse[
|
202
|
+
StackResponseBody,
|
203
|
+
StackResponseMetadata,
|
204
|
+
StackResponseResources,
|
201
205
|
]
|
202
206
|
):
|
203
207
|
"""Response model for stacks."""
|
@@ -324,17 +328,11 @@ class StackResponse(
|
|
324
328
|
# ------------------ Filter Model ------------------
|
325
329
|
|
326
330
|
|
327
|
-
class StackFilter(
|
328
|
-
"""Model to enable advanced filtering
|
329
|
-
|
330
|
-
The Stack Model needs additional scoping. As such the `_scope_user` field
|
331
|
-
can be set to the user that is doing the filtering. The
|
332
|
-
`generate_filter()` method of the baseclass is overwritten to include the
|
333
|
-
scoping.
|
334
|
-
"""
|
331
|
+
class StackFilter(UserScopedFilter):
|
332
|
+
"""Model to enable advanced stack filtering."""
|
335
333
|
|
336
334
|
FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
|
337
|
-
*
|
335
|
+
*UserScopedFilter.FILTER_EXCLUDE_FIELDS,
|
338
336
|
"component_id",
|
339
337
|
"component",
|
340
338
|
]
|
zenml/models/v2/core/step_run.py
CHANGED
@@ -27,12 +27,13 @@ from typing import (
|
|
27
27
|
)
|
28
28
|
from uuid import UUID
|
29
29
|
|
30
|
-
from pydantic import
|
30
|
+
from pydantic import ConfigDict, Field
|
31
31
|
|
32
32
|
from zenml.config.step_configurations import StepConfiguration, StepSpec
|
33
33
|
from zenml.constants import STR_FIELD_MAX_LENGTH, TEXT_FIELD_MAX_LENGTH
|
34
34
|
from zenml.enums import ExecutionStatus, StepRunInputArtifactType
|
35
35
|
from zenml.metadata.metadata_types import MetadataType
|
36
|
+
from zenml.models.v2.base.base import BaseUpdate
|
36
37
|
from zenml.models.v2.base.scoped import (
|
37
38
|
WorkspaceScopedFilter,
|
38
39
|
WorkspaceScopedRequest,
|
@@ -137,14 +138,6 @@ class StepRunRequest(WorkspaceScopedRequest):
|
|
137
138
|
title="Logs associated with this step run.",
|
138
139
|
default=None,
|
139
140
|
)
|
140
|
-
deployment: UUID = Field(
|
141
|
-
title="The deployment associated with the step run."
|
142
|
-
)
|
143
|
-
model_version_id: Optional[UUID] = Field(
|
144
|
-
title="The ID of the model version that was "
|
145
|
-
"configured by this step run explicitly.",
|
146
|
-
default=None,
|
147
|
-
)
|
148
141
|
|
149
142
|
model_config = ConfigDict(protected_namespaces=())
|
150
143
|
|
@@ -152,7 +145,7 @@ class StepRunRequest(WorkspaceScopedRequest):
|
|
152
145
|
# ------------------ Update Model ------------------
|
153
146
|
|
154
147
|
|
155
|
-
class StepRunUpdate(
|
148
|
+
class StepRunUpdate(BaseUpdate):
|
156
149
|
"""Update model for step runs."""
|
157
150
|
|
158
151
|
outputs: Dict[str, List[UUID]] = Field(
|
@@ -171,11 +164,6 @@ class StepRunUpdate(BaseModel):
|
|
171
164
|
title="The end time of the step run.",
|
172
165
|
default=None,
|
173
166
|
)
|
174
|
-
model_version_id: Optional[UUID] = Field(
|
175
|
-
title="The ID of the model version that was "
|
176
|
-
"configured by this step run explicitly.",
|
177
|
-
default=None,
|
178
|
-
)
|
179
167
|
model_config = ConfigDict(protected_namespaces=())
|
180
168
|
|
181
169
|
|