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.
Files changed (160) hide show
  1. zenml/VERSION +1 -1
  2. zenml/__init__.py +2 -0
  3. zenml/analytics/context.py +7 -0
  4. zenml/artifacts/utils.py +0 -2
  5. zenml/cli/login.py +6 -0
  6. zenml/cli/model.py +7 -15
  7. zenml/cli/secret.py +47 -44
  8. zenml/cli/service_connectors.py +0 -1
  9. zenml/cli/stack.py +0 -1
  10. zenml/cli/tag.py +3 -5
  11. zenml/cli/utils.py +25 -23
  12. zenml/cli/workspace.py +79 -5
  13. zenml/client.py +615 -348
  14. zenml/config/global_config.py +16 -3
  15. zenml/config/pipeline_configurations.py +3 -2
  16. zenml/config/pipeline_run_configuration.py +2 -1
  17. zenml/config/secret_reference_mixin.py +1 -1
  18. zenml/constants.py +1 -3
  19. zenml/enums.py +0 -7
  20. zenml/event_hub/event_hub.py +3 -1
  21. zenml/exceptions.py +0 -24
  22. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
  23. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
  24. zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
  25. zenml/integrations/mlflow/steps/mlflow_registry.py +1 -1
  26. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
  27. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +3 -3
  28. zenml/model/model.py +8 -8
  29. zenml/models/__init__.py +18 -1
  30. zenml/models/v2/base/base.py +0 -5
  31. zenml/models/v2/base/filter.py +1 -1
  32. zenml/models/v2/base/scoped.py +104 -121
  33. zenml/models/v2/core/api_key.py +1 -1
  34. zenml/models/v2/core/artifact.py +31 -18
  35. zenml/models/v2/core/artifact_version.py +42 -25
  36. zenml/models/v2/core/component.py +22 -33
  37. zenml/models/v2/core/device.py +3 -2
  38. zenml/models/v2/core/event_source.py +2 -2
  39. zenml/models/v2/core/flavor.py +19 -47
  40. zenml/models/v2/core/logs.py +1 -2
  41. zenml/models/v2/core/model.py +7 -4
  42. zenml/models/v2/core/model_version.py +36 -27
  43. zenml/models/v2/core/pipeline.py +1 -1
  44. zenml/models/v2/core/pipeline_run.py +5 -13
  45. zenml/models/v2/core/run_template.py +1 -2
  46. zenml/models/v2/core/schedule.py +0 -9
  47. zenml/models/v2/core/secret.py +93 -127
  48. zenml/models/v2/core/server_settings.py +2 -2
  49. zenml/models/v2/core/service.py +43 -12
  50. zenml/models/v2/core/service_connector.py +14 -16
  51. zenml/models/v2/core/stack.py +24 -26
  52. zenml/models/v2/core/step_run.py +3 -15
  53. zenml/models/v2/core/tag.py +41 -15
  54. zenml/models/v2/core/user.py +19 -2
  55. zenml/models/v2/misc/statistics.py +45 -0
  56. zenml/models/v2/misc/tag.py +27 -0
  57. zenml/orchestrators/cache_utils.py +1 -1
  58. zenml/orchestrators/input_utils.py +1 -0
  59. zenml/orchestrators/step_launcher.py +0 -1
  60. zenml/orchestrators/step_run_utils.py +0 -2
  61. zenml/orchestrators/step_runner.py +10 -1
  62. zenml/pipelines/build_utils.py +0 -2
  63. zenml/pipelines/pipeline_decorator.py +3 -2
  64. zenml/pipelines/pipeline_definition.py +4 -5
  65. zenml/pipelines/run_utils.py +3 -3
  66. zenml/service_connectors/service_connector.py +0 -7
  67. zenml/service_connectors/service_connector_utils.py +0 -1
  68. zenml/stack/authentication_mixin.py +1 -1
  69. zenml/stack/flavor.py +3 -14
  70. zenml/stack/stack_component.py +1 -5
  71. zenml/steps/step_context.py +19 -0
  72. zenml/utils/string_utils.py +1 -1
  73. zenml/utils/tag_utils.py +642 -0
  74. zenml/zen_server/cloud_utils.py +21 -0
  75. zenml/zen_server/exceptions.py +0 -6
  76. zenml/zen_server/rbac/endpoint_utils.py +134 -46
  77. zenml/zen_server/rbac/models.py +65 -3
  78. zenml/zen_server/rbac/rbac_interface.py +9 -0
  79. zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
  80. zenml/zen_server/rbac/utils.py +156 -29
  81. zenml/zen_server/rbac/zenml_cloud_rbac.py +43 -11
  82. zenml/zen_server/routers/actions_endpoints.py +3 -5
  83. zenml/zen_server/routers/artifact_endpoint.py +0 -5
  84. zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
  85. zenml/zen_server/routers/auth_endpoints.py +22 -7
  86. zenml/zen_server/routers/code_repositories_endpoints.py +56 -3
  87. zenml/zen_server/routers/devices_endpoints.py +0 -4
  88. zenml/zen_server/routers/event_source_endpoints.py +0 -5
  89. zenml/zen_server/routers/flavors_endpoints.py +0 -5
  90. zenml/zen_server/routers/logs_endpoints.py +0 -1
  91. zenml/zen_server/routers/model_versions_endpoints.py +102 -23
  92. zenml/zen_server/routers/models_endpoints.py +51 -68
  93. zenml/zen_server/routers/pipeline_builds_endpoints.py +58 -4
  94. zenml/zen_server/routers/pipeline_deployments_endpoints.py +58 -4
  95. zenml/zen_server/routers/pipelines_endpoints.py +73 -4
  96. zenml/zen_server/routers/plugin_endpoints.py +0 -1
  97. zenml/zen_server/routers/run_metadata_endpoints.py +99 -0
  98. zenml/zen_server/routers/run_templates_endpoints.py +66 -3
  99. zenml/zen_server/routers/runs_endpoints.py +60 -8
  100. zenml/zen_server/routers/schedule_endpoints.py +69 -6
  101. zenml/zen_server/routers/secrets_endpoints.py +40 -4
  102. zenml/zen_server/routers/server_endpoints.py +53 -1
  103. zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
  104. zenml/zen_server/routers/service_connectors_endpoints.py +96 -14
  105. zenml/zen_server/routers/service_endpoints.py +20 -7
  106. zenml/zen_server/routers/stack_components_endpoints.py +68 -7
  107. zenml/zen_server/routers/stacks_endpoints.py +98 -7
  108. zenml/zen_server/routers/steps_endpoints.py +17 -11
  109. zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
  110. zenml/zen_server/routers/tags_endpoints.py +6 -17
  111. zenml/zen_server/routers/triggers_endpoints.py +5 -8
  112. zenml/zen_server/routers/users_endpoints.py +47 -12
  113. zenml/zen_server/routers/workspaces_endpoints.py +56 -1285
  114. zenml/zen_server/template_execution/utils.py +5 -4
  115. zenml/zen_server/utils.py +21 -0
  116. zenml/zen_server/zen_server_api.py +4 -0
  117. zenml/zen_stores/base_zen_store.py +29 -44
  118. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
  119. zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
  120. zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
  121. zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
  122. zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
  123. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
  124. zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
  125. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
  126. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
  127. zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
  128. zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
  129. zenml/zen_stores/rest_zen_store.py +172 -171
  130. zenml/zen_stores/schemas/action_schemas.py +8 -1
  131. zenml/zen_stores/schemas/api_key_schemas.py +8 -1
  132. zenml/zen_stores/schemas/artifact_schemas.py +28 -1
  133. zenml/zen_stores/schemas/code_repository_schemas.py +8 -1
  134. zenml/zen_stores/schemas/component_schemas.py +9 -14
  135. zenml/zen_stores/schemas/event_source_schemas.py +8 -1
  136. zenml/zen_stores/schemas/flavor_schemas.py +14 -20
  137. zenml/zen_stores/schemas/model_schemas.py +3 -0
  138. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -1
  139. zenml/zen_stores/schemas/pipeline_run_schemas.py +0 -3
  140. zenml/zen_stores/schemas/run_template_schemas.py +8 -4
  141. zenml/zen_stores/schemas/schedule_schema.py +9 -14
  142. zenml/zen_stores/schemas/secret_schemas.py +15 -25
  143. zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
  144. zenml/zen_stores/schemas/service_schemas.py +0 -1
  145. zenml/zen_stores/schemas/stack_schemas.py +12 -15
  146. zenml/zen_stores/schemas/step_run_schemas.py +7 -8
  147. zenml/zen_stores/schemas/tag_schemas.py +30 -2
  148. zenml/zen_stores/schemas/trigger_schemas.py +8 -1
  149. zenml/zen_stores/schemas/user_schemas.py +24 -2
  150. zenml/zen_stores/schemas/utils.py +16 -0
  151. zenml/zen_stores/schemas/workspace_schemas.py +7 -25
  152. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
  153. zenml/zen_stores/sql_zen_store.py +2905 -2280
  154. zenml/zen_stores/template_utils.py +1 -1
  155. zenml/zen_stores/zen_store_interface.py +82 -58
  156. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
  157. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +160 -147
  158. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
  159. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
  160. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
