zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250314__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.
Files changed (191) hide show
  1. zenml/VERSION +1 -1
  2. zenml/__init__.py +2 -0
  3. zenml/analytics/context.py +7 -0
  4. zenml/analytics/enums.py +2 -2
  5. zenml/artifacts/utils.py +2 -4
  6. zenml/cli/__init__.py +8 -9
  7. zenml/cli/base.py +2 -2
  8. zenml/cli/code_repository.py +1 -1
  9. zenml/cli/login.py +6 -0
  10. zenml/cli/model.py +7 -15
  11. zenml/cli/pipeline.py +3 -3
  12. zenml/cli/project.py +172 -0
  13. zenml/cli/secret.py +47 -44
  14. zenml/cli/service_accounts.py +0 -1
  15. zenml/cli/service_connectors.py +15 -17
  16. zenml/cli/stack.py +0 -3
  17. zenml/cli/stack_components.py +2 -2
  18. zenml/cli/tag.py +3 -5
  19. zenml/cli/utils.py +25 -23
  20. zenml/client.py +749 -475
  21. zenml/config/global_config.py +48 -37
  22. zenml/config/pipeline_configurations.py +3 -2
  23. zenml/config/pipeline_run_configuration.py +2 -1
  24. zenml/config/secret_reference_mixin.py +1 -1
  25. zenml/constants.py +6 -6
  26. zenml/enums.py +0 -7
  27. zenml/event_hub/event_hub.py +3 -1
  28. zenml/exceptions.py +0 -24
  29. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
  30. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
  31. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +7 -6
  32. zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
  33. zenml/integrations/mlflow/steps/mlflow_registry.py +3 -3
  34. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
  35. zenml/integrations/wandb/__init__.py +1 -1
  36. zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py +29 -9
  37. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +5 -3
  38. zenml/model/model.py +10 -10
  39. zenml/model_registries/base_model_registry.py +1 -1
  40. zenml/models/__init__.py +45 -28
  41. zenml/models/v2/base/base.py +0 -5
  42. zenml/models/v2/base/filter.py +2 -2
  43. zenml/models/v2/base/scoped.py +135 -156
  44. zenml/models/v2/core/action.py +12 -12
  45. zenml/models/v2/core/api_key.py +1 -1
  46. zenml/models/v2/core/artifact.py +31 -18
  47. zenml/models/v2/core/artifact_version.py +57 -40
  48. zenml/models/v2/core/code_repository.py +12 -12
  49. zenml/models/v2/core/component.py +22 -33
  50. zenml/models/v2/core/device.py +3 -2
  51. zenml/models/v2/core/event_source.py +14 -14
  52. zenml/models/v2/core/flavor.py +19 -47
  53. zenml/models/v2/core/logs.py +1 -2
  54. zenml/models/v2/core/model.py +23 -20
  55. zenml/models/v2/core/model_version.py +51 -42
  56. zenml/models/v2/core/pipeline.py +16 -16
  57. zenml/models/v2/core/pipeline_build.py +14 -14
  58. zenml/models/v2/core/pipeline_deployment.py +12 -14
  59. zenml/models/v2/core/pipeline_run.py +21 -29
  60. zenml/models/v2/core/project.py +203 -0
  61. zenml/models/v2/core/run_metadata.py +2 -2
  62. zenml/models/v2/core/run_template.py +16 -17
  63. zenml/models/v2/core/schedule.py +12 -21
  64. zenml/models/v2/core/secret.py +94 -128
  65. zenml/models/v2/core/server_settings.py +2 -2
  66. zenml/models/v2/core/service.py +57 -26
  67. zenml/models/v2/core/service_connector.py +14 -16
  68. zenml/models/v2/core/stack.py +24 -26
  69. zenml/models/v2/core/step_run.py +16 -28
  70. zenml/models/v2/core/tag.py +41 -15
  71. zenml/models/v2/core/trigger.py +13 -13
  72. zenml/models/v2/core/trigger_execution.py +2 -2
  73. zenml/models/v2/core/user.py +2 -2
  74. zenml/models/v2/misc/statistics.py +45 -0
  75. zenml/models/v2/misc/tag.py +27 -0
  76. zenml/orchestrators/cache_utils.py +7 -7
  77. zenml/orchestrators/input_utils.py +1 -0
  78. zenml/orchestrators/step_launcher.py +1 -2
  79. zenml/orchestrators/step_run_utils.py +2 -4
  80. zenml/orchestrators/step_runner.py +10 -1
  81. zenml/orchestrators/utils.py +4 -4
  82. zenml/pipelines/build_utils.py +2 -4
  83. zenml/pipelines/pipeline_decorator.py +3 -2
  84. zenml/pipelines/pipeline_definition.py +8 -9
  85. zenml/pipelines/run_utils.py +4 -4
  86. zenml/service_connectors/service_connector.py +0 -10
  87. zenml/service_connectors/service_connector_utils.py +0 -2
  88. zenml/stack/authentication_mixin.py +1 -1
  89. zenml/stack/flavor.py +3 -14
  90. zenml/stack/stack.py +0 -1
  91. zenml/stack/stack_component.py +1 -5
  92. zenml/steps/base_step.py +10 -2
  93. zenml/steps/step_context.py +19 -0
  94. zenml/utils/string_utils.py +1 -1
  95. zenml/utils/tag_utils.py +642 -0
  96. zenml/zen_server/cloud_utils.py +21 -0
  97. zenml/zen_server/exceptions.py +0 -6
  98. zenml/zen_server/rbac/endpoint_utils.py +134 -46
  99. zenml/zen_server/rbac/models.py +65 -3
  100. zenml/zen_server/rbac/rbac_interface.py +9 -0
  101. zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
  102. zenml/zen_server/rbac/utils.py +155 -30
  103. zenml/zen_server/rbac/zenml_cloud_rbac.py +39 -11
  104. zenml/zen_server/routers/actions_endpoints.py +3 -5
  105. zenml/zen_server/routers/artifact_endpoint.py +0 -5
  106. zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
  107. zenml/zen_server/routers/auth_endpoints.py +22 -7
  108. zenml/zen_server/routers/code_repositories_endpoints.py +54 -3
  109. zenml/zen_server/routers/devices_endpoints.py +0 -4
  110. zenml/zen_server/routers/event_source_endpoints.py +0 -5
  111. zenml/zen_server/routers/flavors_endpoints.py +0 -5
  112. zenml/zen_server/routers/logs_endpoints.py +0 -1
  113. zenml/zen_server/routers/model_versions_endpoints.py +100 -23
  114. zenml/zen_server/routers/models_endpoints.py +50 -69
  115. zenml/zen_server/routers/pipeline_builds_endpoints.py +55 -3
  116. zenml/zen_server/routers/pipeline_deployments_endpoints.py +56 -4
  117. zenml/zen_server/routers/pipelines_endpoints.py +70 -3
  118. zenml/zen_server/routers/plugin_endpoints.py +0 -1
  119. zenml/zen_server/routers/projects_endpoints.py +283 -0
  120. zenml/zen_server/routers/run_metadata_endpoints.py +97 -0
  121. zenml/zen_server/routers/run_templates_endpoints.py +64 -3
  122. zenml/zen_server/routers/runs_endpoints.py +58 -8
  123. zenml/zen_server/routers/schedule_endpoints.py +67 -6
  124. zenml/zen_server/routers/secrets_endpoints.py +38 -4
  125. zenml/zen_server/routers/server_endpoints.py +53 -1
  126. zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
  127. zenml/zen_server/routers/service_connectors_endpoints.py +94 -14
  128. zenml/zen_server/routers/service_endpoints.py +18 -7
  129. zenml/zen_server/routers/stack_components_endpoints.py +66 -7
  130. zenml/zen_server/routers/stacks_endpoints.py +95 -6
  131. zenml/zen_server/routers/steps_endpoints.py +17 -11
  132. zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
  133. zenml/zen_server/routers/tags_endpoints.py +6 -17
  134. zenml/zen_server/routers/triggers_endpoints.py +5 -8
  135. zenml/zen_server/routers/users_endpoints.py +9 -12
  136. zenml/zen_server/template_execution/utils.py +8 -7
  137. zenml/zen_server/utils.py +21 -0
  138. zenml/zen_server/zen_server_api.py +7 -2
  139. zenml/zen_stores/base_zen_store.py +50 -69
  140. zenml/zen_stores/migrations/versions/12eff0206201_rename_workspace_to_project.py +768 -0
  141. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
  142. zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
  143. zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
  144. zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
  145. zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
  146. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
  147. zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
  148. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
  149. zenml/zen_stores/migrations/versions/cbc6acd71f92_add_workspace_display_name.py +58 -0
  150. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
  151. zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
  152. zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
  153. zenml/zen_stores/rest_zen_store.py +223 -230
  154. zenml/zen_stores/schemas/__init__.py +2 -2
  155. zenml/zen_stores/schemas/action_schemas.py +15 -8
  156. zenml/zen_stores/schemas/api_key_schemas.py +8 -1
  157. zenml/zen_stores/schemas/artifact_schemas.py +35 -10
  158. zenml/zen_stores/schemas/code_repository_schemas.py +22 -17
  159. zenml/zen_stores/schemas/component_schemas.py +9 -14
  160. zenml/zen_stores/schemas/event_source_schemas.py +15 -8
  161. zenml/zen_stores/schemas/flavor_schemas.py +14 -20
  162. zenml/zen_stores/schemas/model_schemas.py +18 -17
  163. zenml/zen_stores/schemas/pipeline_build_schemas.py +7 -7
  164. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +10 -8
  165. zenml/zen_stores/schemas/pipeline_run_schemas.py +9 -12
  166. zenml/zen_stores/schemas/pipeline_schemas.py +9 -9
  167. zenml/zen_stores/schemas/{workspace_schemas.py → project_schemas.py} +53 -65
  168. zenml/zen_stores/schemas/run_metadata_schemas.py +5 -5
  169. zenml/zen_stores/schemas/run_template_schemas.py +17 -13
  170. zenml/zen_stores/schemas/schedule_schema.py +16 -21
  171. zenml/zen_stores/schemas/secret_schemas.py +15 -25
  172. zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
  173. zenml/zen_stores/schemas/service_schemas.py +7 -8
  174. zenml/zen_stores/schemas/stack_schemas.py +12 -15
  175. zenml/zen_stores/schemas/step_run_schemas.py +14 -15
  176. zenml/zen_stores/schemas/tag_schemas.py +30 -2
  177. zenml/zen_stores/schemas/trigger_schemas.py +15 -8
  178. zenml/zen_stores/schemas/user_schemas.py +12 -2
  179. zenml/zen_stores/schemas/utils.py +16 -0
  180. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
  181. zenml/zen_stores/sql_zen_store.py +2984 -2369
  182. zenml/zen_stores/template_utils.py +1 -1
  183. zenml/zen_stores/zen_store_interface.py +136 -126
  184. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/METADATA +1 -1
  185. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/RECORD +188 -173
  186. zenml/cli/workspace.py +0 -86
  187. zenml/models/v2/core/workspace.py +0 -131
  188. zenml/zen_server/routers/workspaces_endpoints.py +0 -1469
  189. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/LICENSE +0 -0
  190. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/WHEEL +0 -0
  191. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/entry_points.txt +0 -0
