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
@@ -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 BaseRequest, BaseUpdate
35
+ from zenml.models.v2.base.base import BaseUpdate
36
36
  from zenml.models.v2.base.scoped import (
37
- WorkspaceScopedFilter,
38
- WorkspaceScopedResponse,
39
- WorkspaceScopedResponseBody,
40
- WorkspaceScopedResponseMetadata,
41
- WorkspaceScopedResponseResources,
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(BaseRequest):
61
- """Request model for a stack."""
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(WorkspaceScopedResponseBody):
170
+ class StackResponseBody(UserScopedResponseBody):
169
171
  """Response body for stacks."""
170
172
 
171
173
 
172
- class StackResponseMetadata(WorkspaceScopedResponseMetadata):
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(WorkspaceScopedResponseResources):
195
- """Class for all resource models associated with the stack entity."""
196
+ class StackResponseResources(UserScopedResponseResources):
197
+ """Response resources for stacks."""
196
198
 
197
199
 
198
200
  class StackResponse(
199
- WorkspaceScopedResponse[
200
- StackResponseBody, StackResponseMetadata, StackResponseResources
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(WorkspaceScopedFilter):
328
- """Model to enable advanced filtering of all StackModels.
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
- *WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
335
+ *UserScopedFilter.FILTER_EXCLUDE_FIELDS,
338
336
  "component_id",
339
337
  "component",
340
338
  ]
@@ -27,19 +27,20 @@ from typing import (
27
27
  )
28
28
  from uuid import UUID
29
29
 
30
- from pydantic import BaseModel, ConfigDict, Field
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
- WorkspaceScopedFilter,
38
- WorkspaceScopedRequest,
39
- WorkspaceScopedResponse,
40
- WorkspaceScopedResponseBody,
41
- WorkspaceScopedResponseMetadata,
42
- WorkspaceScopedResponseResources,
38
+ ProjectScopedFilter,
39
+ ProjectScopedRequest,
40
+ ProjectScopedResponse,
41
+ ProjectScopedResponseBody,
42
+ ProjectScopedResponseMetadata,
43
+ ProjectScopedResponseResources,
43
44
  )
44
45
  from zenml.models.v2.core.artifact_version import ArtifactVersionResponse
45
46
  from zenml.models.v2.core.model_version import ModelVersionResponse
@@ -78,7 +79,7 @@ class StepRunInputResponse(ArtifactVersionResponse):
78
79
  # ------------------ Request Model ------------------
79
80
 
80
81
 
81
- class StepRunRequest(WorkspaceScopedRequest):
82
+ class StepRunRequest(ProjectScopedRequest):
82
83
  """Request model for step runs."""
83
84
 
84
85
  name: str = Field(
@@ -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(BaseModel):
148
+ class StepRunUpdate(BaseUpdate):
156
149
  """Update model for step runs."""
157
150
 
158
151
  outputs: Dict[str, List[UUID]] = Field(
@@ -171,16 +164,11 @@ 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
 
182
170
  # ------------------ Response Model ------------------
183
- class StepRunResponseBody(WorkspaceScopedResponseBody):
171
+ class StepRunResponseBody(ProjectScopedResponseBody):
184
172
  """Response body for step runs."""
185
173
 
186
174
  status: ExecutionStatus = Field(title="The status of the step.")
@@ -208,7 +196,7 @@ class StepRunResponseBody(WorkspaceScopedResponseBody):
208
196
  model_config = ConfigDict(protected_namespaces=())
209
197
 
210
198
 
211
- class StepRunResponseMetadata(WorkspaceScopedResponseMetadata):
199
+ class StepRunResponseMetadata(ProjectScopedResponseMetadata):
212
200
  """Response metadata for step runs."""
213
201
 
214
202
  # Configuration
@@ -262,7 +250,7 @@ class StepRunResponseMetadata(WorkspaceScopedResponseMetadata):
262
250
  )
263
251
 
264
252
 
265
- class StepRunResponseResources(WorkspaceScopedResponseResources):
253
+ class StepRunResponseResources(ProjectScopedResponseResources):
266
254
  """Class for all resource models associated with the step run entity."""
267
255
 
268
256
  model_version: Optional[ModelVersionResponse] = None
@@ -277,7 +265,7 @@ class StepRunResponseResources(WorkspaceScopedResponseResources):
277
265
 
278
266
 
279
267
  class StepRunResponse(
280
- WorkspaceScopedResponse[
268
+ ProjectScopedResponse[
281
269
  StepRunResponseBody, StepRunResponseMetadata, StepRunResponseResources
282
270
  ]
283
271
  ):
@@ -516,11 +504,11 @@ class StepRunResponse(
516
504
  # ------------------ Filter Model ------------------
517
505
 
518
506
 
519
- class StepRunFilter(WorkspaceScopedFilter):
507
+ class StepRunFilter(ProjectScopedFilter):
520
508
  """Model to enable advanced filtering of step runs."""
521
509
 
522
510
  FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
523
- *WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
511
+ *ProjectScopedFilter.FILTER_EXCLUDE_FIELDS,
524
512
  "model",
525
513
  "run_metadata",
526
514
  ]
@@ -16,29 +16,34 @@
16
16
  import random
17
17
  from typing import Optional
18
18
 
19
- from pydantic import BaseModel, Field
19
+ from pydantic import Field
20
20
 
21
21
  from zenml.constants import STR_FIELD_MAX_LENGTH
22
22
  from zenml.enums import ColorVariants
23
- from zenml.models.v2.base.base import (
24
- BaseDatedResponseBody,
25
- BaseIdentifiedResponse,
26
- BaseRequest,
27
- BaseResponseMetadata,
28
- BaseResponseResources,
23
+ from zenml.models.v2.base.base import BaseUpdate
24
+ from zenml.models.v2.base.scoped import (
25
+ UserScopedFilter,
26
+ UserScopedRequest,
27
+ UserScopedResponse,
28
+ UserScopedResponseBody,
29
+ UserScopedResponseMetadata,
30
+ UserScopedResponseResources,
29
31
  )
30
- from zenml.models.v2.base.filter import BaseFilter
31
32
 
32
33
  # ------------------ Request Model ------------------
33
34
 
34
35
 
35
- class TagRequest(BaseRequest):
36
+ class TagRequest(UserScopedRequest):
36
37
  """Request model for tags."""
37
38
 
38
39
  name: str = Field(
39
40
  description="The unique title of the tag.",
40
41
  max_length=STR_FIELD_MAX_LENGTH,
41
42
  )
43
+ exclusive: bool = Field(
44
+ description="The flag signifying whether the tag is an exclusive tag.",
45
+ default=False,
46
+ )
42
47
  color: ColorVariants = Field(
43
48
  description="The color variant assigned to the tag.",
44
49
  default_factory=lambda: random.choice(list(ColorVariants)),
@@ -48,35 +53,43 @@ class TagRequest(BaseRequest):
48
53
  # ------------------ Update Model ------------------
49
54
 
50
55
 
51
- class TagUpdate(BaseModel):
56
+ class TagUpdate(BaseUpdate):
52
57
  """Update model for tags."""
53
58
 
54
59
  name: Optional[str] = None
60
+ exclusive: Optional[bool] = None
55
61
  color: Optional[ColorVariants] = None
56
62
 
57
63
 
58
64
  # ------------------ Response Model ------------------
59
65
 
60
66
 
61
- class TagResponseBody(BaseDatedResponseBody):
67
+ class TagResponseBody(UserScopedResponseBody):
62
68
  """Response body for tags."""
63
69
 
64
70
  color: ColorVariants = Field(
65
71
  description="The color variant assigned to the tag.",
66
72
  default_factory=lambda: random.choice(list(ColorVariants)),
67
73
  )
74
+ exclusive: bool = Field(
75
+ description="The flag signifying whether the tag is an exclusive tag."
76
+ )
68
77
  tagged_count: int = Field(
69
78
  description="The count of resources tagged with this tag."
70
79
  )
71
80
 
72
81
 
73
- class TagResponseResources(BaseResponseResources):
82
+ class TagResponseMetadata(UserScopedResponseMetadata):
83
+ """Response metadata for tags."""
84
+
85
+
86
+ class TagResponseResources(UserScopedResponseResources):
74
87
  """Class for all resource models associated with the tag entity."""
75
88
 
76
89
 
77
90
  class TagResponse(
78
- BaseIdentifiedResponse[
79
- TagResponseBody, BaseResponseMetadata, TagResponseResources
91
+ UserScopedResponse[
92
+ TagResponseBody, TagResponseMetadata, TagResponseResources
80
93
  ]
81
94
  ):
82
95
  """Response model for tags."""
@@ -105,6 +118,15 @@ class TagResponse(
105
118
  """
106
119
  return self.get_body().color
107
120
 
121
+ @property
122
+ def exclusive(self) -> bool:
123
+ """The `exclusive` property.
124
+
125
+ Returns:
126
+ the value of the property.
127
+ """
128
+ return self.get_body().exclusive
129
+
108
130
  @property
109
131
  def tagged_count(self) -> int:
110
132
  """The `tagged_count` property.
@@ -118,7 +140,7 @@ class TagResponse(
118
140
  # ------------------ Filter Model ------------------
119
141
 
120
142
 
121
- class TagFilter(BaseFilter):
143
+ class TagFilter(UserScopedFilter):
122
144
  """Model to enable advanced filtering of all tags."""
123
145
 
124
146
  name: Optional[str] = Field(
@@ -127,3 +149,7 @@ class TagFilter(BaseFilter):
127
149
  color: Optional[ColorVariants] = Field(
128
150
  description="The color variant assigned to the tag.", default=None
129
151
  )
152
+ exclusive: Optional[bool] = Field(
153
+ description="The flag signifying whether the tag is an exclusive tag.",
154
+ default=None,
155
+ )
@@ -33,12 +33,12 @@ from zenml.constants import STR_FIELD_MAX_LENGTH
33
33
  from zenml.models.v2.base.base import BaseUpdate
34
34
  from zenml.models.v2.base.page import Page
35
35
  from zenml.models.v2.base.scoped import (
36
- WorkspaceScopedFilter,
37
- WorkspaceScopedRequest,
38
- WorkspaceScopedResponse,
39
- WorkspaceScopedResponseBody,
40
- WorkspaceScopedResponseMetadata,
41
- WorkspaceScopedResponseResources,
36
+ ProjectScopedFilter,
37
+ ProjectScopedRequest,
38
+ ProjectScopedResponse,
39
+ ProjectScopedResponseBody,
40
+ ProjectScopedResponseMetadata,
41
+ ProjectScopedResponseResources,
42
42
  )
43
43
  from zenml.models.v2.core.trigger_execution import TriggerExecutionResponse
44
44
 
@@ -57,7 +57,7 @@ if TYPE_CHECKING:
57
57
  # ------------------ Request Model ------------------
58
58
 
59
59
 
60
- class TriggerRequest(WorkspaceScopedRequest):
60
+ class TriggerRequest(ProjectScopedRequest):
61
61
  """Model for creating a new trigger."""
62
62
 
63
63
  name: str = Field(
@@ -145,7 +145,7 @@ class TriggerUpdate(BaseUpdate):
145
145
  # ------------------ Response Model ------------------
146
146
 
147
147
 
148
- class TriggerResponseBody(WorkspaceScopedResponseBody):
148
+ class TriggerResponseBody(ProjectScopedResponseBody):
149
149
  """Response body for triggers."""
150
150
 
151
151
  action_flavor: str = Field(
@@ -172,7 +172,7 @@ class TriggerResponseBody(WorkspaceScopedResponseBody):
172
172
  )
173
173
 
174
174
 
175
- class TriggerResponseMetadata(WorkspaceScopedResponseMetadata):
175
+ class TriggerResponseMetadata(ProjectScopedResponseMetadata):
176
176
  """Response metadata for triggers."""
177
177
 
178
178
  description: str = Field(
@@ -192,7 +192,7 @@ class TriggerResponseMetadata(WorkspaceScopedResponseMetadata):
192
192
  )
193
193
 
194
194
 
195
- class TriggerResponseResources(WorkspaceScopedResponseResources):
195
+ class TriggerResponseResources(ProjectScopedResponseResources):
196
196
  """Class for all resource models associated with the trigger entity."""
197
197
 
198
198
  action: "ActionResponse" = Field(
@@ -209,7 +209,7 @@ class TriggerResponseResources(WorkspaceScopedResponseResources):
209
209
 
210
210
 
211
211
  class TriggerResponse(
212
- WorkspaceScopedResponse[
212
+ ProjectScopedResponse[
213
213
  TriggerResponseBody, TriggerResponseMetadata, TriggerResponseResources
214
214
  ]
215
215
  ):
@@ -324,11 +324,11 @@ class TriggerResponse(
324
324
  # ------------------ Filter Model ------------------
325
325
 
326
326
 
327
- class TriggerFilter(WorkspaceScopedFilter):
327
+ class TriggerFilter(ProjectScopedFilter):
328
328
  """Model to enable advanced filtering of all triggers."""
329
329
 
330
330
  FILTER_EXCLUDE_FIELDS: ClassVar[List[str]] = [
331
- *WorkspaceScopedFilter.FILTER_EXCLUDE_FIELDS,
331
+ *ProjectScopedFilter.FILTER_EXCLUDE_FIELDS,
332
332
  "action_flavor",
333
333
  "action_subtype",
334
334
  "event_source_flavor",
@@ -27,7 +27,7 @@ from zenml.models.v2.base.base import (
27
27
  BaseDatedResponseBody,
28
28
  BaseResponseResources,
29
29
  )
30
- from zenml.models.v2.base.scoped import WorkspaceScopedFilter
30
+ from zenml.models.v2.base.scoped import ProjectScopedFilter
31
31
 
32
32
  if TYPE_CHECKING:
33
33
  from zenml.models.v2.core.trigger import TriggerResponse
@@ -109,7 +109,7 @@ class TriggerExecutionResponse(
109
109
  # ------------------ Filter Model ------------------
110
110
 
111
111
 
112
- class TriggerExecutionFilter(WorkspaceScopedFilter):
112
+ class TriggerExecutionFilter(ProjectScopedFilter):
113
113
  """Model to enable advanced filtering of all trigger executions."""
114
114
 
115
115
  trigger_id: Optional[Union[UUID, str]] = Field(
@@ -36,7 +36,7 @@ from zenml.models.v2.base.base import (
36
36
  BaseRequest,
37
37
  BaseResponseMetadata,
38
38
  BaseResponseResources,
39
- BaseZenModel,
39
+ BaseUpdate,
40
40
  )
41
41
  from zenml.models.v2.base.filter import AnyQuery, BaseFilter
42
42
 
@@ -176,7 +176,7 @@ class UserRequest(UserBase, BaseRequest):
176
176
  # ------------------ Update Model ------------------
177
177
 
178
178
 
179
- class UserUpdate(UserBase, BaseZenModel):
179
+ class UserUpdate(UserBase, BaseUpdate):
180
180
  """Update model for users."""
181
181
 
182
182
  name: Optional[str] = Field(
@@ -0,0 +1,45 @@
1
+ # Copyright (c) ZenML GmbH 2023. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Models representing statistics."""
15
+
16
+ from pydantic import Field
17
+
18
+ from zenml.models.v2.base.base import (
19
+ BaseZenModel,
20
+ )
21
+
22
+
23
+ class ProjectStatistics(BaseZenModel):
24
+ """Project statistics."""
25
+
26
+ pipelines: int = Field(
27
+ title="The number of pipelines.",
28
+ )
29
+ runs: int = Field(
30
+ title="The number of pipeline runs.",
31
+ )
32
+
33
+
34
+ class ServerStatistics(BaseZenModel):
35
+ """Server statistics."""
36
+
37
+ stacks: int = Field(
38
+ title="The number of stacks.",
39
+ )
40
+ components: int = Field(
41
+ title="The number of components.",
42
+ )
43
+ projects: int = Field(
44
+ title="The number of projects.",
45
+ )
@@ -0,0 +1,27 @@
1
+ # Copyright (c) ZenML GmbH 2025. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Utility models for tags."""
15
+
16
+ from uuid import UUID
17
+
18
+ from pydantic import BaseModel, Field
19
+
20
+ from zenml.enums import TaggableResourceTypes
21
+
22
+
23
+ class TagResource(BaseModel):
24
+ """Utility class to help identify resources to tag."""
25
+
26
+ id: UUID = Field(title="The ID of the resource.")
27
+ type: TaggableResourceTypes = Field(title="The type of the resource.")
@@ -34,7 +34,7 @@ def generate_cache_key(
34
34
  step: "Step",
35
35
  input_artifact_ids: Dict[str, "UUID"],
36
36
  artifact_store: "BaseArtifactStore",
37
- workspace_id: "UUID",
37
+ project_id: "UUID",
38
38
  ) -> str:
39
39
  """Generates a cache key for a step run.
40
40
 
@@ -42,7 +42,7 @@ def generate_cache_key(
42
42
  runs are identical and can be cached.
43
43
 
44
44
  The cache key is a MD5 hash of:
45
- - the workspace ID,
45
+ - the project ID,
46
46
  - the artifact store ID and path,
47
47
  - the source code that defines the step,
48
48
  - the parameters of the step,
@@ -55,15 +55,15 @@ def generate_cache_key(
55
55
  step: The step to generate the cache key for.
56
56
  input_artifact_ids: The input artifact IDs for the step.
57
57
  artifact_store: The artifact store of the active stack.
58
- workspace_id: The ID of the active workspace.
58
+ project_id: The ID of the active project.
59
59
 
60
60
  Returns:
61
61
  A cache key.
62
62
  """
63
63
  hash_ = hashlib.md5() # nosec
64
64
 
65
- # Workspace ID
66
- hash_.update(workspace_id.bytes)
65
+ # Project ID
66
+ hash_.update(project_id.bytes)
67
67
 
68
68
  # Artifact store ID and path
69
69
  hash_.update(artifact_store.id.bytes)
@@ -106,7 +106,7 @@ def get_cached_step_run(cache_key: str) -> Optional["StepRunResponse"]:
106
106
  """If a given step can be cached, get the corresponding existing step run.
107
107
 
108
108
  A step run can be cached if there is an existing step run in the same
109
- workspace which has the same cache key and was successfully executed.
109
+ project which has the same cache key and was successfully executed.
110
110
 
111
111
  Args:
112
112
  cache_key: The cache key of the step.
@@ -117,7 +117,7 @@ def get_cached_step_run(cache_key: str) -> Optional["StepRunResponse"]:
117
117
  client = Client()
118
118
 
119
119
  cache_candidates = client.list_run_steps(
120
- workspace_id=client.active_workspace.id,
120
+ project=client.active_project.id,
121
121
  cache_key=cache_key,
122
122
  status=ExecutionStatus.COMPLETED,
123
123
  sort_by=f"{SorterOps.DESCENDING}:created",
@@ -55,6 +55,7 @@ def resolve_step_inputs(
55
55
  for run_step in pagination_utils.depaginate(
56
56
  Client().list_run_steps,
57
57
  pipeline_run_id=pipeline_run.id,
58
+ project=pipeline_run.project.id,
58
59
  )
59
60
  }
60
61
 
@@ -319,8 +319,7 @@ class StepLauncher:
319
319
  pipeline_run = PipelineRunRequest(
320
320
  name=run_name,
321
321
  orchestrator_run_id=self._orchestrator_run_id,
322
- user=client.active_user.id,
323
- workspace=client.active_workspace.id,
322
+ project=client.active_project.id,
324
323
  deployment=self._deployment.id,
325
324
  pipeline=(
326
325
  self._deployment.pipeline.id
@@ -73,11 +73,9 @@ class StepRunRequestFactory:
73
73
  return StepRunRequest(
74
74
  name=invocation_id,
75
75
  pipeline_run_id=self.pipeline_run.id,
76
- deployment=self.deployment.id,
77
76
  status=ExecutionStatus.RUNNING,
78
77
  start_time=utc_now(),
79
- user=Client().active_user.id,
80
- workspace=Client().active_workspace.id,
78
+ project=Client().active_project.id,
81
79
  )
82
80
 
83
81
  def populate_request(self, request: StepRunRequest) -> None:
@@ -104,7 +102,7 @@ class StepRunRequestFactory:
104
102
  step=step,
105
103
  input_artifact_ids=input_artifact_ids,
106
104
  artifact_store=self.stack.artifact_store,
107
- workspace_id=Client().active_workspace.id,
105
+ project_id=Client().active_project.id,
108
106
  )
109
107
  request.cache_key = cache_key
110
108
 
@@ -56,7 +56,12 @@ from zenml.steps.utils import (
56
56
  parse_return_type_annotations,
57
57
  resolve_type_annotation,
58
58
  )
59
- from zenml.utils import materializer_utils, source_utils, string_utils
59
+ from zenml.utils import (
60
+ materializer_utils,
61
+ source_utils,
62
+ string_utils,
63
+ tag_utils,
64
+ )
60
65
  from zenml.utils.typing_utils import get_origin, is_union
61
66
 
62
67
  if TYPE_CHECKING:
@@ -637,6 +642,10 @@ class StepRunner:
637
642
 
638
643
  # Get full set of tags
639
644
  tags = step_context.get_output_tags(output_name)
645
+ if step_context.pipeline_run.config.tags is not None:
646
+ for tag in step_context.pipeline_run.config.tags:
647
+ if isinstance(tag, tag_utils.Tag) and tag.cascade is True:
648
+ tags.append(tag.name)
640
649
 
641
650
  artifact_request = _store_artifact_data_and_prepare_request(
642
651
  name=artifact_name,
@@ -23,8 +23,8 @@ from zenml.config.global_config import (
23
23
  GlobalConfiguration,
24
24
  )
25
25
  from zenml.constants import (
26
+ ENV_ZENML_ACTIVE_PROJECT_ID,
26
27
  ENV_ZENML_ACTIVE_STACK_ID,
27
- ENV_ZENML_ACTIVE_WORKSPACE_ID,
28
28
  ENV_ZENML_DISABLE_CREDENTIALS_DISK_CACHING,
29
29
  ENV_ZENML_PIPELINE_RUN_API_TOKEN_EXPIRATION,
30
30
  ENV_ZENML_SERVER,
@@ -211,13 +211,13 @@ def get_config_environment_vars(
211
211
  # in the pipeline run environment
212
212
  environment_vars[ENV_ZENML_DISABLE_CREDENTIALS_DISK_CACHING] = "true"
213
213
 
214
- # Make sure to use the correct active stack/workspace which might come
214
+ # Make sure to use the correct active stack/project which might come
215
215
  # from a .zen repository and not the global config
216
216
  environment_vars[ENV_ZENML_ACTIVE_STACK_ID] = str(
217
217
  Client().active_stack_model.id
218
218
  )
219
- environment_vars[ENV_ZENML_ACTIVE_WORKSPACE_ID] = str(
220
- Client().active_workspace.id
219
+ environment_vars[ENV_ZENML_ACTIVE_PROJECT_ID] = str(
220
+ Client().active_project.id
221
221
  )
222
222
 
223
223
  return environment_vars