@@ -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(
@@ -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",
@@ -134,7 +134,7 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
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",
@@ -186,11 +186,14 @@ 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.
@@ -202,14 +205,13 @@ class StepRunSchema(NamedSchema, RunMetadataInterface, table=True):
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(
@@ -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
@@ -51,6 +51,13 @@ 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
+ "workspace_id",
58
+ name="unique_trigger_name_in_workspace",
59
+ ),
60
+ )
54
61
 
55
62
  workspace_id: UUID = build_foreign_key_field(
56
63
  source=__tablename__,
@@ -34,11 +34,14 @@ from zenml.models import (
34
34
  )
35
35
  from zenml.utils.time_utils import utc_now
36
36
  from zenml.zen_stores.schemas.base_schemas import NamedSchema
37
+ from zenml.zen_stores.schemas.schema_utils import build_foreign_key_field
38
+ from zenml.zen_stores.schemas.workspace_schemas import WorkspaceSchema
37
39
 
38
40
  if TYPE_CHECKING:
39
41
  from zenml.zen_stores.schemas import (
40
42
  ActionSchema,
41
43
  APIKeySchema,
44
+ ArtifactSchema,
42
45
  ArtifactVersionSchema,
43
46
  CodeRepositorySchema,
44
47
  EventSourceSchema,
@@ -51,6 +54,7 @@ if TYPE_CHECKING:
51
54
  PipelineRunSchema,
52
55
  PipelineSchema,
53
56
  RunMetadataSchema,
57
+ RunTemplateSchema,
54
58
  ScheduleSchema,
55
59
  SecretSchema,
56
60
  ServiceConnectorSchema,
@@ -58,6 +62,7 @@ if TYPE_CHECKING:
58
62
  StackComponentSchema,
59
63
  StackSchema,
60
64
  StepRunSchema,
65
+ TagSchema,
61
66
  TriggerSchema,
62
67
  )
63
68
 
@@ -79,6 +84,14 @@ class UserSchema(NamedSchema, table=True):
79
84
  external_user_id: Optional[UUID] = Field(nullable=True)
80
85
  is_admin: bool = Field(default=False)
81
86
  user_metadata: Optional[str] = Field(nullable=True)
87
+ default_workspace_id: Optional[UUID] = build_foreign_key_field(
88
+ source=__tablename__,
89
+ target=WorkspaceSchema.__tablename__,
90
+ source_column="default_workspace_id",
91
+ target_column="id",
92
+ ondelete="SET NULL",
93
+ nullable=True,
94
+ )
82
95
 
83
96
  stacks: List["StackSchema"] = Relationship(back_populates="user")
84
97
  components: List["StackComponentSchema"] = Relationship(
@@ -100,8 +113,12 @@ class UserSchema(NamedSchema, table=True):
100
113
  back_populates="user",
101
114
  )
102
115
  runs: List["PipelineRunSchema"] = Relationship(back_populates="user")
116
+ run_templates: List["RunTemplateSchema"] = Relationship(
117
+ back_populates="user",
118
+ )
103
119
  step_runs: List["StepRunSchema"] = Relationship(back_populates="user")
104
120
  builds: List["PipelineBuildSchema"] = Relationship(back_populates="user")
121
+ artifacts: List["ArtifactSchema"] = Relationship(back_populates="user")
105
122
  artifact_versions: List["ArtifactVersionSchema"] = Relationship(
106
123
  back_populates="user"
107
124
  )
@@ -150,6 +167,9 @@ class UserSchema(NamedSchema, table=True):
150
167
  back_populates="service_account",
151
168
  sa_relationship_kwargs={"cascade": "delete"},
152
169
  )