@@ -17,6 +17,7 @@ from datetime import datetime, timedelta
17
17
  from typing import TYPE_CHECKING, Any, List, Optional
18
18
  from uuid import UUID
19
19
 
20
+ from sqlalchemy import UniqueConstraint
20
21
  from sqlmodel import Field, Relationship
21
22
 
22
23
  from zenml.enums import MetadataResourceTypes
@@ -31,10 +32,10 @@ from zenml.utils.time_utils import utc_now
31
32
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
32
33
  from zenml.zen_stores.schemas.component_schemas import StackComponentSchema
33
34
  from zenml.zen_stores.schemas.pipeline_schemas import PipelineSchema
35
+ from zenml.zen_stores.schemas.project_schemas import ProjectSchema
34
36
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
35
37
  from zenml.zen_stores.schemas.user_schemas import UserSchema
36
38
  from zenml.zen_stores.schemas.utils import RunMetadataInterface
37
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
38
39
 
39
40
  if TYPE_CHECKING:
40
41
  from zenml.zen_stores.schemas.pipeline_deployment_schemas import (
@@ -49,16 +50,23 @@ class ScheduleSchema(NamedSchema, RunMetadataInterface, table=True):
49
50
  """SQL Model for schedules."""
50
51
 
51
52
  __tablename__ = "schedule"
53
+ __table_args__ = (
54
+ UniqueConstraint(
55
+ "name",
56
+ "project_id",
57
+ name="unique_schedule_name_in_project",
58
+ ),
59
+ )
52
60
 
53
- workspace_id: UUID = build_foreign_key_field(
61
+ project_id: UUID = build_foreign_key_field(
54
62
  source=__tablename__,
55
- target=WorkspaceSchema.__tablename__,
56
- source_column="workspace_id",
63
+ target=ProjectSchema.__tablename__,
64
+ source_column="project_id",
57
65
  target_column="id",
58
66
  ondelete="CASCADE",
59
67
  nullable=False,
60
68
  )
61
- workspace: "WorkspaceSchema" = Relationship(back_populates="schedules")
69
+ project: "ProjectSchema" = Relationship(back_populates="schedules")
62
70
 
63
71
  user_id: Optional[UUID] = build_foreign_key_field(
64
72
  source=__tablename__,
@@ -130,7 +138,7 @@ class ScheduleSchema(NamedSchema, RunMetadataInterface, table=True):
130
138
  interval_second = None
131
139
  return cls(
132
140
  name=schedule_request.name,
133
- workspace_id=schedule_request.workspace,
141
+ project_id=schedule_request.project,
134
142
  user_id=schedule_request.user,
135
143
  pipeline_id=schedule_request.pipeline_id,
136
144
  orchestrator_id=schedule_request.orchestrator_id,
@@ -154,20 +162,7 @@ class ScheduleSchema(NamedSchema, RunMetadataInterface, table=True):
154
162
  """
155
163
  if schedule_update.name is not None:
156
164
  self.name = schedule_update.name
157
- if schedule_update.active is not None:
158
- self.active = schedule_update.active
159
- if schedule_update.cron_expression is not None:
160
- self.cron_expression = schedule_update.cron_expression
161
- if schedule_update.start_time is not None:
162
- self.start_time = schedule_update.start_time
163
- if schedule_update.end_time is not None:
164
- self.end_time = schedule_update.end_time
165
- if schedule_update.interval_second is not None:
166
- self.interval_second = (
167
- schedule_update.interval_second.total_seconds()
168
- )
169
- if schedule_update.catchup is not None:
170
- self.catchup = schedule_update.catchup
165
+
171
166
  self.updated = utc_now()
172
167
  return self
173
168
 
@@ -208,7 +203,7 @@ class ScheduleSchema(NamedSchema, RunMetadataInterface, table=True):
208
203
  metadata = None
209
204
  if include_metadata:
210
205
  metadata = ScheduleResponseMetadata(
211
- workspace=self.workspace.to_model(),
206
+ project=self.project.to_model(),
212
207
  pipeline_id=self.pipeline_id,
213
208
  orchestrator_id=self.orchestrator_id,
214
209
  run_metadata=self.fetch_metadata(),
@@ -18,7 +18,7 @@ import json
18
18
  from typing import Any, Dict, Optional, cast
19
19
  from uuid import UUID
20
20
 
21
- from sqlalchemy import TEXT, Column
21
+ from sqlalchemy import TEXT, Column, UniqueConstraint
22
22
  from sqlalchemy_utils.types.encrypted.encrypted_type import (
23
23
  AesGcmEngine,
24
24
  InvalidCiphertextError,
@@ -26,7 +26,6 @@ from sqlalchemy_utils.types.encrypted.encrypted_type import (
26
26
  from sqlmodel import Field, Relationship
27
27
 
28
28
  from zenml.constants import TEXT_FIELD_MAX_LENGTH
29
- from zenml.enums import SecretScope
30
29
  from zenml.models import (
31
30
  SecretRequest,
32
31
  SecretResponse,
@@ -38,7 +37,6 @@ from zenml.utils.time_utils import utc_now
38
37
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
39
38
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
40
39
  from zenml.zen_stores.schemas.user_schemas import UserSchema
41
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
42
40
 
43
41
 
44
42
  class SecretDecodeError(Exception):
@@ -54,21 +52,19 @@ class SecretSchema(NamedSchema, table=True):
54
52
  """
55
53
 
56
54
  __tablename__ = "secret"
55
+ __table_args__ = (
56
+ UniqueConstraint(
57
+ "name",
58
+ "private",
59
+ "user_id",
60
+ name="unique_secret_name_private_scope_user",
61
+ ),
62
+ )
57
63
 
58
- scope: str
64
+ private: bool
59
65
 
60
66
  values: Optional[bytes] = Field(sa_column=Column(TEXT, nullable=True))
61
67
 
62
- workspace_id: UUID = build_foreign_key_field(
63
- source=__tablename__,
64
- target=WorkspaceSchema.__tablename__,
65
- source_column="workspace_id",
66
- target_column="id",
67
- ondelete="CASCADE",
68
- nullable=False,
69
- )
70
- workspace: "WorkspaceSchema" = Relationship(back_populates="secrets")
71
-
72
68
  user_id: UUID = build_foreign_key_field(
73
69
  source=__tablename__,
74
70
  target=UserSchema.__tablename__,
@@ -177,8 +173,7 @@ class SecretSchema(NamedSchema, table=True):
177
173
  assert secret.user is not None, "User must be set for secret creation."
178
174
  return cls(
179
175
  name=secret.name,
180
- scope=secret.scope.value,
181
- workspace_id=secret.workspace,
176
+ private=secret.private,
182
177
  user_id=secret.user,
183
178
  # Don't store secret values implicitly in the secret. The
184
179
  # SQL secret store will call `store_secret_values` to store the
@@ -202,12 +197,9 @@ class SecretSchema(NamedSchema, table=True):
202
197
  # SQL secret store will call `set_secret_values` to update the
203
198
  # values separately if SQL is used as the secrets store.
204
199
  for field, value in secret_update.model_dump(
205
- exclude_unset=True, exclude={"workspace", "user", "values"}
200
+ exclude_unset=True, exclude={"user", "values"}
206
201
  ).items():
207
- if field == "scope":
208
- setattr(self, field, value.value)
209
- else:
210
- setattr(self, field, value)
202
+ setattr(self, field, value)
211
203
 
212
204
  self.updated = utc_now()
213
205
  return self
@@ -231,9 +223,7 @@ class SecretSchema(NamedSchema, table=True):
231
223
  """
232
224
  metadata = None
233
225
  if include_metadata:
234
- metadata = SecretResponseMetadata(
235
- workspace=self.workspace.to_model(),
236
- )
226
+ metadata = SecretResponseMetadata()
237
227
 
238
228
  # Don't load the secret values implicitly in the secret. The
239
229
  # SQL secret store will call `get_secret_values` to load the
@@ -242,7 +232,7 @@ class SecretSchema(NamedSchema, table=True):
242
232
  user=self.user.to_model() if self.user else None,
243
233
  created=self.created,
244
234
  updated=self.updated,
245
- scope=SecretScope(self.scope),
235
+ private=self.private,
246
236
  )
247
237
  return SecretResponse(
248
238
  id=self.id,
@@ -19,7 +19,7 @@ from datetime import datetime
19
19
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
20
20
  from uuid import UUID
21
21
 
22
- from sqlalchemy import TEXT, Column
22
+ from sqlalchemy import TEXT, Column, UniqueConstraint
23
23
  from sqlmodel import Field, Relationship
24
24
 
25
25
  from zenml.models import (
@@ -33,7 +33,6 @@ from zenml.utils.time_utils import utc_now
33
33
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
34
34
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
35
35
  from zenml.zen_stores.schemas.user_schemas import UserSchema
36
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
37
36
 
38
37
  if TYPE_CHECKING:
39
38
  from zenml.zen_stores.schemas.component_schemas import StackComponentSchema
@@ -43,6 +42,12 @@ class ServiceConnectorSchema(NamedSchema, table=True):
43
42
  """SQL Model for service connectors."""
44
43
 
45
44
  __tablename__ = "service_connector"
45
+ __table_args__ = (
46
+ UniqueConstraint(
47
+ "name",
48
+ name="unique_service_connector_name",
49
+ ),
50
+ )
46
51
 
47
52
  connector_type: str = Field(sa_column=Column(TEXT))
48
53
  description: str
@@ -57,18 +62,6 @@ class ServiceConnectorSchema(NamedSchema, table=True):
57
62
  expiration_seconds: Optional[int]
58
63
  labels: Optional[bytes]
59
64
 
60
- workspace_id: UUID = build_foreign_key_field(
61
- source=__tablename__,
62
- target=WorkspaceSchema.__tablename__,
63
- source_column="workspace_id",
64
- target_column="id",
65
- ondelete="CASCADE",
66
- nullable=False,
67
- )
68
- workspace: "WorkspaceSchema" = Relationship(
69
- back_populates="service_connectors"
70
- )
71
-
72
65
  user_id: Optional[UUID] = build_foreign_key_field(
73
66
  source=__tablename__,
74
67
  target=UserSchema.__tablename__,
@@ -146,7 +139,6 @@ class ServiceConnectorSchema(NamedSchema, table=True):
146
139
  """
147
140
  assert connector_request.user is not None, "User must be set."
148
141
  return cls(
149
- workspace_id=connector_request.workspace,
150
142
  user_id=connector_request.user,
151
143
  name=connector_request.name,
152
144
  description=connector_request.description,
@@ -189,7 +181,7 @@ class ServiceConnectorSchema(NamedSchema, table=True):
189
181
  """
190
182
  for field, value in connector_update.model_dump(
191
183
  exclude_unset=False,
192
- exclude={"workspace", "user", "secrets"},
184
+ exclude={"user", "secrets"},
193
185
  ).items():
194
186
  if value is None:
195
187
  if field == "resource_id":
@@ -264,7 +256,6 @@ class ServiceConnectorSchema(NamedSchema, table=True):
264
256
  metadata = None
265
257
  if include_metadata:
266
258
  metadata = ServiceConnectorResponseMetadata(
267
- workspace=self.workspace.to_model(),
268
259
  configuration=json.loads(
269
260
  base64.b64decode(self.configuration).decode()
270
261
  )
@@ -35,9 +35,9 @@ from zenml.utils.time_utils import utc_now
35
35
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
36
36
  from zenml.zen_stores.schemas.model_schemas import ModelVersionSchema
37
37
  from zenml.zen_stores.schemas.pipeline_run_schemas import PipelineRunSchema
38
+ from zenml.zen_stores.schemas.project_schemas import ProjectSchema
38
39
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
39
40
  from zenml.zen_stores.schemas.user_schemas import UserSchema
40
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
41
41
 
42
42
 
43
43
  class ServiceSchema(NamedSchema, table=True):
@@ -45,15 +45,15 @@ class ServiceSchema(NamedSchema, table=True):
45
45
 
46
46
  __tablename__ = "service"
47
47
 
48
- workspace_id: UUID = build_foreign_key_field(
48
+ project_id: UUID = build_foreign_key_field(
49
49
  source=__tablename__,
50
- target=WorkspaceSchema.__tablename__,
51
- source_column="workspace_id",
50
+ target=ProjectSchema.__tablename__,
51
+ source_column="project_id",
52
52
  target_column="id",
53
53
  ondelete="CASCADE",
54
54
  nullable=False,
55
55
  )
56
- workspace: "WorkspaceSchema" = Relationship(back_populates="services")
56
+ project: "ProjectSchema" = Relationship(back_populates="services")
57
57
 
58
58
  user_id: Optional[UUID] = build_foreign_key_field(
59
59
  source=__tablename__,
@@ -135,7 +135,6 @@ class ServiceSchema(NamedSchema, table=True):
135
135
  """
136
136
  body = ServiceResponseBody(
137
137
  user=self.user.to_model() if self.user else None,
138
- workspace=self.workspace.to_model(),
139
138
  created=self.created,
140
139
  updated=self.updated,
141
140
  service_type=json.loads(self.service_type),
@@ -147,7 +146,7 @@ class ServiceSchema(NamedSchema, table=True):
147
146
  metadata = None
148
147
  if include_metadata:
149
148
  metadata = ServiceResponseMetadata(
150
- workspace=self.workspace.to_model(),
149
+ project=self.project.to_model(),
151
150
  service_source=self.service_source,
152
151
  config=json.loads(base64.b64decode(self.config).decode()),
153
152
  status=json.loads(base64.b64decode(self.status).decode())
@@ -227,7 +226,7 @@ class ServiceSchema(NamedSchema, table=True):
227
226
  """
228
227
  return cls(
229
228
  name=service_request.name,
230
- workspace_id=service_request.workspace,
229
+ project_id=service_request.project,
231
230
  user_id=service_request.user,
232
231
  service_source=service_request.service_source,
233
232
  service_type=service_request.service_type.model_dump_json(),
@@ -18,7 +18,8 @@ import json
18
18
  from typing import TYPE_CHECKING, Any, List, Optional
19
19
  from uuid import UUID
20
20
 
21
- from sqlmodel import Relationship, SQLModel
21
+ from sqlalchemy import UniqueConstraint
22
+ from sqlmodel import Field, Relationship, SQLModel
22
23
 
23
24
  from zenml.models import (
24
25
  StackResponse,
@@ -30,7 +31,6 @@ from zenml.utils.time_utils import utc_now
30
31
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
31
32
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
32
33
  from zenml.zen_stores.schemas.user_schemas import UserSchema
33
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
34
34
 
35
35
  if TYPE_CHECKING:
36
36
  from zenml.zen_stores.schemas.component_schemas import (
@@ -76,19 +76,17 @@ class StackSchema(NamedSchema, table=True):
76
76
  """SQL Model for stacks."""
77
77
 
78
78
  __tablename__ = "stack"
79
+ __table_args__ = (
80
+ UniqueConstraint(
81
+ "name",
82
+ name="unique_stack_name",
83
+ ),
84
+ )
85
+
86
+ description: Optional[str] = Field(default=None)
79
87
  stack_spec_path: Optional[str]
80
88
  labels: Optional[bytes]
81
89
 
82
- workspace_id: UUID = build_foreign_key_field(
83
- source=__tablename__,
84
- target=WorkspaceSchema.__tablename__,
85
- source_column="workspace_id",
86
- target_column="id",
87
- ondelete="CASCADE",
88
- nullable=False,
89
- )
90
- workspace: "WorkspaceSchema" = Relationship(back_populates="stacks")
91
-
92
90
  user_id: Optional[UUID] = build_foreign_key_field(
93
91
  source=__tablename__,
94
92
  target=UserSchema.__tablename__,
@@ -123,7 +121,7 @@ class StackSchema(NamedSchema, table=True):
123
121
  The updated StackSchema.
124
122
  """
125
123
  for field, value in stack_update.model_dump(
126
- exclude_unset=True, exclude={"workspace", "user"}
124
+ exclude_unset=True, exclude={"user"}
127
125
  ).items():
128
126
  if field == "components":
129
127
  self.components = components
@@ -150,7 +148,6 @@ class StackSchema(NamedSchema, table=True):
150
148
  include_resources: Whether the resources will be filled.
151
149
  **kwargs: Keyword arguments to allow schema specific logic
152
150
 
153
-
154
151
  Returns:
155
152
  The converted model.
156
153
  """
@@ -162,12 +159,12 @@ class StackSchema(NamedSchema, table=True):
162
159
  metadata = None
163
160
  if include_metadata:
164
161
  metadata = StackResponseMetadata(
165
- workspace=self.workspace.to_model(),
166
162
  components={c.type: [c.to_model()] for c in self.components},
167
163
  stack_spec_path=self.stack_spec_path,
168
164
  labels=json.loads(base64.b64decode(self.labels).decode())
169
165
  if self.labels
170
166
  else None,
167
+ description=self.description,
171
168
  )
172
169
 
173
170
  return StackResponse(
@@ -50,10 +50,10 @@ from zenml.zen_stores.schemas.pipeline_deployment_schemas import (
50
50
  PipelineDeploymentSchema,
51
51
  )
52
52
  from zenml.zen_stores.schemas.pipeline_run_schemas import PipelineRunSchema
53
+ from zenml.zen_stores.schemas.project_schemas import ProjectSchema
53
54
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
54
55
  from zenml.zen_stores.schemas.user_schemas import UserSchema
55
56
  from zenml.zen_stores.schemas.utils import RunMetadataInterface
56
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
57
57
 
58
58
  if TYPE_CHECKING:
59
59
  from zenml.zen_stores.schemas.artifact_schemas import ArtifactVersionSchema
@@ -102,7 +102,7 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
102
102
  ondelete="SET NULL",
103
103
  nullable=True,
104
104
  )
105
- deployment_id: UUID = build_foreign_key_field(
105
+ deployment_id: Optional[UUID] = build_foreign_key_field(
106
106
  source=__tablename__,
107
107
  target=PipelineDeploymentSchema.__tablename__,
108
108
  source_column="deployment_id",
@@ -126,15 +126,15 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
126
126
  ondelete="SET NULL",
127
127
  nullable=True,
128
128
  )
129
- workspace_id: UUID = build_foreign_key_field(
129
+ project_id: UUID = build_foreign_key_field(
130
130
  source=__tablename__,
131
- target=WorkspaceSchema.__tablename__,
132
- source_column="workspace_id",
131
+ target=ProjectSchema.__tablename__,
132
+ source_column="project_id",
133
133
  target_column="id",
134
134
  ondelete="CASCADE",
135
135
  nullable=False,
136
136
  )
137
- model_version_id: UUID = build_foreign_key_field(
137
+ model_version_id: Optional[UUID] = build_foreign_key_field(
138
138
  source=__tablename__,
139
139
  target=MODEL_VERSION_TABLENAME,
140
140
  source_column="model_version_id",
@@ -144,7 +144,7 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
144
144
  )
145
145
 
146
146
  # Relationships
147
- workspace: "WorkspaceSchema" = Relationship(back_populates="step_runs")
147
+ project: "ProjectSchema" = Relationship(back_populates="step_runs")
148
148
  user: Optional["UserSchema"] = Relationship(back_populates="step_runs")
149
149
  deployment: Optional["PipelineDeploymentSchema"] = Relationship(
150
150
  back_populates="step_runs"
@@ -186,30 +186,32 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
186
186
  model_config = ConfigDict(protected_namespaces=()) # type: ignore[assignment]
187
187
 
188
188
  @classmethod
189
- def from_request(cls, request: StepRunRequest) -> "StepRunSchema":
189
+ def from_request(
190
+ cls, request: StepRunRequest, deployment_id: Optional[UUID]
191
+ ) -> "StepRunSchema":
190
192
  """Create a step run schema from a step run request model.
191
193
 
192
194
  Args:
193
195
  request: The step run request model.
196
+ deployment_id: The deployment ID.
194
197
 
195
198
  Returns:
196
199
  The step run schema.
197
200
  """
198
201
  return cls(
199
202
  name=request.name,
200
- workspace_id=request.workspace,
203
+ project_id=request.project,
201
204
  user_id=request.user,
202
205
  start_time=request.start_time,
203
206
  end_time=request.end_time,
204
207
  status=request.status.value,
208
+ deployment_id=deployment_id,
205
209
  original_step_run_id=request.original_step_run_id,
206
210
  pipeline_run_id=request.pipeline_run_id,
207
- deployment_id=request.deployment,
208
211
  docstring=request.docstring,
209
212
  cache_key=request.cache_key,
210
213
  code_hash=request.code_hash,
211
214
  source_code=request.source_code,
212
- model_version_id=request.model_version_id,
213
215
  )
214
216
 
215
217
  def to_model(
@@ -308,7 +310,7 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
308
310
  metadata = None
309
311
  if include_metadata:
310
312
  metadata = StepRunResponseMetadata(
311
- workspace=self.workspace.to_model(),
313
+ project=self.project.to_model(),
312
314
  config=full_step_config.config,
313
315
  spec=full_step_config.spec,
314
316
  cache_key=self.cache_key,
@@ -355,9 +357,6 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
355
357
  self.status = value.value
356
358
  if key == "end_time":
357
359
  self.end_time = value
358
- if key == "model_version_id":
359
- if value and self.model_version_id is None:
360
- self.model_version_id = value
361
360
 
362
361
  self.updated = utc_now()
363
362
 
@@ -13,10 +13,10 @@
13
13
  # permissions and limitations under the License.
14
14
  """SQLModel implementation of tag tables."""
15
15
 
16
- from typing import Any, List
16
+ from typing import Any, List, Optional
17
17
  from uuid import UUID
18
18
 
19
- from sqlalchemy import VARCHAR, Column
19
+ from sqlalchemy import VARCHAR, Column, UniqueConstraint
20
20
  from sqlmodel import Field, Relationship
21
21
 
22
22
  from zenml.enums import ColorVariants, TaggableResourceTypes
@@ -27,6 +27,7 @@ from zenml.models import (
27
27
  TagResourceResponseBody,
28
28
  TagResponse,
29
29
  TagResponseBody,
30
+ TagResponseMetadata,
30
31
  TagUpdate,
31
32
  )
32
33
  from zenml.utils.time_utils import utc_now
@@ -35,14 +36,33 @@ from zenml.zen_stores.schemas.schema_utils import (
35
36
  build_foreign_key_field,
36
37
  build_index,
37
38
  )
39
+ from zenml.zen_stores.schemas.user_schemas import UserSchema
38
40
 
39
41
 
40
42
  class TagSchema(NamedSchema, table=True):
41
43
  """SQL Model for tag."""
42
44
 
43
45
  __tablename__ = "tag"
46
+ __table_args__ = (
47
+ UniqueConstraint(
48
+ "name",
49
+ name="unique_tag_name",
50
+ ),
51
+ )
52
+
53
+ user_id: Optional[UUID] = build_foreign_key_field(
54
+ source=__tablename__,
55
+ target=UserSchema.__tablename__,
56
+ source_column="user_id",
57
+ target_column="id",
58
+ ondelete="SET NULL",
59
+ nullable=True,
60
+ )
61
+ user: Optional["UserSchema"] = Relationship(back_populates="tags")
44
62
 
45
63
  color: str = Field(sa_column=Column(VARCHAR(255), nullable=False))
64
+ exclusive: bool = Field(default=False)
65
+
46
66
  links: List["TagResourceSchema"] = Relationship(
47
67
  back_populates="tag",
48
68
  sa_relationship_kwargs={"overlaps": "tags", "cascade": "delete"},
@@ -60,7 +80,9 @@ class TagSchema(NamedSchema, table=True):
60
80
  """
61
81
  return cls(
62
82
  name=request.name,
83
+ exclusive=request.exclusive,
63
84
  color=request.color.value,
85
+ user_id=request.user,
64
86
  )
65
87
 
66
88
  def to_model(
@@ -80,15 +102,21 @@ class TagSchema(NamedSchema, table=True):
80
102
  Returns:
81
103
  The created `TagResponse`.
82
104
  """
105
+ metadata = None
106
+ if include_metadata:
107
+ metadata = TagResponseMetadata()
83
108
  return TagResponse(
84
109
  id=self.id,
85
110
  name=self.name,
86
111
  body=TagResponseBody(
112
+ user=self.user.to_model() if self.user else None,
87
113
  created=self.created,
88
114
  updated=self.updated,
89
115
  color=ColorVariants(self.color),
116
+ exclusive=self.exclusive,
90
117
  tagged_count=len(self.links),
91
118
  ),
119
+ metadata=metadata,
92
120
  )
93
121
 
94
122
  def update(self, update: TagUpdate) -> "TagSchema":
@@ -18,7 +18,7 @@ import json
18
18
  from typing import Any, List, Optional, cast
19
19
  from uuid import UUID
20
20
 
21
- from sqlalchemy import TEXT, Column
21
+ from sqlalchemy import TEXT, Column, UniqueConstraint
22
22
  from sqlmodel import Field, Relationship
23
23
 
24
24
  from zenml.config.schedule import Schedule
@@ -41,26 +41,33 @@ from zenml.utils.time_utils import utc_now
41
41
  from zenml.zen_stores.schemas.action_schemas import ActionSchema
42
42
  from zenml.zen_stores.schemas.base_schemas import BaseSchema, NamedSchema
43
43
  from zenml.zen_stores.schemas.event_source_schemas import EventSourceSchema
44
+ from zenml.zen_stores.schemas.project_schemas import ProjectSchema
44
45
  from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
45
46
  from zenml.zen_stores.schemas.user_schemas import UserSchema
46
47
  from zenml.zen_stores.schemas.utils import get_page_from_list
47
- from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
48
48
 
49
49
 
50
50
  class TriggerSchema(NamedSchema, table=True):
51
51
  """SQL Model for triggers."""
52
52
 
53
53
  __tablename__ = "trigger"
54
+ __table_args__ = (
55
+ UniqueConstraint(
56
+ "name",
57
+ "project_id",
58
+ name="unique_trigger_name_in_project",
59
+ ),
60
+ )
54
61
 
55
- workspace_id: UUID = build_foreign_key_field(
62
+ project_id: UUID = build_foreign_key_field(
56
63
  source=__tablename__,
57
- target=WorkspaceSchema.__tablename__,
58
- source_column="workspace_id",
64
+ target=ProjectSchema.__tablename__,
65
+ source_column="project_id",
59
66
  target_column="id",
60
67
  ondelete="CASCADE",
61
68
  nullable=False,
62
69
  )
63
- workspace: "WorkspaceSchema" = Relationship(back_populates="triggers")
70
+ project: "ProjectSchema" = Relationship(back_populates="triggers")
64
71
 
65
72
  user_id: Optional[UUID] = build_foreign_key_field(
66
73
  source=__tablename__,
@@ -148,7 +155,7 @@ class TriggerSchema(NamedSchema, table=True):
148
155
  """
149
156
  return cls(
150
157
  name=request.name,
151
- workspace_id=request.workspace,
158
+ project_id=request.project,
152
159
  user_id=request.user,
153
160
  action_id=request.action_id,
154
161
  event_source_id=request.event_source_id,
@@ -201,7 +208,7 @@ class TriggerSchema(NamedSchema, table=True):
201
208
  metadata = None
202
209
  if include_metadata:
203
210
  metadata = TriggerResponseMetadata(
204
- workspace=self.workspace.to_model(),
211
+ project=self.project.to_model(),
205
212
  event_filter=json.loads(
206
213
  base64.b64decode(self.event_filter).decode()
207
214
  ),