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
@@ -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
+ )
@@ -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
 
@@ -81,6 +81,10 @@ class UserBase(BaseModel):
81
81
  default=None,
82
82
  title="The metadata associated with the user.",
83
83
  )
84
+ default_workspace_id: Optional[UUID] = Field(
85
+ default=None,
86
+ title="The default workspace ID for the user.",
87
+ )
84
88
 
85
89
  @classmethod
86
90
  def _get_crypt_context(cls) -> "CryptContext":
@@ -176,7 +180,7 @@ class UserRequest(UserBase, BaseRequest):
176
180
  # ------------------ Update Model ------------------
177
181
 
178
182
 
179
- class UserUpdate(UserBase, BaseZenModel):
183
+ class UserUpdate(UserBase, BaseUpdate):
180
184
  """Update model for users."""
181
185
 
182
186
  name: Optional[str] = Field(
@@ -279,6 +283,10 @@ class UserResponseBody(BaseDatedResponseBody):
279
283
  is_admin: bool = Field(
280
284
  title="Whether the account is an administrator.",
281
285
  )
286
+ default_workspace_id: Optional[UUID] = Field(
287
+ default=None,
288
+ title="The default workspace ID for the user.",
289
+ )
282
290
 
283
291
 
284
292
  class UserResponseMetadata(BaseResponseMetadata):
@@ -395,6 +403,15 @@ class UserResponse(
395
403
  """
396
404
  return self.get_body().is_admin
397
405
 
406
+ @property
407
+ def default_workspace_id(self) -> Optional[UUID]:
408
+ """The `default_workspace_id` property.
409
+
410
+ Returns:
411
+ the value of the property.
412
+ """
413
+ return self.get_body().default_workspace_id
414
+
398
415
  @property
399
416
  def email(self) -> Optional[str]:
400
417
  """The `email` property.
@@ -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 WorkspaceStatistics(BaseZenModel):
24
+ """Workspace 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
+ workspaces: int = Field(
44
+ title="The number of workspaces.",
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.")
@@ -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
+ workspace=client.active_workspace.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
+ workspace=pipeline_run.workspace.id,
58
59
  )
59
60
  }
60
61
 
@@ -319,7 +319,6 @@ 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
322
  workspace=client.active_workspace.id,
324
323
  deployment=self._deployment.id,
325
324
  pipeline=(
@@ -73,10 +73,8 @@ 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
78
  workspace=Client().active_workspace.id,
81
79
  )
82
80
 
@@ -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,
@@ -215,7 +215,6 @@ def reuse_or_create_pipeline_build(
215
215
  build_model = Client().zen_store.get_build(build_id=build)
216
216
  else:
217
217
  build_request = PipelineBuildRequest(
218
- user=Client().active_user.id,
219
218
  workspace=Client().active_workspace.id,
220
219
  stack=Client().active_stack_model.id,
221
220
  pipeline=pipeline_id,
@@ -419,7 +418,6 @@ def create_pipeline_build(
419
418
  )
420
419
  stack_checksum = compute_stack_checksum(stack=stack_model)
421
420
  build_request = PipelineBuildRequest(
422
- user=client.active_user.id,
423
421
  workspace=client.active_workspace.id,
424
422
  stack=stack_model.id,
425
423
  pipeline=pipeline_id,
@@ -32,6 +32,7 @@ if TYPE_CHECKING:
32
32
  from zenml.model.model import Model
33
33
  from zenml.pipelines.pipeline_definition import Pipeline
34
34
  from zenml.types import HookSpecification
35
+ from zenml.utils.tag_utils import Tag
35
36
 
36
37
  F = TypeVar("F", bound=Callable[..., None])
37
38
 
@@ -50,7 +51,7 @@ def pipeline(
50
51
  enable_artifact_metadata: Optional[bool] = None,
51
52
  enable_step_logs: Optional[bool] = None,
52
53
  settings: Optional[Dict[str, "SettingsOrDict"]] = None,
53
- tags: Optional[List[str]] = None,
54
+ tags: Optional[List[Union[str, "Tag"]]] = None,
54
55
  extra: Optional[Dict[str, Any]] = None,
55
56
  on_failure: Optional["HookSpecification"] = None,
56
57
  on_success: Optional["HookSpecification"] = None,
@@ -67,7 +68,7 @@ def pipeline(
67
68
  enable_artifact_metadata: Optional[bool] = None,
68
69
  enable_step_logs: Optional[bool] = None,
69
70
  settings: Optional[Dict[str, "SettingsOrDict"]] = None,
70
- tags: Optional[List[str]] = None,
71
+ tags: Optional[List[Union[str, "Tag"]]] = None,
71
72
  extra: Optional[Dict[str, Any]] = None,
72
73
  on_failure: Optional["HookSpecification"] = None,
73
74
  on_success: Optional["HookSpecification"] = None,
@@ -93,6 +93,7 @@ from zenml.utils import (
93
93
  yaml_utils,
94
94
  )
95
95
  from zenml.utils.string_utils import format_name_template
96
+ from zenml.utils.tag_utils import Tag
96
97
 
97
98
  if TYPE_CHECKING:
98
99
  from zenml.artifacts.external_artifact import ExternalArtifact
@@ -130,7 +131,7 @@ class Pipeline:
130
131
  enable_artifact_visualization: Optional[bool] = None,
131
132
  enable_step_logs: Optional[bool] = None,
132
133
  settings: Optional[Mapping[str, "SettingsOrDict"]] = None,
133
- tags: Optional[List[str]] = None,
134
+ tags: Optional[List[Union[str, "Tag"]]] = None,
134
135
  extra: Optional[Dict[str, Any]] = None,
135
136
  on_failure: Optional["HookSpecification"] = None,
136
137
  on_success: Optional["HookSpecification"] = None,
@@ -293,7 +294,7 @@ class Pipeline:
293
294
  enable_artifact_visualization: Optional[bool] = None,
294
295
  enable_step_logs: Optional[bool] = None,
295
296
  settings: Optional[Mapping[str, "SettingsOrDict"]] = None,
296
- tags: Optional[List[str]] = None,
297
+ tags: Optional[List[Union[str, "Tag"]]] = None,
297
298
  extra: Optional[Dict[str, Any]] = None,
298
299
  on_failure: Optional["HookSpecification"] = None,
299
300
  on_success: Optional["HookSpecification"] = None,
@@ -684,7 +685,6 @@ To avoid this consider setting pipeline parameters only in one place (config or
684
685
  orchestrator = components[StackComponentType.ORCHESTRATOR][0]
685
686
  schedule_model = ScheduleRequest(
686
687
  workspace=Client().active_workspace.id,
687
- user=Client().active_user.id,
688
688
  pipeline_id=pipeline_id,
689
689
  orchestrator_id=orchestrator.id,
690
690
  name=schedule_name,
@@ -770,7 +770,6 @@ To avoid this consider setting pipeline parameters only in one place (config or
770
770
  code_path = code_utils.upload_code_if_necessary(code_archive)
771
771
 
772
772
  request = PipelineDeploymentRequest(
773
- user=Client().active_user.id,
774
773
  workspace=Client().active_workspace.id,
775
774
  stack=stack.id,
776
775
  pipeline=pipeline_id,
@@ -1014,6 +1013,7 @@ To avoid this consider setting pipeline parameters only in one place (config or
1014
1013
  for component_type, component in stack.components.items()
1015
1014
  }
1016
1015
  return {
1016
+ "workspace_id": deployment.workspace.id,
1017
1017
  "store_type": Client().zen_store.type.value,
1018
1018
  **stack_metadata,
1019
1019
  "total_steps": len(self.invocations),
@@ -1095,7 +1095,6 @@ To avoid this consider setting pipeline parameters only in one place (config or
1095
1095
  except RuntimeError:
1096
1096
  request = PipelineRequest(
1097
1097
  workspace=client.active_workspace.id,
1098
- user=client.active_user.id,
1099
1098
  name=self.name,
1100
1099
  )
1101
1100
 
@@ -81,14 +81,14 @@ def create_placeholder_run(
81
81
  # running.
82
82
  start_time=start_time,
83
83
  orchestrator_run_id=None,
84
- user=deployment.user.id,
85
84
  workspace=deployment.workspace.id,
86
85
  deployment=deployment.id,
87
86
  pipeline=deployment.pipeline.id if deployment.pipeline else None,
88
87
  status=ExecutionStatus.INITIALIZING,
89
88
  tags=deployment.pipeline_configuration.tags,
90
89
  )
91
- return Client().zen_store.create_run(run_request)
90
+ run, _ = Client().zen_store.get_or_create_run(run_request)
91
+ return run
92
92
 
93
93
 
94
94
  def get_placeholder_run(
@@ -213,7 +213,7 @@ def validate_stack_is_runnable_from_server(
213
213
  assert len(flavors) == 1
214
214
  flavor_model = flavors[0]
215
215
 
216
- if flavor_model.workspace is not None:
216
+ if flavor_model.is_custom:
217
217
  raise ValueError("No custom stack component flavors allowed.")
218
218
 
219
219
  flavor = Flavor.from_model(flavor_model)
@@ -53,7 +53,6 @@ from zenml.models import (
53
53
  ServiceConnectorTypedResourcesModel,
54
54
  ServiceConnectorTypeModel,
55
55
  UserResponse,
56
- WorkspaceResponse,
57
56
  )
58
57
  from zenml.utils.time_utils import utc_now
59
58
 
@@ -706,7 +705,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
706
705
 
707
706
  def to_model(
708
707
  self,
709
- user: UUID,
710
708
  workspace: UUID,
711
709
  name: Optional[str] = None,
712
710
  description: str = "",
@@ -716,7 +714,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
716
714
 
717
715
  Args:
718
716
  name: The name of the connector.
719
- user: The ID of the user that created the connector.
720
717
  workspace: The ID of the workspace that the connector belongs to.
721
718
  description: The description of the connector.
722
719
  labels: The labels of the connector.
@@ -740,7 +737,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
740
737
  connector_type=spec.connector_type,
741
738
  name=name,
742
739
  description=description,
743
- user=user,
744
740
  workspace=workspace,
745
741
  auth_method=self.auth_method,
746
742
  expires_at=self.expires_at,
@@ -762,7 +758,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
762
758
 
763
759
  def to_response_model(
764
760
  self,
765
- workspace: WorkspaceResponse,
766
761
  user: Optional[UserResponse] = None,
767
762
  name: Optional[str] = None,
768
763
  id: Optional[UUID] = None,
@@ -772,7 +767,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
772
767
  """Convert the connector instance to a service connector response model.
773
768
 
774
769
  Args:
775
- workspace: The workspace that the connector belongs to.
776
770
  user: The user that created the connector.
777
771
  name: The name of the connector.
778
772
  id: The ID of the connector.
@@ -810,7 +804,6 @@ class ServiceConnector(BaseModel, metaclass=ServiceConnectorMeta):
810
804
  expires_skew_tolerance=self.expires_skew_tolerance,
811
805
  ),
812
806
  metadata=ServiceConnectorResponseMetadata(
813
- workspace=workspace,
814
807
  expiration_seconds=self.expiration_seconds,
815
808
  labels=labels or {},
816
809
  ),
@@ -184,7 +184,6 @@ def get_resources_options_from_resource_model_for_full_stack(
184
184
  else:
185
185
  resource_model = zen_store.verify_service_connector_config(
186
186
  service_connector=ServiceConnectorRequest(
187
- user=client.active_user.id,
188
187
  workspace=client.active_workspace.id,
189
188
  name="fake",
190
189
  connector_type=connector_details.type,
@@ -71,7 +71,7 @@ class AuthenticationMixin(StackComponent):
71
71
 
72
72
  # Try to resolve the secret using the secret store
73
73
  try:
74
- return Client().get_secret_by_name_and_scope(
74
+ return Client().get_secret_by_name_and_private_status(
75
75
  name=self.config.authentication_secret,
76
76
  )
77
77
  except (KeyError, NotImplementedError):
zenml/stack/flavor.py CHANGED
@@ -17,7 +17,6 @@ import os
17
17
  from abc import abstractmethod
18
18
  from typing import Any, Dict, Optional, Type, cast
19
19
 
20
- from zenml.client import Client
21
20
  from zenml.enums import StackComponentType
22
21
  from zenml.exceptions import CustomFlavorImportError
23
22
  from zenml.models import (
@@ -25,7 +24,6 @@ from zenml.models import (
25
24
  FlavorResponse,
26
25
  ServiceConnectorRequirements,
27
26
  )
28
- from zenml.models.v2.core.flavor import InternalFlavorRequest
29
27
  from zenml.stack.stack_component import StackComponent, StackComponentConfig
30
28
  from zenml.utils import source_utils
31
29
  from zenml.utils.package_utils import is_latest_zenml_version
@@ -167,8 +165,7 @@ class Flavor:
167
165
 
168
166
  Args:
169
167
  integration: The integration to use for the model.
170
- is_custom: Whether the flavor is a custom flavor. Custom flavors
171
- are then scoped by user and workspace
168
+ is_custom: Whether the flavor is a custom flavor.
172
169
 
173
170
  Returns:
174
171
  The model.
@@ -189,16 +186,8 @@ class Flavor:
189
186
  if connector_requirements
190
187
  else None
191
188
  )
192
- user = None
193
- workspace = None
194
- if is_custom:
195
- user = Client().active_user.id
196
- workspace = Client().active_workspace.id
197
-
198
- model_class = FlavorRequest if is_custom else InternalFlavorRequest
199
- model = model_class(
200
- user=user,
201
- workspace=workspace,
189
+
190
+ model = FlavorRequest(
202
191
  name=self.name,
203
192
  type=self.type,
204
193
  source=source_utils.resolve(self.__class__).import_path,
@@ -215,7 +215,7 @@ class StackComponentConfig(BaseModel, ABC):
215
215
 
216
216
  # Try to resolve the secret using the secret store
217
217
  try:
218
- secret = Client().get_secret_by_name_and_scope(
218
+ secret = Client().get_secret_by_name_and_private_status(
219
219
  name=secret_ref.name,
220
220
  )
221
221
  except (KeyError, NotImplementedError):
@@ -333,7 +333,6 @@ class StackComponent:
333
333
  flavor: str,
334
334
  type: StackComponentType,
335
335
  user: Optional[UUID],
336
- workspace: UUID,
337
336
  created: datetime,
338
337
  updated: datetime,
339
338
  labels: Optional[Dict[str, Any]] = None,
@@ -352,7 +351,6 @@ class StackComponent:
352
351
  flavor: The flavor of the component.
353
352
  type: The type of the component.
354
353
  user: The ID of the user who created the component.
355
- workspace: The ID of the workspace the component belongs to.
356
354
  created: The creation time of the component.
357
355
  updated: The last update time of the component.
358
356
  labels: The labels of the component.
@@ -378,7 +376,6 @@ class StackComponent:
378
376
  self.flavor = flavor
379
377
  self.type = type
380
378
  self.user = user
381
- self.workspace = workspace
382
379
  self.created = created
383
380
  self.updated = updated
384
381
  self.labels = labels
@@ -417,7 +414,6 @@ class StackComponent:
417
414
  try:
418
415
  return flavor.implementation_class(
419
416
  user=user_id,
420
- workspace=component_model.workspace.id,
421
417
  name=component_model.name,
422
418
  id=component_model.id,
423
419
  config=configuration,
@@ -384,6 +384,25 @@ class StepContext(metaclass=SingletonMetaClass):
384
384
  output.tags = []
385
385
  output.tags += tags
386
386
 
387
+ def remove_output_tags(
388
+ self,
389
+ tags: List[str],
390
+ output_name: Optional[str] = None,
391
+ ) -> None:
392
+ """Removes tags for a given step output.
393
+
394
+ Args:
395
+ tags: The tags to remove.
396
+ output_name: Optional name of the output for which to remove the
397
+ tags. If no name is given and the step only has a single
398
+ output, the tags of this output will be removed. If the
399
+ step has multiple outputs, an exception will be raised.
400
+ """
401
+ output = self._get_output(output_name)
402
+ if not output.tags:
403
+ return
404
+ output.tags = [tag for tag in output.tags if tag not in tags]
405
+
387
406
 
388
407
  class StepContextOutput:
389
408
  """Represents a step output in the step context."""
@@ -101,7 +101,7 @@ def b64_decode(input_: str) -> str:
101
101
 
102
102
 
103
103
  def random_str(length: int) -> str:
104
- """Generate a random human readable string of given length.
104
+ """Generate a random human-readable string of given length.
105
105
 
106
106
  Args:
107
107
  length: Length of string