170
+ tags: List["TagSchema"] = Relationship(
171
+ back_populates="user",
172
+ )
153
173
 
154
174
  @classmethod
155
175
  def from_user_request(cls, model: UserRequest) -> "UserSchema":
@@ -175,6 +195,7 @@ class UserSchema(NamedSchema, table=True):
175
195
  user_metadata=json.dumps(model.user_metadata)
176
196
  if model.user_metadata
177
197
  else None,
198
+ default_workspace_id=model.default_workspace_id,
178
199
  )
179
200
 
180
201
  @classmethod
@@ -262,8 +283,8 @@ class UserSchema(NamedSchema, table=True):
262
283
  include_resources: Whether the resources will be filled.
263
284
  **kwargs: Keyword arguments to allow schema specific logic
264
285
  include_private: Whether to include the user private information
265
- this is to limit the amount of data one can get
266
- about other users
286
+ this is to limit the amount of data one can get about other
287
+ users.
267
288
 
268
289
  Returns:
269
290
  The converted `UserResponse`.
@@ -289,6 +310,7 @@ class UserSchema(NamedSchema, table=True):
289
310
  created=self.created,
290
311
  updated=self.updated,
291
312
  is_admin=self.is_admin,
313
+ default_workspace_id=self.default_workspace_id,
292
314
  ),
293
315
  metadata=metadata,
294
316
  )
@@ -110,3 +110,19 @@ class RunMetadataInterface:
110
110
  k: sorted(v, key=lambda x: x.created, reverse=True)[0].value
