zenml-nightly 0.71.0.dev20241212__py3-none-any.whl → 0.71.0.dev20241214__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/artifacts/artifact_config.py +8 -5
- zenml/artifacts/utils.py +3 -1
- zenml/client.py +54 -2
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +0 -1
- zenml/model/model.py +12 -16
- zenml/model/utils.py +3 -1
- zenml/models/v2/base/filter.py +26 -30
- zenml/models/v2/base/scoped.py +258 -5
- zenml/models/v2/core/artifact_version.py +15 -26
- zenml/models/v2/core/code_repository.py +1 -12
- zenml/models/v2/core/component.py +5 -46
- zenml/models/v2/core/flavor.py +1 -11
- zenml/models/v2/core/model.py +1 -57
- zenml/models/v2/core/model_version.py +5 -33
- zenml/models/v2/core/model_version_artifact.py +11 -3
- zenml/models/v2/core/model_version_pipeline_run.py +14 -3
- zenml/models/v2/core/pipeline.py +47 -55
- zenml/models/v2/core/pipeline_build.py +67 -12
- zenml/models/v2/core/pipeline_deployment.py +0 -10
- zenml/models/v2/core/pipeline_run.py +91 -29
- zenml/models/v2/core/run_template.py +21 -29
- zenml/models/v2/core/schedule.py +0 -10
- zenml/models/v2/core/secret.py +0 -14
- zenml/models/v2/core/service.py +9 -16
- zenml/models/v2/core/service_connector.py +0 -11
- zenml/models/v2/core/stack.py +21 -30
- zenml/models/v2/core/step_run.py +18 -14
- zenml/models/v2/core/trigger.py +19 -3
- zenml/orchestrators/step_launcher.py +9 -13
- zenml/orchestrators/step_run_utils.py +8 -204
- zenml/pipelines/build_utils.py +12 -0
- zenml/zen_server/rbac/rbac_sql_zen_store.py +173 -0
- zenml/zen_server/utils.py +4 -3
- zenml/zen_stores/base_zen_store.py +10 -2
- zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
- zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
- zenml/zen_stores/schemas/model_schemas.py +42 -6
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +7 -7
- zenml/zen_stores/schemas/pipeline_schemas.py +5 -0
- zenml/zen_stores/schemas/step_run_schemas.py +8 -1
- zenml/zen_stores/sql_zen_store.py +327 -99
- {zenml_nightly-0.71.0.dev20241212.dist-info → zenml_nightly-0.71.0.dev20241214.dist-info}/METADATA +1 -1
- {zenml_nightly-0.71.0.dev20241212.dist-info → zenml_nightly-0.71.0.dev20241214.dist-info}/RECORD +47 -44
- {zenml_nightly-0.71.0.dev20241212.dist-info → zenml_nightly-0.71.0.dev20241214.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.71.0.dev20241212.dist-info → zenml_nightly-0.71.0.dev20241214.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.71.0.dev20241212.dist-info → zenml_nightly-0.71.0.dev20241214.dist-info}/entry_points.txt +0 -0
@@ -15,10 +15,16 @@
|
|
15
15
|
|
16
16
|
from datetime import datetime
|
17
17
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
|
18
|
-
from uuid import UUID
|
18
|
+
from uuid import UUID, uuid4
|
19
19
|
|
20
20
|
from pydantic import ConfigDict
|
21
|
-
from sqlalchemy import
|
21
|
+
from sqlalchemy import (
|
22
|
+
BOOLEAN,
|
23
|
+
INTEGER,
|
24
|
+
TEXT,
|
25
|
+
Column,
|
26
|
+
UniqueConstraint,
|
27
|
+
)
|
22
28
|
from sqlmodel import Field, Relationship
|
23
29
|
|
24
30
|
from zenml.enums import (
|
@@ -228,11 +234,13 @@ class ModelVersionSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
228
234
|
|
229
235
|
__tablename__ = MODEL_VERSION_TABLENAME
|
230
236
|
__table_args__ = (
|
231
|
-
# We need
|
237
|
+
# We need three unique constraints here:
|
232
238
|
# - The first to ensure that each model version for a
|
233
239
|
# model has a unique version number
|
234
240
|
# - The second one to ensure that explicit names given by
|
235
241
|
# users are unique
|
242
|
+
# - The third one to ensure that a pipeline run only produces a single
|
243
|
+
# auto-incremented version per model
|
236
244
|
UniqueConstraint(
|
237
245
|
"number",
|
238
246
|
"model_id",
|
@@ -243,6 +251,11 @@ class ModelVersionSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
243
251
|
"model_id",
|
244
252
|
name="unique_version_for_model_id",
|
245
253
|
),
|
254
|
+
UniqueConstraint(
|
255
|
+
"model_id",
|
256
|
+
"producer_run_id_if_numeric",
|
257
|
+
name="unique_numeric_version_for_pipeline_run",
|
258
|
+
),
|
246
259
|
)
|
247
260
|
|
248
261
|
workspace_id: UUID = build_foreign_key_field(
|
@@ -312,12 +325,23 @@ class ModelVersionSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
312
325
|
),
|
313
326
|
)
|
314
327
|
pipeline_runs: List["PipelineRunSchema"] = Relationship(
|
315
|
-
back_populates="model_version"
|
328
|
+
back_populates="model_version",
|
316
329
|
)
|
317
330
|
step_runs: List["StepRunSchema"] = Relationship(
|
318
331
|
back_populates="model_version"
|
319
332
|
)
|
320
333
|
|
334
|
+
# We want to make sure each pipeline run only creates a single numeric
|
335
|
+
# version for each model. To solve this, we need to add a unique constraint.
|
336
|
+
# If a value of a unique constraint is NULL it is ignored and the
|
337
|
+
# remaining values in the unique constraint have to be unique. In
|
338
|
+
# our case however, we only want the unique constraint applied in
|
339
|
+
# case there is a producer run and only for numeric versions. To solve this,
|
340
|
+
# we fall back to the model version ID (which is the primary key and
|
341
|
+
# therefore unique) in case there is no producer run or the version is not
|
342
|
+
# numeric.
|
343
|
+
producer_run_id_if_numeric: UUID
|
344
|
+
|
321
345
|
# TODO: In Pydantic v2, the `model_` is a protected namespaces for all
|
322
346
|
# fields defined under base models. If not handled, this raises a warning.
|
323
347
|
# It is possible to suppress this warning message with the following
|
@@ -328,24 +352,36 @@ class ModelVersionSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
328
352
|
|
329
353
|
@classmethod
|
330
354
|
def from_request(
|
331
|
-
cls,
|
355
|
+
cls,
|
356
|
+
model_version_request: ModelVersionRequest,
|
357
|
+
model_version_number: int,
|
358
|
+
producer_run_id: Optional[UUID] = None,
|
332
359
|
) -> "ModelVersionSchema":
|
333
360
|
"""Convert an `ModelVersionRequest` to an `ModelVersionSchema`.
|
334
361
|
|
335
362
|
Args:
|
336
363
|
model_version_request: The request model version to convert.
|
364
|
+
model_version_number: The model version number.
|
365
|
+
producer_run_id: The ID of the producer run.
|
337
366
|
|
338
367
|
Returns:
|
339
368
|
The converted schema.
|
340
369
|
"""
|
370
|
+
id_ = uuid4()
|
371
|
+
is_numeric = str(model_version_number) == model_version_request.name
|
372
|
+
|
341
373
|
return cls(
|
374
|
+
id=id_,
|
342
375
|
workspace_id=model_version_request.workspace,
|
343
376
|
user_id=model_version_request.user,
|
344
377
|
model_id=model_version_request.model,
|
345
378
|
name=model_version_request.name,
|
346
|
-
number=
|
379
|
+
number=model_version_number,
|
347
380
|
description=model_version_request.description,
|
348
381
|
stage=model_version_request.stage,
|
382
|
+
producer_run_id_if_numeric=producer_run_id
|
383
|
+
if (producer_run_id and is_numeric)
|
384
|
+
else id_,
|
349
385
|
)
|
350
386
|
|
351
387
|
def to_model(
|
@@ -228,13 +228,6 @@ class PipelineDeploymentSchema(BaseSchema, table=True):
|
|
228
228
|
Returns:
|
229
229
|
The created `PipelineDeploymentResponse`.
|
230
230
|
"""
|
231
|
-
pipeline_configuration = PipelineConfiguration.model_validate_json(
|
232
|
-
self.pipeline_configuration
|
233
|
-
)
|
234
|
-
step_configurations = json.loads(self.step_configurations)
|
235
|
-
for s, c in step_configurations.items():
|
236
|
-
step_configurations[s] = Step.model_validate(c)
|
237
|
-
|
238
231
|
body = PipelineDeploymentResponseBody(
|
239
232
|
user=self.user.to_model() if self.user else None,
|
240
233
|
created=self.created,
|
@@ -242,6 +235,13 @@ class PipelineDeploymentSchema(BaseSchema, table=True):
|
|
242
235
|
)
|
243
236
|
metadata = None
|
244
237
|
if include_metadata:
|
238
|
+
pipeline_configuration = PipelineConfiguration.model_validate_json(
|
239
|
+
self.pipeline_configuration
|
240
|
+
)
|
241
|
+
step_configurations = json.loads(self.step_configurations)
|
242
|
+
for s, c in step_configurations.items():
|
243
|
+
step_configurations[s] = Step.model_validate(c)
|
244
|
+
|
245
245
|
metadata = PipelineDeploymentResponseMetadata(
|
246
246
|
workspace=self.workspace.to_model(),
|
247
247
|
run_name_template=self.run_name_template,
|
@@ -156,7 +156,12 @@ class PipelineSchema(NamedSchema, table=True):
|
|
156
156
|
|
157
157
|
resources = None
|
158
158
|
if include_resources:
|
159
|
+
latest_run_user = self.runs[-1].user if self.runs else None
|
160
|
+
|
159
161
|
resources = PipelineResponseResources(
|
162
|
+
latest_run_user=latest_run_user.to_model()
|
163
|
+
if latest_run_user
|
164
|
+
else None,
|
160
165
|
tags=[t.tag.to_model() for t in self.tags],
|
161
166
|
)
|
162
167
|
|
@@ -19,7 +19,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
|
19
19
|
from uuid import UUID
|
20
20
|
|
21
21
|
from pydantic import ConfigDict
|
22
|
-
from sqlalchemy import TEXT, Column, String
|
22
|
+
from sqlalchemy import TEXT, Column, String, UniqueConstraint
|
23
23
|
from sqlalchemy.dialects.mysql import MEDIUMTEXT
|
24
24
|
from sqlmodel import Field, Relationship, SQLModel
|
25
25
|
|
@@ -67,6 +67,13 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
|
|
67
67
|
"""SQL Model for steps of pipeline runs."""
|
68
68
|
|
69
69
|
__tablename__ = "step_run"
|
70
|
+
__table_args__ = (
|
71
|
+
UniqueConstraint(
|
72
|
+
"name",
|
73
|
+
"pipeline_run_id",
|
74
|
+
name="unique_step_name_for_pipeline_run",
|
75
|
+
),
|
76
|
+
)
|
70
77
|
|
71
78
|
# Fields
|
72
79
|
start_time: Optional[datetime] = Field(nullable=True)
|