111
111
  for k, v in metadata_collection.items()
112
112
  }
113
+
114
+
115
+ def get_resource_type_name(schema_class: Type[BaseSchema]) -> str:
116
+ """Get the name of a resource from a schema class.
117
+
118
+ Args:
119
+ schema_class: The schema class to get the name of.
120
+
121
+ Returns:
122
+ The name of the resource.
123
+ """
124
+ entity_name = schema_class.__tablename__
125
+ assert isinstance(entity_name, str)
126
+ # Some entities are plural, some are singular, some have multiple words
127
+ # in their table name connected by underscores (e.g. pipeline_run)
128
+ return entity_name.replace("_", " ").rstrip("s")
@@ -15,6 +15,7 @@
15
15
 
16
16
  from typing import TYPE_CHECKING, Any, List
17
17
 
18
+ from sqlalchemy import UniqueConstraint
18
19
  from sqlmodel import Relationship
19
20
 
20
21
  from zenml.models import (
@@ -33,7 +34,6 @@ if TYPE_CHECKING:
33
34
  ArtifactVersionSchema,
34
35
  CodeRepositorySchema,
35
36
  EventSourceSchema,
36
- FlavorSchema,
37
37
  ModelSchema,
38
38
  ModelVersionSchema,
39
39
  PipelineBuildSchema,
@@ -42,11 +42,7 @@ if TYPE_CHECKING:
42
42
  PipelineSchema,
43
43
  RunMetadataSchema,
44
44
  ScheduleSchema,
45
- SecretSchema,
46
- ServiceConnectorSchema,
47
45
  ServiceSchema,
48
- StackComponentSchema,
49
- StackSchema,
50
46
  StepRunSchema,
51
47
  TriggerSchema,
52
48
  )
@@ -56,21 +52,15 @@ class WorkspaceSchema(NamedSchema, table=True):
56
52
  """SQL Model for workspaces."""
57
53
 
58
54
  __tablename__ = "workspace"
55
+ __table_args__ = (
56
+ UniqueConstraint(
57
+ "name",
58
+ name="unique_workspace_name",
59
+ ),
60
+ )
59
61
 
60
62
  description: str
61
63
 
62
- stacks: List["StackSchema"] = Relationship(
63
- back_populates="workspace",
64
- sa_relationship_kwargs={"cascade": "delete"},
65
- )
66
- components: List["StackComponentSchema"] = Relationship(
67
- back_populates="workspace",
68
- sa_relationship_kwargs={"cascade": "delete"},
69
- )
70
- flavors: List["FlavorSchema"] = Relationship(
71
- back_populates="workspace",
72
- sa_relationship_kwargs={"cascade": "delete"},
73
- )
74
64
  pipelines: List["PipelineSchema"] = Relationship(
75
65
  back_populates="workspace",
76
66
  sa_relationship_kwargs={"cascade": "delete"},
@@ -99,10 +89,6 @@ class WorkspaceSchema(NamedSchema, table=True):
99
89
  back_populates="workspace",
100
90
  sa_relationship_kwargs={"cascade": "delete"},
101
91
  )
102
- secrets: List["SecretSchema"] = Relationship(
103
- back_populates="workspace",
104
- sa_relationship_kwargs={"cascade": "delete"},
105
- )
106
92
  actions: List["ActionSchema"] = Relationship(
107
93
  back_populates="workspace",
108
94
  sa_relationship_kwargs={"cascade": "delete"},
@@ -128,10 +114,6 @@ class WorkspaceSchema(NamedSchema, table=True):
128
114
  back_populates="workspace",
129
115
  sa_relationship_kwargs={"cascade": "delete"},
130
116
  )
131
- service_connectors: List["ServiceConnectorSchema"] = Relationship(
132
- back_populates="workspace",
133
- sa_relationship_kwargs={"cascade": "delete"},
134
- )
135
117
  models: List["ModelSchema"] = Relationship(
136
118
  back_populates="workspace",
137
119
  sa_relationship_kwargs={"cascade": "delete"},
@@ -23,7 +23,6 @@ from typing import (
23
23
  Optional,
24
24
  Type,
25
25
  )
26
- from uuid import uuid4
27
26
 
28
27
  from pydantic import Field, model_validator
29
28
 
@@ -133,8 +132,6 @@ class ServiceConnectorSecretsStore(BaseSecretsStore):
133
132
  name="secrets-store",
134
133
  connector_type=self.SERVICE_CONNECTOR_TYPE,
135
134
  resource_types=[self.SERVICE_CONNECTOR_RESOURCE_TYPE],
136
- user=uuid4(), # Use a fake user ID
137
- workspace=uuid4(), # Use a fake workspace ID
138
135
  auth_method=self.config.auth_method,
139
136
  configuration=self.config.auth_config,
140
137
  )