zenml-nightly 0.75.0.dev20250311__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 (163) 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 +618 -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_build.py +18 -0
  45. zenml/models/v2/core/pipeline_run.py +5 -13
  46. zenml/models/v2/core/run_template.py +1 -2
  47. zenml/models/v2/core/schedule.py +0 -9
  48. zenml/models/v2/core/secret.py +93 -127
  49. zenml/models/v2/core/server_settings.py +2 -2
  50. zenml/models/v2/core/service.py +43 -12
  51. zenml/models/v2/core/service_connector.py +14 -16
  52. zenml/models/v2/core/stack.py +24 -26
  53. zenml/models/v2/core/step_run.py +3 -15
  54. zenml/models/v2/core/tag.py +41 -15
  55. zenml/models/v2/core/user.py +19 -2
  56. zenml/models/v2/misc/statistics.py +45 -0
  57. zenml/models/v2/misc/tag.py +27 -0
  58. zenml/orchestrators/cache_utils.py +1 -1
  59. zenml/orchestrators/input_utils.py +1 -0
  60. zenml/orchestrators/step_launcher.py +0 -1
  61. zenml/orchestrators/step_run_utils.py +0 -2
  62. zenml/orchestrators/step_runner.py +10 -1
  63. zenml/pipelines/build_utils.py +4 -2
  64. zenml/pipelines/pipeline_decorator.py +3 -2
  65. zenml/pipelines/pipeline_definition.py +4 -5
  66. zenml/pipelines/run_utils.py +3 -3
  67. zenml/service_connectors/service_connector.py +0 -7
  68. zenml/service_connectors/service_connector_utils.py +0 -1
  69. zenml/stack/authentication_mixin.py +1 -1
  70. zenml/stack/flavor.py +3 -14
  71. zenml/stack/stack_component.py +1 -5
  72. zenml/steps/step_context.py +19 -0
  73. zenml/utils/string_utils.py +1 -1
  74. zenml/utils/tag_utils.py +642 -0
  75. zenml/zen_server/cloud_utils.py +21 -0
  76. zenml/zen_server/exceptions.py +0 -6
  77. zenml/zen_server/rbac/endpoint_utils.py +134 -46
  78. zenml/zen_server/rbac/models.py +65 -3
  79. zenml/zen_server/rbac/rbac_interface.py +9 -0
  80. zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
  81. zenml/zen_server/rbac/utils.py +156 -29
  82. zenml/zen_server/rbac/zenml_cloud_rbac.py +43 -11
  83. zenml/zen_server/routers/actions_endpoints.py +3 -5
  84. zenml/zen_server/routers/artifact_endpoint.py +0 -5
  85. zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
  86. zenml/zen_server/routers/auth_endpoints.py +22 -7
  87. zenml/zen_server/routers/code_repositories_endpoints.py +56 -3
  88. zenml/zen_server/routers/devices_endpoints.py +0 -4
  89. zenml/zen_server/routers/event_source_endpoints.py +0 -5
  90. zenml/zen_server/routers/flavors_endpoints.py +0 -5
  91. zenml/zen_server/routers/logs_endpoints.py +0 -1
  92. zenml/zen_server/routers/model_versions_endpoints.py +102 -23
  93. zenml/zen_server/routers/models_endpoints.py +51 -68
  94. zenml/zen_server/routers/pipeline_builds_endpoints.py +58 -4
  95. zenml/zen_server/routers/pipeline_deployments_endpoints.py +58 -4
  96. zenml/zen_server/routers/pipelines_endpoints.py +73 -4
  97. zenml/zen_server/routers/plugin_endpoints.py +0 -1
  98. zenml/zen_server/routers/run_metadata_endpoints.py +99 -0
  99. zenml/zen_server/routers/run_templates_endpoints.py +66 -3
  100. zenml/zen_server/routers/runs_endpoints.py +60 -8
  101. zenml/zen_server/routers/schedule_endpoints.py +69 -6
  102. zenml/zen_server/routers/secrets_endpoints.py +40 -4
  103. zenml/zen_server/routers/server_endpoints.py +53 -1
  104. zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
  105. zenml/zen_server/routers/service_connectors_endpoints.py +96 -14
  106. zenml/zen_server/routers/service_endpoints.py +20 -7
  107. zenml/zen_server/routers/stack_components_endpoints.py +68 -7
  108. zenml/zen_server/routers/stacks_endpoints.py +98 -7
  109. zenml/zen_server/routers/steps_endpoints.py +17 -11
  110. zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
  111. zenml/zen_server/routers/tags_endpoints.py +6 -17
  112. zenml/zen_server/routers/triggers_endpoints.py +5 -8
  113. zenml/zen_server/routers/users_endpoints.py +47 -12
  114. zenml/zen_server/routers/workspaces_endpoints.py +56 -1285
  115. zenml/zen_server/template_execution/utils.py +5 -4
  116. zenml/zen_server/utils.py +21 -0
  117. zenml/zen_server/zen_server_api.py +4 -0
  118. zenml/zen_stores/base_zen_store.py +29 -44
  119. zenml/zen_stores/migrations/versions/0392807467dc_add_build_duration.py +34 -0
  120. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
  121. zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
  122. zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
  123. zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
  124. zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
  125. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
  126. zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
  127. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
  128. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
  129. zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
  130. zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
  131. zenml/zen_stores/rest_zen_store.py +172 -171
  132. zenml/zen_stores/schemas/action_schemas.py +8 -1
  133. zenml/zen_stores/schemas/api_key_schemas.py +8 -1
  134. zenml/zen_stores/schemas/artifact_schemas.py +28 -1
  135. zenml/zen_stores/schemas/code_repository_schemas.py +8 -1
  136. zenml/zen_stores/schemas/component_schemas.py +9 -14
  137. zenml/zen_stores/schemas/event_source_schemas.py +8 -1
  138. zenml/zen_stores/schemas/flavor_schemas.py +14 -20
  139. zenml/zen_stores/schemas/model_schemas.py +3 -0
  140. zenml/zen_stores/schemas/pipeline_build_schemas.py +4 -0
  141. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -1
  142. zenml/zen_stores/schemas/pipeline_run_schemas.py +0 -3
  143. zenml/zen_stores/schemas/run_template_schemas.py +8 -4
  144. zenml/zen_stores/schemas/schedule_schema.py +9 -14
  145. zenml/zen_stores/schemas/secret_schemas.py +15 -25
  146. zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
  147. zenml/zen_stores/schemas/service_schemas.py +0 -1
  148. zenml/zen_stores/schemas/stack_schemas.py +12 -15
  149. zenml/zen_stores/schemas/step_run_schemas.py +7 -8
  150. zenml/zen_stores/schemas/tag_schemas.py +30 -2
  151. zenml/zen_stores/schemas/trigger_schemas.py +8 -1
  152. zenml/zen_stores/schemas/user_schemas.py +24 -2
  153. zenml/zen_stores/schemas/utils.py +16 -0
  154. zenml/zen_stores/schemas/workspace_schemas.py +7 -25
  155. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
  156. zenml/zen_stores/sql_zen_store.py +2905 -2280
  157. zenml/zen_stores/template_utils.py +1 -1
  158. zenml/zen_stores/zen_store_interface.py +82 -58
  159. {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
  160. {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +163 -149
  161. {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
  162. {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
  163. {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
zenml/client.py CHANGED
@@ -59,12 +59,12 @@ from zenml.constants import (
59
59
  )
60
60
  from zenml.enums import (
61
61
  ArtifactType,
62
+ ColorVariants,
62
63
  LogicalOperators,
63
64
  ModelStages,
64
65
  OAuthDeviceStatus,
65
66
  PluginSubType,
66
67
  PluginType,
67
- SecretScope,
68
68
  SorterOps,
69
69
  StackComponentType,
70
70
  StoreType,
@@ -170,6 +170,8 @@ from zenml.models import (
170
170
  StepRunResponse,
171
171
  TagFilter,
172
172
  TagRequest,
173
+ TagResource,
174
+ TagResourceRequest,
173
175
  TagResponse,
174
176
  TagUpdate,
175
177
  TriggerExecutionFilter,
@@ -465,7 +467,8 @@ class Client(metaclass=ClientMetaClass):
465
467
  config_name="repo",
466
468
  )
467
469
  self._config.set_active_stack(active_stack)
468
- self._config.set_active_workspace(active_workspace)
470
+ if active_workspace:
471
+ self._config.set_active_workspace(active_workspace)
469
472
 
470
473
  def _load_config(self) -> Optional[ClientConfiguration]:
471
474
  """Loads the client configuration from disk.
@@ -1139,14 +1142,15 @@ class Client(metaclass=ClientMetaClass):
1139
1142
  )
1140
1143
 
1141
1144
  if workspace.name != DEFAULT_WORKSPACE_NAME:
1142
- logger.warning(
1143
- f"You are running with a non-default workspace "
1144
- f"'{workspace.name}'. Any stacks, components, "
1145
- f"pipelines and pipeline runs produced in this "
1146
- f"workspace will currently not be accessible through "
1147
- f"the dashboard. However, this will be possible "
1148
- f"in the near future."
1149
- )
1145
+ if not self.zen_store.get_store_info().is_pro_server():
1146
+ logger.warning(
1147
+ f"You are running with a non-default workspace "
1148
+ f"'{workspace.name}'. The ZenML workspace feature is "
1149
+ "available only in ZenML Pro. Pipelines, pipeline runs and "
1150
+ "artifacts produced in this workspace will not be "
1151
+ "accessible through the dashboard. Please visit "
1152
+ "https://zenml.io/pro to learn more."
1153
+ )
1150
1154
  return workspace
1151
1155
 
1152
1156
  # --------------------------------- Stacks ---------------------------------
@@ -1188,7 +1192,6 @@ class Client(metaclass=ClientMetaClass):
1188
1192
  components=stack_components,
1189
1193
  stack_spec_path=stack_spec_file,
1190
1194
  workspace=self.active_workspace.id,
1191
- user=self.active_user.id,
1192
1195
  labels=labels,
1193
1196
  )
1194
1197
 
@@ -1237,8 +1240,6 @@ class Client(metaclass=ClientMetaClass):
1237
1240
  updated: Optional[Union[datetime, str]] = None,
1238
1241
  name: Optional[str] = None,
1239
1242
  description: Optional[str] = None,
1240
- workspace_id: Optional[Union[str, UUID]] = None,
1241
- user_id: Optional[Union[str, UUID]] = None,
1242
1243
  component_id: Optional[Union[str, UUID]] = None,
1243
1244
  user: Optional[Union[UUID, str]] = None,
1244
1245
  component: Optional[Union[UUID, str]] = None,
@@ -1255,8 +1256,6 @@ class Client(metaclass=ClientMetaClass):
1255
1256
  created: Use to filter by time of creation
1256
1257
  updated: Use the last updated date for filtering
1257
1258
  description: Use the stack description for filtering
1258
- workspace_id: The id of the workspace to filter by.
1259
- user_id: The id of the user to filter by.
1260
1259
  component_id: The id of the component to filter by.
1261
1260
  user: The name/ID of the user to filter by.
1262
1261
  component: The name/ID of the component to filter by.
@@ -1272,8 +1271,6 @@ class Client(metaclass=ClientMetaClass):
1272
1271
  size=size,
1273
1272
  sort_by=sort_by,
1274
1273
  logical_operator=logical_operator,
1275
- workspace_id=workspace_id,
1276
- user_id=user_id,
1277
1274
  component_id=component_id,
1278
1275
  user=user,
1279
1276
  component=component,
@@ -1283,7 +1280,6 @@ class Client(metaclass=ClientMetaClass):
1283
1280
  created=created,
1284
1281
  updated=updated,
1285
1282
  )
1286
- stack_filter_model.set_scope_workspace(self.active_workspace.id)
1287
1283
  return self.zen_store.list_stacks(stack_filter_model, hydrate=hydrate)
1288
1284
 
1289
1285
  def update_stack(
@@ -1322,7 +1318,6 @@ class Client(metaclass=ClientMetaClass):
1322
1318
  # Create the update model
1323
1319
  update_model = StackUpdate(
1324
1320
  workspace=self.active_workspace.id,
1325
- user=self.active_user.id,
1326
1321
  stack_spec_path=stack_spec_file,
1327
1322
  )
1328
1323
 
@@ -1633,7 +1628,6 @@ class Client(metaclass=ClientMetaClass):
1633
1628
  service_type=service_type,
1634
1629
  config=config.model_dump(),
1635
1630
  workspace=self.active_workspace.id,
1636
- user=self.active_user.id,
1637
1631
  model_version_id=model_version_id,
1638
1632
  )
1639
1633
  # Register the service
@@ -1645,6 +1639,7 @@ class Client(metaclass=ClientMetaClass):
1645
1639
  allow_name_prefix_match: bool = True,
1646
1640
  hydrate: bool = True,
1647
1641
  type: Optional[str] = None,
1642
+ workspace: Optional[Union[str, UUID]] = None,
1648
1643
  ) -> ServiceResponse:
1649
1644
  """Gets a service.
1650
1645
 
@@ -1654,6 +1649,7 @@ class Client(metaclass=ClientMetaClass):
1654
1649
  hydrate: Flag deciding whether to hydrate the output model(s)
1655
1650
  by including metadata fields in the response.
1656
1651
  type: The type of the service.
1652
+ workspace: The workspace name/ID to filter by.
1657
1653
 
1658
1654
  Returns:
1659
1655
  The Service
@@ -1676,7 +1672,6 @@ class Client(metaclass=ClientMetaClass):
1676
1672
  service_filter_model = ServiceFilter(**kwargs)
1677
1673
  if type:
1678
1674
  service_filter_model.set_type(type=type)
1679
- service_filter_model.set_scope_workspace(self.active_workspace.id)
1680
1675
  return self.zen_store.list_services(
1681
1676
  filter_model=service_filter_model,
1682
1677
  hydrate=hydrate,
@@ -1687,6 +1682,7 @@ class Client(metaclass=ClientMetaClass):
1687
1682
  list_method=type_scoped_list_method,
1688
1683
  name_id_or_prefix=name_id_or_prefix,
1689
1684
  allow_name_prefix_match=allow_name_prefix_match,
1685
+ workspace=workspace,
1690
1686
  hydrate=hydrate,
1691
1687
  )
1692
1688
 
@@ -1702,8 +1698,7 @@ class Client(metaclass=ClientMetaClass):
1702
1698
  type: Optional[str] = None,
1703
1699
  flavor: Optional[str] = None,
1704
1700
  user: Optional[Union[UUID, str]] = None,
1705
- workspace_id: Optional[Union[str, UUID]] = None,
1706
- user_id: Optional[Union[str, UUID]] = None,
1701
+ workspace: Optional[Union[str, UUID]] = None,
1707
1702
  hydrate: bool = False,
1708
1703
  running: Optional[bool] = None,
1709
1704
  service_name: Optional[str] = None,
@@ -1725,8 +1720,7 @@ class Client(metaclass=ClientMetaClass):
1725
1720
  updated: Use the last updated date for filtering
1726
1721
  type: Use the service type for filtering
1727
1722
  flavor: Use the service flavor for filtering
1728
- workspace_id: The id of the workspace to filter by.
1729
- user_id: The id of the user to filter by.
1723
+ workspace: The workspace name/ID to filter by.
1730
1724
  user: Filter by user name/ID.
1731
1725
  hydrate: Flag deciding whether to hydrate the output model(s)
1732
1726
  by including metadata fields in the response.
@@ -1752,8 +1746,7 @@ class Client(metaclass=ClientMetaClass):
1752
1746
  updated=updated,
1753
1747
  type=type,
1754
1748
  flavor=flavor,
1755
- workspace_id=workspace_id,
1756
- user_id=user_id,
1749
+ workspace=workspace or self.active_workspace.id,
1757
1750
  user=user,
1758
1751
  running=running,
1759
1752
  name=service_name,
@@ -1763,7 +1756,6 @@ class Client(metaclass=ClientMetaClass):
1763
1756
  pipeline_run_id=pipeline_run_id,
1764
1757
  config=dict_to_bytes(config) if config else None,
1765
1758
  )
1766
- service_filter_model.set_scope_workspace(self.active_workspace.id)
1767
1759
  return self.zen_store.list_services(
1768
1760
  filter_model=service_filter_model, hydrate=hydrate
1769
1761
  )
@@ -1821,15 +1813,21 @@ class Client(metaclass=ClientMetaClass):
1821
1813
  service_id=id, update=service_update
1822
1814
  )
1823
1815
 
1824
- def delete_service(self, name_id_or_prefix: UUID) -> None:
1816
+ def delete_service(
1817
+ self,
1818
+ name_id_or_prefix: UUID,
1819
+ workspace: Optional[Union[str, UUID]] = None,
1820
+ ) -> None:
1825
1821
  """Delete a service.
1826
1822
 
1827
1823
  Args:
1828
1824
  name_id_or_prefix: The name or ID of the service to delete.
1825
+ workspace: The workspace name/ID to filter by.
1829
1826
  """
1830
1827
  service = self.get_service(
1831
1828
  name_id_or_prefix,
1832
1829
  allow_name_prefix_match=False,
1830
+ workspace=workspace,
1833
1831
  )
1834
1832
  self.zen_store.delete_service(service_id=service.id)
1835
1833
 
@@ -1893,9 +1891,6 @@ class Client(metaclass=ClientMetaClass):
1893
1891
  component_filter_model.set_scope_type(
1894
1892
  component_type=component_type
1895
1893
  )
1896
- component_filter_model.set_scope_workspace(
1897
- self.active_workspace.id
1898
- )
1899
1894
  return self.zen_store.list_stack_components(
1900
1895
  component_filter_model=component_filter_model,
1901
1896
  hydrate=hydrate,
@@ -1921,8 +1916,6 @@ class Client(metaclass=ClientMetaClass):
1921
1916
  name: Optional[str] = None,
1922
1917
  flavor: Optional[str] = None,
1923
1918
  type: Optional[str] = None,
1924
- workspace_id: Optional[Union[str, UUID]] = None,
1925
- user_id: Optional[Union[str, UUID]] = None,
1926
1919
  connector_id: Optional[Union[str, UUID]] = None,
1927
1920
  stack_id: Optional[Union[str, UUID]] = None,
1928
1921
  user: Optional[Union[UUID, str]] = None,
@@ -1940,8 +1933,6 @@ class Client(metaclass=ClientMetaClass):
1940
1933
  updated: Use the last updated date for filtering
1941
1934
  flavor: Use the component flavor for filtering
1942
1935
  type: Use the component type for filtering
1943
- workspace_id: The id of the workspace to filter by.
1944
- user_id: The id of the user to filter by.
1945
1936
  connector_id: The id of the connector to filter by.
1946
1937
  stack_id: The id of the stack to filter by.
1947
1938
  name: The name of the component to filter by.
@@ -1957,8 +1948,6 @@ class Client(metaclass=ClientMetaClass):
1957
1948
  size=size,
1958
1949
  sort_by=sort_by,
1959
1950
  logical_operator=logical_operator,
1960
- workspace_id=workspace_id or self.active_workspace.id,
1961
- user_id=user_id,
1962
1951
  connector_id=connector_id,
1963
1952
  stack_id=stack_id,
1964
1953
  name=name,
@@ -1969,7 +1958,6 @@ class Client(metaclass=ClientMetaClass):
1969
1958
  updated=updated,
1970
1959
  user=user,
1971
1960
  )
1972
- component_filter_model.set_scope_workspace(self.active_workspace.id)
1973
1961
 
1974
1962
  return self.zen_store.list_stack_components(
1975
1963
  component_filter_model=component_filter_model, hydrate=hydrate
@@ -2017,7 +2005,6 @@ class Client(metaclass=ClientMetaClass):
2017
2005
  type=component_type,
2018
2006
  flavor=flavor,
2019
2007
  configuration=configuration,
2020
- user=self.active_user.id,
2021
2008
  workspace=self.active_workspace.id,
2022
2009
  labels=labels,
2023
2010
  )
@@ -2068,7 +2055,6 @@ class Client(metaclass=ClientMetaClass):
2068
2055
 
2069
2056
  update_model = ComponentUpdate(
2070
2057
  workspace=self.active_workspace.id,
2071
- user=self.active_user.id,
2072
2058
  )
2073
2059
 
2074
2060
  if name is not None:
@@ -2241,7 +2227,6 @@ class Client(metaclass=ClientMetaClass):
2241
2227
  name: Optional[str] = None,
2242
2228
  type: Optional[str] = None,
2243
2229
  integration: Optional[str] = None,
2244
- user_id: Optional[Union[str, UUID]] = None,
2245
2230
  user: Optional[Union[UUID, str]] = None,
2246
2231
  hydrate: bool = False,
2247
2232
  ) -> Page[FlavorResponse]:
@@ -2255,7 +2240,6 @@ class Client(metaclass=ClientMetaClass):
2255
2240
  id: Use the id of flavors to filter by.
2256
2241
  created: Use to flavors by time of creation
2257
2242
  updated: Use the last updated date for filtering
2258
- user_id: The id of the user to filter by.
2259
2243
  user: Filter by user name/ID.
2260
2244
  name: The name of the flavor to filter by.
2261
2245
  type: The type of the flavor to filter by.
@@ -2271,7 +2255,6 @@ class Client(metaclass=ClientMetaClass):
2271
2255
  size=size,
2272
2256
  sort_by=sort_by,
2273
2257
  logical_operator=logical_operator,
2274
- user_id=user_id,
2275
2258
  user=user,
2276
2259
  name=name,
2277
2260
  type=type,
@@ -2280,7 +2263,6 @@ class Client(metaclass=ClientMetaClass):
2280
2263
  created=created,
2281
2264
  updated=updated,
2282
2265
  )
2283
- flavor_filter_model.set_scope_workspace(self.active_workspace.id)
2284
2266
  return self.zen_store.list_flavors(
2285
2267
  flavor_filter_model=flavor_filter_model, hydrate=hydrate
2286
2268
  )
@@ -2365,10 +2347,10 @@ class Client(metaclass=ClientMetaClass):
2365
2347
  updated: Optional[Union[datetime, str]] = None,
2366
2348
  name: Optional[str] = None,
2367
2349
  latest_run_status: Optional[str] = None,
2368
- workspace_id: Optional[Union[str, UUID]] = None,
2369
- user_id: Optional[Union[str, UUID]] = None,
2350
+ workspace: Optional[Union[str, UUID]] = None,
2370
2351
  user: Optional[Union[UUID, str]] = None,
2371
2352
  tag: Optional[str] = None,
2353
+ tags: Optional[List[str]] = None,
2372
2354
  hydrate: bool = False,
2373
2355
  ) -> Page[PipelineResponse]:
2374
2356
  """List all pipelines.
@@ -2384,10 +2366,10 @@ class Client(metaclass=ClientMetaClass):
2384
2366
  name: The name of the pipeline to filter by.
2385
2367
  latest_run_status: Filter by the status of the latest run of a
2386
2368
  pipeline.
2387
- workspace_id: The id of the workspace to filter by.
2388
- user_id: The id of the user to filter by.
2369
+ workspace: The workspace name/ID to filter by.
2389
2370
  user: The name/ID of the user to filter by.
2390
2371
  tag: Tag to filter by.
2372
+ tags: Tags to filter by.
2391
2373
  hydrate: Flag deciding whether to hydrate the output model(s)
2392
2374
  by including metadata fields in the response.
2393
2375
 
@@ -2404,12 +2386,11 @@ class Client(metaclass=ClientMetaClass):
2404
2386
  updated=updated,
2405
2387
  name=name,
2406
2388
  latest_run_status=latest_run_status,
2407
- workspace_id=workspace_id,
2408
- user_id=user_id,
2389
+ workspace=workspace or self.active_workspace.id,
2409
2390
  user=user,
2410
2391
  tag=tag,
2392
+ tags=tags,
2411
2393
  )
2412
- pipeline_filter_model.set_scope_workspace(self.active_workspace.id)
2413
2394
  return self.zen_store.list_pipelines(
2414
2395
  pipeline_filter_model=pipeline_filter_model,
2415
2396
  hydrate=hydrate,
@@ -2418,12 +2399,14 @@ class Client(metaclass=ClientMetaClass):
2418
2399
  def get_pipeline(
2419
2400
  self,
2420
2401
  name_id_or_prefix: Union[str, UUID],
2402
+ workspace: Optional[Union[str, UUID]] = None,
2421
2403
  hydrate: bool = True,
2422
2404
  ) -> PipelineResponse:
2423
2405
  """Get a pipeline by name, id or prefix.
2424
2406
 
2425
2407
  Args:
2426
2408
  name_id_or_prefix: The name, ID or ID prefix of the pipeline.
2409
+ workspace: The workspace name/ID to filter by.
2427
2410
  hydrate: Flag deciding whether to hydrate the output model(s)
2428
2411
  by including metadata fields in the response.
2429
2412
 
@@ -2434,19 +2417,24 @@ class Client(metaclass=ClientMetaClass):
2434
2417
  get_method=self.zen_store.get_pipeline,
2435
2418
  list_method=self.list_pipelines,
2436
2419
  name_id_or_prefix=name_id_or_prefix,
2420
+ workspace=workspace,
2437
2421
  hydrate=hydrate,
2438
2422
  )
2439
2423
 
2440
2424
  def delete_pipeline(
2441
2425
  self,
2442
2426
  name_id_or_prefix: Union[str, UUID],
2427
+ workspace: Optional[Union[str, UUID]] = None,
2443
2428
  ) -> None:
2444
2429
  """Delete a pipeline.
2445
2430
 
2446
2431
  Args:
2447
2432
  name_id_or_prefix: The name, ID or ID prefix of the pipeline.
2433
+ workspace: The workspace name/ID to filter by.
2448
2434
  """
2449
- pipeline = self.get_pipeline(name_id_or_prefix=name_id_or_prefix)
2435
+ pipeline = self.get_pipeline(
2436
+ name_id_or_prefix=name_id_or_prefix, workspace=workspace
2437
+ )
2450
2438
  self.zen_store.delete_pipeline(pipeline_id=pipeline.id)
2451
2439
 
2452
2440
  @_fail_for_sql_zen_store
@@ -2460,6 +2448,7 @@ class Client(metaclass=ClientMetaClass):
2460
2448
  template_id: Optional[UUID] = None,
2461
2449
  stack_name_or_id: Union[str, UUID, None] = None,
2462
2450
  synchronous: bool = False,
2451
+ workspace: Optional[Union[str, UUID]] = None,
2463
2452
  ) -> PipelineRunResponse:
2464
2453
  """Trigger a pipeline from the server.
2465
2454
 
@@ -2499,6 +2488,7 @@ class Client(metaclass=ClientMetaClass):
2499
2488
  runnable template on any stack.
2500
2489
  synchronous: If `True`, this method will wait until the triggered
2501
2490
  run is finished.
2491
+ workspace: The workspace name/ID to filter by.
2502
2492
 
2503
2493
  Raises:
2504
2494
  RuntimeError: If triggering the pipeline failed.
@@ -2562,6 +2552,7 @@ class Client(metaclass=ClientMetaClass):
2562
2552
  self.list_run_templates,
2563
2553
  pipeline_id=pipeline.id,
2564
2554
  stack_id=stack.id if stack else None,
2555
+ workspace=workspace or pipeline.workspace.id,
2565
2556
  )
2566
2557
 
2567
2558
  for template in templates:
@@ -2600,12 +2591,14 @@ class Client(metaclass=ClientMetaClass):
2600
2591
  def get_build(
2601
2592
  self,
2602
2593
  id_or_prefix: Union[str, UUID],
2594
+ workspace: Optional[Union[str, UUID]] = None,
2603
2595
  hydrate: bool = True,
2604
2596
  ) -> PipelineBuildResponse:
2605
2597
  """Get a build by id or prefix.
2606
2598
 
2607
2599
  Args:
2608
2600
  id_or_prefix: The id or id prefix of the build.
2601
+ workspace: The workspace name/ID to filter by.
2609
2602
  hydrate: Flag deciding whether to hydrate the output model(s)
2610
2603
  by including metadata fields in the response.
2611
2604
 
@@ -2629,9 +2622,16 @@ class Client(metaclass=ClientMetaClass):
2629
2622
  hydrate=hydrate,
2630
2623
  )
2631
2624
 
2632
- entity = self.list_builds(
2633
- id=f"startswith:{id_or_prefix}", hydrate=hydrate
2625
+ list_kwargs: Dict[str, Any] = dict(
2626
+ id=f"startswith:{id_or_prefix}",
2627
+ hydrate=hydrate,
2634
2628
  )
2629
+ scope = ""
2630
+ if workspace:
2631
+ list_kwargs["workspace"] = workspace
2632
+ scope = f" in workspace {workspace}"
2633
+
2634
+ entity = self.list_builds(**list_kwargs)
2635
2635
 
2636
2636
  # If only a single entity is found, return it.
2637
2637
  if entity.total == 1:
@@ -2641,11 +2641,11 @@ class Client(metaclass=ClientMetaClass):
2641
2641
  if entity.total == 0:
2642
2642
  raise KeyError(
2643
2643
  f"No builds have been found that have either an id or prefix "
2644
- f"that matches the provided string '{id_or_prefix}'."
2644
+ f"that matches the provided string '{id_or_prefix}'{scope}."
2645
2645
  )
2646
2646
 
2647
2647
  raise ZenKeyError(
2648
- f"{entity.total} builds have been found that have "
2648
+ f"{entity.total} builds have been found{scope} that have "
2649
2649
  f"an ID that matches the provided "
2650
2650
  f"string '{id_or_prefix}':\n"
2651
2651
  f"{[entity.items]}.\n"
@@ -2662,8 +2662,7 @@ class Client(metaclass=ClientMetaClass):
2662
2662
  id: Optional[Union[UUID, str]] = None,
2663
2663
  created: Optional[Union[datetime, str]] = None,
2664
2664
  updated: Optional[Union[datetime, str]] = None,
2665
- workspace_id: Optional[Union[str, UUID]] = None,
2666
- user_id: Optional[Union[str, UUID]] = None,
2665
+ workspace: Optional[Union[str, UUID]] = None,
2667
2666
  user: Optional[Union[UUID, str]] = None,
2668
2667
  pipeline_id: Optional[Union[str, UUID]] = None,
2669
2668
  stack_id: Optional[Union[str, UUID]] = None,
@@ -2674,6 +2673,7 @@ class Client(metaclass=ClientMetaClass):
2674
2673
  python_version: Optional[str] = None,
2675
2674
  checksum: Optional[str] = None,
2676
2675
  stack_checksum: Optional[str] = None,
2676
+ duration: Optional[Union[int, str]] = None,
2677
2677
  hydrate: bool = False,
2678
2678
  ) -> Page[PipelineBuildResponse]:
2679
2679
  """List all builds.
@@ -2686,8 +2686,7 @@ class Client(metaclass=ClientMetaClass):
2686
2686
  id: Use the id of build to filter by.
2687
2687
  created: Use to filter by time of creation
2688
2688
  updated: Use the last updated date for filtering
2689
- workspace_id: The id of the workspace to filter by.
2690
- user_id: The id of the user to filter by.
2689
+ workspace: The workspace name/ID to filter by.
2691
2690
  user: Filter by user name/ID.
2692
2691
  pipeline_id: The id of the pipeline to filter by.
2693
2692
  stack_id: The id of the stack to filter by.
@@ -2699,6 +2698,7 @@ class Client(metaclass=ClientMetaClass):
2699
2698
  python_version: The Python version to filter by.
2700
2699
  checksum: The build checksum to filter by.
2701
2700
  stack_checksum: The stack checksum to filter by.
2701
+ duration: The duration of the build in seconds to filter by.
2702
2702
  hydrate: Flag deciding whether to hydrate the output model(s)
2703
2703
  by including metadata fields in the response.
2704
2704
 
@@ -2713,8 +2713,7 @@ class Client(metaclass=ClientMetaClass):
2713
2713
  id=id,
2714
2714
  created=created,
2715
2715
  updated=updated,
2716
- workspace_id=workspace_id,
2717
- user_id=user_id,
2716
+ workspace=workspace or self.active_workspace.id,
2718
2717
  user=user,
2719
2718
  pipeline_id=pipeline_id,
2720
2719
  stack_id=stack_id,
@@ -2725,20 +2724,23 @@ class Client(metaclass=ClientMetaClass):
2725
2724
  python_version=python_version,
2726
2725
  checksum=checksum,
2727
2726
  stack_checksum=stack_checksum,
2727
+ duration=duration,
2728
2728
  )
2729
- build_filter_model.set_scope_workspace(self.active_workspace.id)
2730
2729
  return self.zen_store.list_builds(
2731
2730
  build_filter_model=build_filter_model,
2732
2731
  hydrate=hydrate,
2733
2732
  )
2734
2733
 
2735
- def delete_build(self, id_or_prefix: str) -> None:
2734
+ def delete_build(
2735
+ self, id_or_prefix: str, workspace: Optional[Union[str, UUID]] = None
2736
+ ) -> None:
2736
2737
  """Delete a build.
2737
2738
 
2738
2739
  Args:
2739
2740
  id_or_prefix: The id or id prefix of the build.
2741
+ workspace: The workspace name/ID to filter by.
2740
2742
  """
2741
- build = self.get_build(id_or_prefix=id_or_prefix)
2743
+ build = self.get_build(id_or_prefix=id_or_prefix, workspace=workspace)
2742
2744
  self.zen_store.delete_build(build_id=build.id)
2743
2745
 
2744
2746
  # --------------------------------- Event Sources -------------------------
@@ -2771,7 +2773,6 @@ class Client(metaclass=ClientMetaClass):
2771
2773
  flavor=flavor,
2772
2774
  plugin_type=PluginType.EVENT_SOURCE,
2773
2775
  plugin_subtype=event_source_subtype,
2774
- user=self.active_user.id,
2775
2776
  workspace=self.active_workspace.id,
2776
2777
  )
2777
2778
 
@@ -2782,6 +2783,7 @@ class Client(metaclass=ClientMetaClass):
2782
2783
  self,
2783
2784
  name_id_or_prefix: Union[UUID, str],
2784
2785
  allow_name_prefix_match: bool = True,
2786
+ workspace: Optional[Union[str, UUID]] = None,
2785
2787
  hydrate: bool = True,
2786
2788
  ) -> EventSourceResponse:
2787
2789
  """Get an event source by name, ID or prefix.
@@ -2789,6 +2791,7 @@ class Client(metaclass=ClientMetaClass):
2789
2791
  Args:
2790
2792
  name_id_or_prefix: The name, ID or prefix of the stack.
2791
2793
  allow_name_prefix_match: If True, allow matching by name prefix.
2794
+ workspace: The workspace name/ID to filter by.
2792
2795
  hydrate: Flag deciding whether to hydrate the output model(s)
2793
2796
  by including metadata fields in the response.
2794
2797
 
@@ -2800,6 +2803,7 @@ class Client(metaclass=ClientMetaClass):
2800
2803
  list_method=self.list_event_sources,
2801
2804
  name_id_or_prefix=name_id_or_prefix,
2802
2805
  allow_name_prefix_match=allow_name_prefix_match,
2806
+ workspace=workspace,
2803
2807
  hydrate=hydrate,
2804
2808
  )
2805
2809
 
@@ -2815,8 +2819,7 @@ class Client(metaclass=ClientMetaClass):
2815
2819
  name: Optional[str] = None,
2816
2820
  flavor: Optional[str] = None,
2817
2821
  event_source_type: Optional[str] = None,
2818
- workspace_id: Optional[Union[str, UUID]] = None,
2819
- user_id: Optional[Union[str, UUID]] = None,
2822
+ workspace: Optional[Union[str, UUID]] = None,
2820
2823
  user: Optional[Union[UUID, str]] = None,
2821
2824
  hydrate: bool = False,
2822
2825
  ) -> Page[EventSourceResponse]:
@@ -2830,8 +2833,7 @@ class Client(metaclass=ClientMetaClass):
2830
2833
  id: Use the id of event_sources to filter by.
2831
2834
  created: Use to filter by time of creation
2832
2835
  updated: Use the last updated date for filtering
2833
- workspace_id: The id of the workspace to filter by.
2834
- user_id: The id of the user to filter by.
2836
+ workspace: The workspace name/ID to filter by.
2835
2837
  user: Filter by user name/ID.
2836
2838
  name: The name of the event_source to filter by.
2837
2839
  flavor: The flavor of the event_source to filter by.
@@ -2847,8 +2849,7 @@ class Client(metaclass=ClientMetaClass):
2847
2849
  size=size,
2848
2850
  sort_by=sort_by,
2849
2851
  logical_operator=logical_operator,
2850
- workspace_id=workspace_id,
2851
- user_id=user_id,
2852
+ workspace=workspace or self.active_workspace.id,
2852
2853
  user=user,
2853
2854
  name=name,
2854
2855
  flavor=flavor,
@@ -2857,7 +2858,6 @@ class Client(metaclass=ClientMetaClass):
2857
2858
  created=created,
2858
2859
  updated=updated,
2859
2860
  )
2860
- event_source_filter_model.set_scope_workspace(self.active_workspace.id)
2861
2861
  return self.zen_store.list_event_sources(
2862
2862
  event_source_filter_model, hydrate=hydrate
2863
2863
  )
@@ -2871,8 +2871,9 @@ class Client(metaclass=ClientMetaClass):
2871
2871
  configuration: Optional[Dict[str, Any]] = None,
2872
2872
  rotate_secret: Optional[bool] = None,
2873
2873
  is_active: Optional[bool] = None,
2874
+ workspace: Optional[Union[str, UUID]] = None,
2874
2875
  ) -> EventSourceResponse:
2875
- """Updates a event_source.
2876
+ """Updates an event_source.
2876
2877
 
2877
2878
  Args:
2878
2879
  name_id_or_prefix: The name, id or prefix of the event_source to update.
@@ -2883,6 +2884,7 @@ class Client(metaclass=ClientMetaClass):
2883
2884
  contain the new secret value
2884
2885
  is_active: Optional[bool] = Allows for activation/deactivating the
2885
2886
  event source
2887
+ workspace: The workspace name/ID to filter by.
2886
2888
 
2887
2889
  Returns:
2888
2890
  The model of the updated event_source.
@@ -2892,7 +2894,9 @@ class Client(metaclass=ClientMetaClass):
2892
2894
  """
2893
2895
  # First, get the eve
2894
2896
  event_source = self.get_event_source(
2895
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
2897
+ name_id_or_prefix=name_id_or_prefix,
2898
+ allow_name_prefix_match=False,
2899
+ workspace=workspace,
2896
2900
  )
2897
2901
 
2898
2902
  # Create the update model
@@ -2918,15 +2922,22 @@ class Client(metaclass=ClientMetaClass):
2918
2922
  return updated_event_source
2919
2923
 
2920
2924
  @_fail_for_sql_zen_store
2921
- def delete_event_source(self, name_id_or_prefix: Union[str, UUID]) -> None:
2925
+ def delete_event_source(
2926
+ self,
2927
+ name_id_or_prefix: Union[str, UUID],
2928
+ workspace: Optional[Union[str, UUID]] = None,
2929
+ ) -> None:
2922
2930
  """Deletes an event_source.
2923
2931
 
2924
2932
  Args:
2925
2933
  name_id_or_prefix: The name, id or prefix id of the event_source
2926
2934
  to deregister.
2935
+ workspace: The workspace name/ID to filter by.
2927
2936
  """
2928
2937
  event_source = self.get_event_source(
2929
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
2938
+ name_id_or_prefix=name_id_or_prefix,
2939
+ allow_name_prefix_match=False,
2940
+ workspace=workspace,
2930
2941
  )
2931
2942
 
2932
2943
  self.zen_store.delete_event_source(event_source_id=event_source.id)
@@ -2970,7 +2981,6 @@ class Client(metaclass=ClientMetaClass):
2970
2981
  configuration=configuration,
2971
2982
  service_account_id=service_account_id,
2972
2983
  auth_window=auth_window,
2973
- user=self.active_user.id,
2974
2984
  workspace=self.active_workspace.id,
2975
2985
  )
2976
2986
 
@@ -2981,6 +2991,7 @@ class Client(metaclass=ClientMetaClass):
2981
2991
  self,
2982
2992
  name_id_or_prefix: Union[UUID, str],
2983
2993
  allow_name_prefix_match: bool = True,
2994
+ workspace: Optional[Union[str, UUID]] = None,
2984
2995
  hydrate: bool = True,
2985
2996
  ) -> ActionResponse:
2986
2997
  """Get an action by name, ID or prefix.
@@ -2988,6 +2999,7 @@ class Client(metaclass=ClientMetaClass):
2988
2999
  Args:
2989
3000
  name_id_or_prefix: The name, ID or prefix of the action.
2990
3001
  allow_name_prefix_match: If True, allow matching by name prefix.
3002
+ workspace: The workspace name/ID to filter by.
2991
3003
  hydrate: Flag deciding whether to hydrate the output model(s)
2992
3004
  by including metadata fields in the response.
2993
3005
 
@@ -2999,6 +3011,7 @@ class Client(metaclass=ClientMetaClass):
2999
3011
  list_method=self.list_actions,
3000
3012
  name_id_or_prefix=name_id_or_prefix,
3001
3013
  allow_name_prefix_match=allow_name_prefix_match,
3014
+ workspace=workspace,
3002
3015
  hydrate=hydrate,
3003
3016
  )
3004
3017
 
@@ -3015,8 +3028,7 @@ class Client(metaclass=ClientMetaClass):
3015
3028
  name: Optional[str] = None,
3016
3029
  flavor: Optional[str] = None,
3017
3030
  action_type: Optional[str] = None,
3018
- workspace_id: Optional[Union[str, UUID]] = None,
3019
- user_id: Optional[Union[str, UUID]] = None,
3031
+ workspace: Optional[Union[str, UUID]] = None,
3020
3032
  user: Optional[Union[UUID, str]] = None,
3021
3033
  hydrate: bool = False,
3022
3034
  ) -> Page[ActionResponse]:
@@ -3030,8 +3042,7 @@ class Client(metaclass=ClientMetaClass):
3030
3042
  id: Use the id of the action to filter by.
3031
3043
  created: Use to filter by time of creation
3032
3044
  updated: Use the last updated date for filtering
3033
- workspace_id: The id of the workspace to filter by.
3034
- user_id: The id of the user to filter by.
3045
+ workspace: The workspace name/ID to filter by.
3035
3046
  user: Filter by user name/ID.
3036
3047
  name: The name of the action to filter by.
3037
3048
  flavor: The flavor of the action to filter by.
@@ -3047,8 +3058,7 @@ class Client(metaclass=ClientMetaClass):
3047
3058
  size=size,
3048
3059
  sort_by=sort_by,
3049
3060
  logical_operator=logical_operator,
3050
- workspace_id=workspace_id,
3051
- user_id=user_id,
3061
+ workspace=workspace or self.active_workspace.id,
3052
3062
  user=user,
3053
3063
  name=name,
3054
3064
  id=id,
@@ -3057,7 +3067,6 @@ class Client(metaclass=ClientMetaClass):
3057
3067
  created=created,
3058
3068
  updated=updated,
3059
3069
  )
3060
- filter_model.set_scope_workspace(self.active_workspace.id)
3061
3070
  return self.zen_store.list_actions(filter_model, hydrate=hydrate)
3062
3071
 
3063
3072
  @_fail_for_sql_zen_store
@@ -3069,6 +3078,7 @@ class Client(metaclass=ClientMetaClass):
3069
3078
  configuration: Optional[Dict[str, Any]] = None,
3070
3079
  service_account_id: Optional[UUID] = None,
3071
3080
  auth_window: Optional[int] = None,
3081
+ workspace: Optional[Union[str, UUID]] = None,
3072
3082
  ) -> ActionResponse:
3073
3083
  """Update an action.
3074
3084
 
@@ -3082,12 +3092,15 @@ class Client(metaclass=ClientMetaClass):
3082
3092
  auth_window: The new time window in minutes for which the service
3083
3093
  account is authorized to execute the action. Set this to 0 to
3084
3094
  authorize the service account indefinitely (not recommended).
3095
+ workspace: The workspace name/ID to filter by.
3085
3096
 
3086
3097
  Returns:
3087
3098
  The updated action.
3088
3099
  """
3089
3100
  action = self.get_action(
3090
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3101
+ name_id_or_prefix=name_id_or_prefix,
3102
+ allow_name_prefix_match=False,
3103
+ workspace=workspace,
3091
3104
  )
3092
3105
 
3093
3106
  update_model = ActionUpdate(
@@ -3104,15 +3117,22 @@ class Client(metaclass=ClientMetaClass):
3104
3117
  )
3105
3118
 
3106
3119
  @_fail_for_sql_zen_store
3107
- def delete_action(self, name_id_or_prefix: Union[str, UUID]) -> None:
3120
+ def delete_action(
3121
+ self,
3122
+ name_id_or_prefix: Union[str, UUID],
3123
+ workspace: Optional[Union[str, UUID]] = None,
3124
+ ) -> None:
3108
3125
  """Delete an action.
3109
3126
 
3110
3127
  Args:
3111
3128
  name_id_or_prefix: The name, id or prefix id of the action
3112
3129
  to delete.
3130
+ workspace: The workspace name/ID to filter by.
3113
3131
  """
3114
3132
  action = self.get_action(
3115
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3133
+ name_id_or_prefix=name_id_or_prefix,
3134
+ allow_name_prefix_match=False,
3135
+ workspace=workspace,
3116
3136
  )
3117
3137
 
3118
3138
  self.zen_store.delete_action(action_id=action.id)
@@ -3147,7 +3167,6 @@ class Client(metaclass=ClientMetaClass):
3147
3167
  event_source_id=event_source_id,
3148
3168
  event_filter=event_filter,
3149
3169
  action_id=action_id,
3150
- user=self.active_user.id,
3151
3170
  workspace=self.active_workspace.id,
3152
3171
  )
3153
3172
 
@@ -3158,6 +3177,7 @@ class Client(metaclass=ClientMetaClass):
3158
3177
  self,
3159
3178
  name_id_or_prefix: Union[UUID, str],
3160
3179
  allow_name_prefix_match: bool = True,
3180
+ workspace: Optional[Union[str, UUID]] = None,
3161
3181
  hydrate: bool = True,
3162
3182
  ) -> TriggerResponse:
3163
3183
  """Get a trigger by name, ID or prefix.
@@ -3165,6 +3185,7 @@ class Client(metaclass=ClientMetaClass):
3165
3185
  Args:
3166
3186
  name_id_or_prefix: The name, ID or prefix of the trigger.
3167
3187
  allow_name_prefix_match: If True, allow matching by name prefix.
3188
+ workspace: The workspace name/ID to filter by.
3168
3189
  hydrate: Flag deciding whether to hydrate the output model(s)
3169
3190
  by including metadata fields in the response.
3170
3191
 
@@ -3176,6 +3197,7 @@ class Client(metaclass=ClientMetaClass):
3176
3197
  list_method=self.list_triggers,
3177
3198
  name_id_or_prefix=name_id_or_prefix,
3178
3199
  allow_name_prefix_match=allow_name_prefix_match,
3200
+ workspace=workspace,
3179
3201
  hydrate=hydrate,
3180
3202
  )
3181
3203
 
@@ -3196,8 +3218,7 @@ class Client(metaclass=ClientMetaClass):
3196
3218
  event_source_subtype: Optional[str] = None,
3197
3219
  action_flavor: Optional[str] = None,
3198
3220
  action_subtype: Optional[str] = None,
3199
- workspace_id: Optional[Union[str, UUID]] = None,
3200
- user_id: Optional[Union[str, UUID]] = None,
3221
+ workspace: Optional[Union[str, UUID]] = None,
3201
3222
  user: Optional[Union[UUID, str]] = None,
3202
3223
  hydrate: bool = False,
3203
3224
  ) -> Page[TriggerResponse]:
@@ -3211,8 +3232,7 @@ class Client(metaclass=ClientMetaClass):
3211
3232
  id: Use the id of triggers to filter by.
3212
3233
  created: Use to filter by time of creation
3213
3234
  updated: Use the last updated date for filtering
3214
- workspace_id: The id of the workspace to filter by.
3215
- user_id: The id of the user to filter by.
3235
+ workspace: The workspace name/ID to filter by.
3216
3236
  user: Filter by user name/ID.
3217
3237
  name: The name of the trigger to filter by.
3218
3238
  event_source_id: The event source associated with the trigger.
@@ -3234,8 +3254,7 @@ class Client(metaclass=ClientMetaClass):
3234
3254
  size=size,
3235
3255
  sort_by=sort_by,
3236
3256
  logical_operator=logical_operator,
3237
- workspace_id=workspace_id,
3238
- user_id=user_id,
3257
+ workspace=workspace or self.active_workspace.id,
3239
3258
  user=user,
3240
3259
  name=name,
3241
3260
  event_source_id=event_source_id,
@@ -3248,7 +3267,6 @@ class Client(metaclass=ClientMetaClass):
3248
3267
  created=created,
3249
3268
  updated=updated,
3250
3269
  )
3251
- trigger_filter_model.set_scope_workspace(self.active_workspace.id)
3252
3270
  return self.zen_store.list_triggers(
3253
3271
  trigger_filter_model, hydrate=hydrate
3254
3272
  )
@@ -3261,6 +3279,7 @@ class Client(metaclass=ClientMetaClass):
3261
3279
  description: Optional[str] = None,
3262
3280
  event_filter: Optional[Dict[str, Any]] = None,
3263
3281
  is_active: Optional[bool] = None,
3282
+ workspace: Optional[Union[str, UUID]] = None,
3264
3283
  ) -> TriggerResponse:
3265
3284
  """Updates a trigger.
3266
3285
 
@@ -3270,6 +3289,7 @@ class Client(metaclass=ClientMetaClass):
3270
3289
  description: the new description of the trigger.
3271
3290
  event_filter: The event filter configuration.
3272
3291
  is_active: Whether the trigger is active or not.
3292
+ workspace: The workspace name/ID to filter by.
3273
3293
 
3274
3294
  Returns:
3275
3295
  The model of the updated trigger.
@@ -3279,7 +3299,9 @@ class Client(metaclass=ClientMetaClass):
3279
3299
  """
3280
3300
  # First, get the eve
3281
3301
  trigger = self.get_trigger(
3282
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3302
+ name_id_or_prefix=name_id_or_prefix,
3303
+ allow_name_prefix_match=False,
3304
+ workspace=workspace,
3283
3305
  )
3284
3306
 
3285
3307
  # Create the update model
@@ -3304,15 +3326,22 @@ class Client(metaclass=ClientMetaClass):
3304
3326
  return updated_trigger
3305
3327
 
3306
3328
  @_fail_for_sql_zen_store
3307
- def delete_trigger(self, name_id_or_prefix: Union[str, UUID]) -> None:
3329
+ def delete_trigger(
3330
+ self,
3331
+ name_id_or_prefix: Union[str, UUID],
3332
+ workspace: Optional[Union[str, UUID]] = None,
3333
+ ) -> None:
3308
3334
  """Deletes an trigger.
3309
3335
 
3310
3336
  Args:
3311
3337
  name_id_or_prefix: The name, id or prefix id of the trigger
3312
3338
  to deregister.
3339
+ workspace: The workspace name/ID to filter by.
3313
3340
  """
3314
3341
  trigger = self.get_trigger(
3315
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3342
+ name_id_or_prefix=name_id_or_prefix,
3343
+ allow_name_prefix_match=False,
3344
+ workspace=workspace,
3316
3345
  )
3317
3346
 
3318
3347
  self.zen_store.delete_trigger(trigger_id=trigger.id)
@@ -3323,12 +3352,14 @@ class Client(metaclass=ClientMetaClass):
3323
3352
  def get_deployment(
3324
3353
  self,
3325
3354
  id_or_prefix: Union[str, UUID],
3355
+ workspace: Optional[Union[str, UUID]] = None,
3326
3356
  hydrate: bool = True,
3327
3357
  ) -> PipelineDeploymentResponse:
3328
3358
  """Get a deployment by id or prefix.
3329
3359
 
3330
3360
  Args:
3331
3361
  id_or_prefix: The id or id prefix of the deployment.
3362
+ workspace: The workspace name/ID to filter by.
3332
3363
  hydrate: Flag deciding whether to hydrate the output model(s)
3333
3364
  by including metadata fields in the response.
3334
3365
 
@@ -3351,10 +3382,16 @@ class Client(metaclass=ClientMetaClass):
3351
3382
  )
3352
3383
  return self.zen_store.get_deployment(id_, hydrate=hydrate)
3353
3384
 
3354
- entity = self.list_deployments(
3385
+ list_kwargs: Dict[str, Any] = dict(
3355
3386
  id=f"startswith:{id_or_prefix}",
3356
3387
  hydrate=hydrate,
3357
3388
  )
3389
+ scope = ""
3390
+ if workspace:
3391
+ list_kwargs["workspace"] = workspace
3392
+ scope = f" in workspace {workspace}"
3393
+
3394
+ entity = self.list_deployments(**list_kwargs)
3358
3395
 
3359
3396
  # If only a single entity is found, return it.
3360
3397
  if entity.total == 1:
@@ -3364,11 +3401,11 @@ class Client(metaclass=ClientMetaClass):
3364
3401
  if entity.total == 0:
3365
3402
  raise KeyError(
3366
3403
  f"No deployment have been found that have either an id or "
3367
- f"prefix that matches the provided string '{id_or_prefix}'."
3404
+ f"prefix that matches the provided string '{id_or_prefix}'{scope}."
3368
3405
  )
3369
3406
 
3370
3407
  raise ZenKeyError(
3371
- f"{entity.total} deployments have been found that have "
3408
+ f"{entity.total} deployments have been found{scope} that have "
3372
3409
  f"an ID that matches the provided "
3373
3410
  f"string '{id_or_prefix}':\n"
3374
3411
  f"{[entity.items]}.\n"
@@ -3385,8 +3422,7 @@ class Client(metaclass=ClientMetaClass):
3385
3422
  id: Optional[Union[UUID, str]] = None,
3386
3423
  created: Optional[Union[datetime, str]] = None,
3387
3424
  updated: Optional[Union[datetime, str]] = None,
3388
- workspace_id: Optional[Union[str, UUID]] = None,
3389
- user_id: Optional[Union[str, UUID]] = None,
3425
+ workspace: Optional[Union[str, UUID]] = None,
3390
3426
  user: Optional[Union[UUID, str]] = None,
3391
3427
  pipeline_id: Optional[Union[str, UUID]] = None,
3392
3428
  stack_id: Optional[Union[str, UUID]] = None,
@@ -3404,8 +3440,7 @@ class Client(metaclass=ClientMetaClass):
3404
3440
  id: Use the id of build to filter by.
3405
3441
  created: Use to filter by time of creation
3406
3442
  updated: Use the last updated date for filtering
3407
- workspace_id: The id of the workspace to filter by.
3408
- user_id: The id of the user to filter by.
3443
+ workspace: The workspace name/ID to filter by.
3409
3444
  user: Filter by user name/ID.
3410
3445
  pipeline_id: The id of the pipeline to filter by.
3411
3446
  stack_id: The id of the stack to filter by.
@@ -3425,28 +3460,33 @@ class Client(metaclass=ClientMetaClass):
3425
3460
  id=id,
3426
3461
  created=created,
3427
3462
  updated=updated,
3428
- workspace_id=workspace_id,
3429
- user_id=user_id,
3463
+ workspace=workspace or self.active_workspace.id,
3430
3464
  user=user,
3431
3465
  pipeline_id=pipeline_id,
3432
3466
  stack_id=stack_id,
3433
3467
  build_id=build_id,
3434
3468
  template_id=template_id,
3435
3469
  )
3436
- deployment_filter_model.set_scope_workspace(self.active_workspace.id)
3437
3470
  return self.zen_store.list_deployments(
3438
3471
  deployment_filter_model=deployment_filter_model,
3439
3472
  hydrate=hydrate,
3440
3473
  )
3441
3474
 
3442
- def delete_deployment(self, id_or_prefix: str) -> None:
3475
+ def delete_deployment(
3476
+ self,
3477
+ id_or_prefix: str,
3478
+ workspace: Optional[Union[str, UUID]] = None,
3479
+ ) -> None:
3443
3480
  """Delete a deployment.
3444
3481
 
3445
3482
  Args:
3446
3483
  id_or_prefix: The id or id prefix of the deployment.
3484
+ workspace: The workspace name/ID to filter by.
3447
3485
  """
3448
3486
  deployment = self.get_deployment(
3449
- id_or_prefix=id_or_prefix, hydrate=False
3487
+ id_or_prefix=id_or_prefix,
3488
+ workspace=workspace,
3489
+ hydrate=False,
3450
3490
  )
3451
3491
  self.zen_store.delete_deployment(deployment_id=deployment.id)
3452
3492
 
@@ -3477,7 +3517,6 @@ class Client(metaclass=ClientMetaClass):
3477
3517
  description=description,
3478
3518
  source_deployment_id=deployment_id,
3479
3519
  tags=tags,
3480
- user=self.active_user.id,
3481
3520
  workspace=self.active_workspace.id,
3482
3521
  )
3483
3522
  )
@@ -3485,12 +3524,14 @@ class Client(metaclass=ClientMetaClass):
3485
3524
  def get_run_template(
3486
3525
  self,
3487
3526
  name_id_or_prefix: Union[str, UUID],
3527
+ workspace: Optional[Union[str, UUID]] = None,
3488
3528
  hydrate: bool = True,
3489
3529
  ) -> RunTemplateResponse:
3490
3530
  """Get a run template.
3491
3531
 
3492
3532
  Args:
3493
3533
  name_id_or_prefix: Name/ID/ID prefix of the template to get.
3534
+ workspace: The workspace name/ID to filter by.
3494
3535
  hydrate: Flag deciding whether to hydrate the output model(s)
3495
3536
  by including metadata fields in the response.
3496
3537
 
@@ -3502,6 +3543,7 @@ class Client(metaclass=ClientMetaClass):
3502
3543
  list_method=self.list_run_templates,
3503
3544
  name_id_or_prefix=name_id_or_prefix,
3504
3545
  allow_name_prefix_match=False,
3546
+ workspace=workspace,
3505
3547
  hydrate=hydrate,
3506
3548
  )
3507
3549
 
@@ -3516,8 +3558,7 @@ class Client(metaclass=ClientMetaClass):
3516
3558
  id: Optional[Union[UUID, str]] = None,
3517
3559
  name: Optional[str] = None,
3518
3560
  tag: Optional[str] = None,
3519
- workspace_id: Optional[Union[str, UUID]] = None,
3520
- user_id: Optional[Union[str, UUID]] = None,
3561
+ workspace: Optional[Union[str, UUID]] = None,
3521
3562
  pipeline_id: Optional[Union[str, UUID]] = None,
3522
3563
  build_id: Optional[Union[str, UUID]] = None,
3523
3564
  stack_id: Optional[Union[str, UUID]] = None,
@@ -3539,8 +3580,7 @@ class Client(metaclass=ClientMetaClass):
3539
3580
  id: Filter by run template ID.
3540
3581
  name: Filter by run template name.
3541
3582
  tag: Filter by run template tags.
3542
- workspace_id: Filter by workspace ID.
3543
- user_id: Filter by user ID.
3583
+ workspace: Filter by workspace name/ID.
3544
3584
  pipeline_id: Filter by pipeline ID.
3545
3585
  build_id: Filter by build ID.
3546
3586
  stack_id: Filter by stack ID.
@@ -3564,8 +3604,7 @@ class Client(metaclass=ClientMetaClass):
3564
3604
  id=id,
3565
3605
  name=name,
3566
3606
  tag=tag,
3567
- workspace_id=workspace_id,
3568
- user_id=user_id,
3607
+ workspace=workspace,
3569
3608
  pipeline_id=pipeline_id,
3570
3609
  build_id=build_id,
3571
3610
  stack_id=stack_id,
@@ -3586,6 +3625,7 @@ class Client(metaclass=ClientMetaClass):
3586
3625
  description: Optional[str] = None,
3587
3626
  add_tags: Optional[List[str]] = None,
3588
3627
  remove_tags: Optional[List[str]] = None,
3628
+ workspace: Optional[Union[str, UUID]] = None,
3589
3629
  ) -> RunTemplateResponse:
3590
3630
  """Update a run template.
3591
3631
 
@@ -3595,6 +3635,7 @@ class Client(metaclass=ClientMetaClass):
3595
3635
  description: The new description of the run template.
3596
3636
  add_tags: Tags to add to the run template.
3597
3637
  remove_tags: Tags to remove from the run template.
3638
+ workspace: The workspace name/ID to filter by.
3598
3639
 
3599
3640
  Returns:
3600
3641
  The updated run template.
@@ -3607,7 +3648,9 @@ class Client(metaclass=ClientMetaClass):
3607
3648
  )
3608
3649
  else:
3609
3650
  template_id = self.get_run_template(
3610
- name_id_or_prefix, hydrate=False
3651
+ name_id_or_prefix,
3652
+ workspace=workspace,
3653
+ hydrate=False,
3611
3654
  ).id
3612
3655
 
3613
3656
  return self.zen_store.update_run_template(
@@ -3620,11 +3663,16 @@ class Client(metaclass=ClientMetaClass):
3620
3663
  ),
3621
3664
  )
3622
3665
 
3623
- def delete_run_template(self, name_id_or_prefix: Union[str, UUID]) -> None:
3666
+ def delete_run_template(
3667
+ self,
3668
+ name_id_or_prefix: Union[str, UUID],
3669
+ workspace: Optional[Union[str, UUID]] = None,
3670
+ ) -> None:
3624
3671
  """Delete a run template.
3625
3672
 
3626
3673
  Args:
3627
3674
  name_id_or_prefix: Name/ID/ID prefix of the template to delete.
3675
+ workspace: The workspace name/ID to filter by.
3628
3676
  """
3629
3677
  if is_valid_uuid(name_id_or_prefix):
3630
3678
  template_id = (
@@ -3634,7 +3682,9 @@ class Client(metaclass=ClientMetaClass):
3634
3682
  )
3635
3683
  else:
3636
3684
  template_id = self.get_run_template(
3637
- name_id_or_prefix, hydrate=False
3685
+ name_id_or_prefix,
3686
+ workspace=workspace,
3687
+ hydrate=False,
3638
3688
  ).id
3639
3689
 
3640
3690
  self.zen_store.delete_run_template(template_id=template_id)
@@ -3645,6 +3695,7 @@ class Client(metaclass=ClientMetaClass):
3645
3695
  self,
3646
3696
  name_id_or_prefix: Union[str, UUID],
3647
3697
  allow_name_prefix_match: bool = True,
3698
+ workspace: Optional[Union[str, UUID]] = None,
3648
3699
  hydrate: bool = True,
3649
3700
  ) -> ScheduleResponse:
3650
3701
  """Get a schedule by name, id or prefix.
@@ -3652,6 +3703,7 @@ class Client(metaclass=ClientMetaClass):
3652
3703
  Args:
3653
3704
  name_id_or_prefix: The name, id or prefix of the schedule.
3654
3705
  allow_name_prefix_match: If True, allow matching by name prefix.
3706
+ workspace: The workspace name/ID to filter by.
3655
3707
  hydrate: Flag deciding whether to hydrate the output model(s)
3656
3708
  by including metadata fields in the response.
3657
3709
 
@@ -3663,6 +3715,7 @@ class Client(metaclass=ClientMetaClass):
3663
3715
  list_method=self.list_schedules,
3664
3716
  name_id_or_prefix=name_id_or_prefix,
3665
3717
  allow_name_prefix_match=allow_name_prefix_match,
3718
+ workspace=workspace,
3666
3719
  hydrate=hydrate,
3667
3720
  )
3668
3721
 
@@ -3676,8 +3729,7 @@ class Client(metaclass=ClientMetaClass):
3676
3729
  created: Optional[Union[datetime, str]] = None,
3677
3730
  updated: Optional[Union[datetime, str]] = None,
3678
3731
  name: Optional[str] = None,
3679
- workspace_id: Optional[Union[str, UUID]] = None,
3680
- user_id: Optional[Union[str, UUID]] = None,
3732
+ workspace: Optional[Union[str, UUID]] = None,
3681
3733
  user: Optional[Union[UUID, str]] = None,
3682
3734
  pipeline_id: Optional[Union[str, UUID]] = None,
3683
3735
  orchestrator_id: Optional[Union[str, UUID]] = None,
@@ -3701,8 +3753,7 @@ class Client(metaclass=ClientMetaClass):
3701
3753
  created: Use to filter by time of creation
3702
3754
  updated: Use the last updated date for filtering
3703
3755
  name: The name of the stack to filter by.
3704
- workspace_id: The id of the workspace to filter by.
3705
- user_id: The id of the user to filter by.
3756
+ workspace: The workspace name/ID to filter by.
3706
3757
  user: Filter by user name/ID.
3707
3758
  pipeline_id: The id of the pipeline to filter by.
3708
3759
  orchestrator_id: The id of the orchestrator to filter by.
@@ -3728,8 +3779,7 @@ class Client(metaclass=ClientMetaClass):
3728
3779
  created=created,
3729
3780
  updated=updated,
3730
3781
  name=name,
3731
- workspace_id=workspace_id,
3732
- user_id=user_id,
3782
+ workspace=workspace or self.active_workspace.id,
3733
3783
  user=user,
3734
3784
  pipeline_id=pipeline_id,
3735
3785
  orchestrator_id=orchestrator_id,
@@ -3741,21 +3791,27 @@ class Client(metaclass=ClientMetaClass):
3741
3791
  catchup=catchup,
3742
3792
  run_once_start_time=run_once_start_time,
3743
3793
  )
3744
- schedule_filter_model.set_scope_workspace(self.active_workspace.id)
3745
3794
  return self.zen_store.list_schedules(
3746
3795
  schedule_filter_model=schedule_filter_model,
3747
3796
  hydrate=hydrate,
3748
3797
  )
3749
3798
 
3750
- def delete_schedule(self, name_id_or_prefix: Union[str, UUID]) -> None:
3799
+ def delete_schedule(
3800
+ self,
3801
+ name_id_or_prefix: Union[str, UUID],
3802
+ workspace: Optional[Union[str, UUID]] = None,
3803
+ ) -> None:
3751
3804
  """Delete a schedule.
3752
3805
 
3753
3806
  Args:
3754
3807
  name_id_or_prefix: The name, id or prefix id of the schedule
3755
3808
  to delete.
3809
+ workspace: The workspace name/ID to filter by.
3756
3810
  """
3757
3811
  schedule = self.get_schedule(
3758
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3812
+ name_id_or_prefix=name_id_or_prefix,
3813
+ allow_name_prefix_match=False,
3814
+ workspace=workspace,
3759
3815
  )
3760
3816
  logger.warning(
3761
3817
  f"Deleting schedule '{name_id_or_prefix}'... This will only delete "
@@ -3770,6 +3826,7 @@ class Client(metaclass=ClientMetaClass):
3770
3826
  self,
3771
3827
  name_id_or_prefix: Union[str, UUID],
3772
3828
  allow_name_prefix_match: bool = True,
3829
+ workspace: Optional[Union[str, UUID]] = None,
3773
3830
  hydrate: bool = True,
3774
3831
  ) -> PipelineRunResponse:
3775
3832
  """Gets a pipeline run by name, ID, or prefix.
@@ -3777,6 +3834,7 @@ class Client(metaclass=ClientMetaClass):
3777
3834
  Args:
3778
3835
  name_id_or_prefix: Name, ID, or prefix of the pipeline run.
3779
3836
  allow_name_prefix_match: If True, allow matching by name prefix.
3837
+ workspace: The workspace name/ID to filter by.
3780
3838
  hydrate: Flag deciding whether to hydrate the output model(s)
3781
3839
  by including metadata fields in the response.
3782
3840
 
@@ -3788,6 +3846,7 @@ class Client(metaclass=ClientMetaClass):
3788
3846
  list_method=self.list_pipeline_runs,
3789
3847
  name_id_or_prefix=name_id_or_prefix,
3790
3848
  allow_name_prefix_match=allow_name_prefix_match,
3849
+ workspace=workspace,
3791
3850
  hydrate=hydrate,
3792
3851
  )
3793
3852
 
@@ -3801,10 +3860,9 @@ class Client(metaclass=ClientMetaClass):
3801
3860
  created: Optional[Union[datetime, str]] = None,
3802
3861
  updated: Optional[Union[datetime, str]] = None,
3803
3862
  name: Optional[str] = None,
3804
- workspace_id: Optional[Union[str, UUID]] = None,
3863
+ workspace: Optional[Union[str, UUID]] = None,
3805
3864
  pipeline_id: Optional[Union[str, UUID]] = None,
3806
3865
  pipeline_name: Optional[str] = None,
3807
- user_id: Optional[Union[str, UUID]] = None,
3808
3866
  stack_id: Optional[Union[str, UUID]] = None,
3809
3867
  schedule_id: Optional[Union[str, UUID]] = None,
3810
3868
  build_id: Optional[Union[str, UUID]] = None,
@@ -3816,10 +3874,10 @@ class Client(metaclass=ClientMetaClass):
3816
3874
  status: Optional[str] = None,
3817
3875
  start_time: Optional[Union[datetime, str]] = None,
3818
3876
  end_time: Optional[Union[datetime, str]] = None,
3819
- num_steps: Optional[Union[int, str]] = None,
3820
3877
  unlisted: Optional[bool] = None,
3821
3878
  templatable: Optional[bool] = None,
3822
3879
  tag: Optional[str] = None,
3880
+ tags: Optional[List[str]] = None,
3823
3881
  user: Optional[Union[UUID, str]] = None,
3824
3882
  run_metadata: Optional[Dict[str, Any]] = None,
3825
3883
  pipeline: Optional[Union[UUID, str]] = None,
@@ -3839,11 +3897,10 @@ class Client(metaclass=ClientMetaClass):
3839
3897
  id: The id of the runs to filter by.
3840
3898
  created: Use to filter by time of creation
3841
3899
  updated: Use the last updated date for filtering
3842
- workspace_id: The id of the workspace to filter by.
3900
+ workspace: The workspace name/ID to filter by.
3843
3901
  pipeline_id: The id of the pipeline to filter by.
3844
3902
  pipeline_name: DEPRECATED. Use `pipeline` instead to filter by
3845
3903
  pipeline name.
3846
- user_id: The id of the user to filter by.
3847
3904
  stack_id: The id of the stack to filter by.
3848
3905
  schedule_id: The id of the schedule to filter by.
3849
3906
  build_id: The id of the build to filter by.
@@ -3856,10 +3913,10 @@ class Client(metaclass=ClientMetaClass):
3856
3913
  status: The status of the pipeline run
3857
3914
  start_time: The start_time for the pipeline run
3858
3915
  end_time: The end_time for the pipeline run
3859
- num_steps: The number of steps for the pipeline run
3860
3916
  unlisted: If the runs should be unlisted or not.
3861
3917
  templatable: If the runs should be templatable or not.
3862
3918
  tag: Tag to filter by.
3919
+ tags: Tags to filter by.
3863
3920
  user: The name/ID of the user to filter by.
3864
3921
  run_metadata: The run_metadata of the run to filter by.
3865
3922
  pipeline: The name/ID of the pipeline to filter by.
@@ -3882,7 +3939,7 @@ class Client(metaclass=ClientMetaClass):
3882
3939
  created=created,
3883
3940
  updated=updated,
3884
3941
  name=name,
3885
- workspace_id=workspace_id,
3942
+ workspace=workspace or self.active_workspace.id,
3886
3943
  pipeline_id=pipeline_id,
3887
3944
  pipeline_name=pipeline_name,
3888
3945
  schedule_id=schedule_id,
@@ -3892,13 +3949,12 @@ class Client(metaclass=ClientMetaClass):
3892
3949
  template_id=template_id,
3893
3950
  model_version_id=model_version_id,
3894
3951
  orchestrator_run_id=orchestrator_run_id,
3895
- user_id=user_id,
3896
3952
  stack_id=stack_id,
3897
3953
  status=status,
3898
3954
  start_time=start_time,
3899
3955
  end_time=end_time,
3900
- num_steps=num_steps,
3901
3956
  tag=tag,
3957
+ tags=tags,
3902
3958
  unlisted=unlisted,
3903
3959
  user=user,
3904
3960
  run_metadata=run_metadata,
@@ -3909,7 +3965,6 @@ class Client(metaclass=ClientMetaClass):
3909
3965
  stack_component=stack_component,
3910
3966
  templatable=templatable,
3911
3967
  )
3912
- runs_filter_model.set_scope_workspace(self.active_workspace.id)
3913
3968
  return self.zen_store.list_runs(
3914
3969
  runs_filter_model=runs_filter_model,
3915
3970
  hydrate=hydrate,
@@ -3918,14 +3973,18 @@ class Client(metaclass=ClientMetaClass):
3918
3973
  def delete_pipeline_run(
3919
3974
  self,
3920
3975
  name_id_or_prefix: Union[str, UUID],
3976
+ workspace: Optional[Union[str, UUID]] = None,
3921
3977
  ) -> None:
3922
3978
  """Deletes a pipeline run.
3923
3979
 
3924
3980
  Args:
3925
3981
  name_id_or_prefix: Name, ID, or prefix of the pipeline run.
3982
+ workspace: The workspace name/ID to filter by.
3926
3983
  """
3927
3984
  run = self.get_pipeline_run(
3928
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
3985
+ name_id_or_prefix=name_id_or_prefix,
3986
+ allow_name_prefix_match=False,
3987
+ workspace=workspace,
3929
3988
  )
3930
3989
  self.zen_store.delete_run(run_id=run.id)
3931
3990
 
@@ -3969,8 +4028,7 @@ class Client(metaclass=ClientMetaClass):
3969
4028
  pipeline_run_id: Optional[Union[str, UUID]] = None,
3970
4029
  deployment_id: Optional[Union[str, UUID]] = None,
3971
4030
  original_step_run_id: Optional[Union[str, UUID]] = None,
3972
- workspace_id: Optional[Union[str, UUID]] = None,
3973
- user_id: Optional[Union[str, UUID]] = None,
4031
+ workspace: Optional[Union[str, UUID]] = None,
3974
4032
  user: Optional[Union[UUID, str]] = None,
3975
4033
  model_version_id: Optional[Union[str, UUID]] = None,
3976
4034
  model: Optional[Union[UUID, str]] = None,
@@ -3989,8 +4047,7 @@ class Client(metaclass=ClientMetaClass):
3989
4047
  updated: Use the last updated date for filtering
3990
4048
  start_time: Use to filter by the time when the step started running
3991
4049
  end_time: Use to filter by the time when the step finished running
3992
- workspace_id: The id of the workspace to filter by.
3993
- user_id: The id of the user to filter by.
4050
+ workspace: The workspace name/ID to filter by.
3994
4051
  user: Filter by user name/ID.
3995
4052
  pipeline_run_id: The id of the pipeline run to filter by.
3996
4053
  deployment_id: The id of the deployment to filter by.
@@ -4025,14 +4082,12 @@ class Client(metaclass=ClientMetaClass):
4025
4082
  start_time=start_time,
4026
4083
  end_time=end_time,
4027
4084
  name=name,
4028
- workspace_id=workspace_id,
4029
- user_id=user_id,
4085
+ workspace=workspace or self.active_workspace.id,
4030
4086
  user=user,
4031
4087
  model_version_id=model_version_id,
4032
4088
  model=model,
4033
4089
  run_metadata=run_metadata,
4034
4090
  )
4035
- step_run_filter_model.set_scope_workspace(self.active_workspace.id)
4036
4091
  return self.zen_store.list_run_steps(
4037
4092
  step_run_filter_model=step_run_filter_model,
4038
4093
  hydrate=hydrate,
@@ -4043,12 +4098,14 @@ class Client(metaclass=ClientMetaClass):
4043
4098
  def get_artifact(
4044
4099
  self,
4045
4100
  name_id_or_prefix: Union[str, UUID],
4101
+ workspace: Optional[Union[str, UUID]] = None,
4046
4102
  hydrate: bool = False,
4047
4103
  ) -> ArtifactResponse:
4048
4104
  """Get an artifact by name, id or prefix.
4049
4105
 
4050
4106
  Args:
4051
4107
  name_id_or_prefix: The name, ID or prefix of the artifact to get.
4108
+ workspace: The workspace name/ID to filter by.
4052
4109
  hydrate: Flag deciding whether to hydrate the output model(s)
4053
4110
  by including metadata fields in the response.
4054
4111
 
@@ -4059,6 +4116,7 @@ class Client(metaclass=ClientMetaClass):
4059
4116
  get_method=self.zen_store.get_artifact,
4060
4117
  list_method=self.list_artifacts,
4061
4118
  name_id_or_prefix=name_id_or_prefix,
4119
+ workspace=workspace,
4062
4120
  hydrate=hydrate,
4063
4121
  )
4064
4122
 
@@ -4073,8 +4131,11 @@ class Client(metaclass=ClientMetaClass):
4073
4131
  updated: Optional[Union[datetime, str]] = None,
4074
4132
  name: Optional[str] = None,
4075
4133
  has_custom_name: Optional[bool] = None,
4134
+ user: Optional[Union[UUID, str]] = None,
4135
+ workspace: Optional[Union[str, UUID]] = None,
4076
4136
  hydrate: bool = False,
4077
4137
  tag: Optional[str] = None,
4138
+ tags: Optional[List[str]] = None,
4078
4139
  ) -> Page[ArtifactResponse]:
4079
4140
  """Get a list of artifacts.
4080
4141
 
@@ -4088,9 +4149,12 @@ class Client(metaclass=ClientMetaClass):
4088
4149
  updated: Use the last updated date for filtering
4089
4150
  name: The name of the artifact to filter by.
4090
4151
  has_custom_name: Filter artifacts with/without custom names.
4152
+ user: Filter by user name or ID.
4153
+ workspace: The workspace name/ID to filter by.
4091
4154
  hydrate: Flag deciding whether to hydrate the output model(s)
4092
4155
  by including metadata fields in the response.
4093
4156
  tag: Filter artifacts by tag.
4157
+ tags: Tags to filter by.
4094
4158
 
4095
4159
  Returns:
4096
4160
  A list of artifacts.
@@ -4106,6 +4170,9 @@ class Client(metaclass=ClientMetaClass):
4106
4170
  name=name,
4107
4171
  has_custom_name=has_custom_name,
4108
4172
  tag=tag,
4173
+ tags=tags,
4174
+ user=user,
4175
+ workspace=workspace or self.active_workspace.id,
4109
4176
  )
4110
4177
  return self.zen_store.list_artifacts(
4111
4178
  artifact_filter_model,
@@ -4119,6 +4186,7 @@ class Client(metaclass=ClientMetaClass):
4119
4186
  add_tags: Optional[List[str]] = None,
4120
4187
  remove_tags: Optional[List[str]] = None,
4121
4188
  has_custom_name: Optional[bool] = None,
4189
+ workspace: Optional[Union[str, UUID]] = None,
4122
4190
  ) -> ArtifactResponse:
4123
4191
  """Update an artifact.
4124
4192
 
@@ -4128,11 +4196,15 @@ class Client(metaclass=ClientMetaClass):
4128
4196
  add_tags: Tags to add to the artifact.
4129
4197
  remove_tags: Tags to remove from the artifact.
4130
4198
  has_custom_name: Whether the artifact has a custom name.
4199
+ workspace: The workspace name/ID to filter by.
4131
4200
 
4132
4201
  Returns:
4133
4202
  The updated artifact.
4134
4203
  """
4135
- artifact = self.get_artifact(name_id_or_prefix=name_id_or_prefix)
4204
+ artifact = self.get_artifact(
4205
+ name_id_or_prefix=name_id_or_prefix,
4206
+ workspace=workspace,
4207
+ )
4136
4208
  artifact_update = ArtifactUpdate(
4137
4209
  name=new_name,
4138
4210
  add_tags=add_tags,
@@ -4146,13 +4218,18 @@ class Client(metaclass=ClientMetaClass):
4146
4218
  def delete_artifact(
4147
4219
  self,
4148
4220
  name_id_or_prefix: Union[str, UUID],
4221
+ workspace: Optional[Union[str, UUID]] = None,
4149
4222
  ) -> None:
4150
4223
  """Delete an artifact.
4151
4224
 
4152
4225
  Args:
4153
4226
  name_id_or_prefix: The name, ID or prefix of the artifact to delete.
4227
+ workspace: The workspace name/ID to filter by.
4154
4228
  """
4155
- artifact = self.get_artifact(name_id_or_prefix=name_id_or_prefix)
4229
+ artifact = self.get_artifact(
4230
+ name_id_or_prefix=name_id_or_prefix,
4231
+ workspace=workspace,
4232
+ )
4156
4233
  self.zen_store.delete_artifact(artifact_id=artifact.id)
4157
4234
  logger.info(f"Deleted artifact '{artifact.name}'.")
4158
4235
 
@@ -4160,23 +4237,31 @@ class Client(metaclass=ClientMetaClass):
4160
4237
  self,
4161
4238
  only_versions: bool = True,
4162
4239
  delete_from_artifact_store: bool = False,
4240
+ workspace: Optional[Union[str, UUID]] = None,
4163
4241
  ) -> None:
4164
4242
  """Delete all unused artifacts and artifact versions.
4165
4243
 
4166
4244
  Args:
4167
4245
  only_versions: Only delete artifact versions, keeping artifacts
4168
4246
  delete_from_artifact_store: Delete data from artifact metadata
4247
+ workspace: The workspace name/ID to filter by.
4169
4248
  """
4170
4249
  if delete_from_artifact_store:
4171
4250
  unused_artifact_versions = depaginate(
4172
- self.list_artifact_versions, only_unused=True
4251
+ self.list_artifact_versions,
4252
+ only_unused=True,
4253
+ workspace=workspace,
4173
4254
  )
4174
4255
  for unused_artifact_version in unused_artifact_versions:
4175
4256
  self._delete_artifact_from_artifact_store(
4176
4257
  unused_artifact_version
4177
4258
  )
4178
4259
 
4179
- self.zen_store.prune_artifact_versions(only_versions)
4260
+ workspace = workspace or self.active_workspace.id
4261
+
4262
+ self.zen_store.prune_artifact_versions(
4263
+ workspace_name_or_id=workspace, only_versions=only_versions
4264
+ )
4180
4265
  logger.info("All unused artifacts and artifact versions deleted.")
4181
4266
 
4182
4267
  # --------------------------- Artifact Versions ---------------------------
@@ -4185,6 +4270,7 @@ class Client(metaclass=ClientMetaClass):
4185
4270
  self,
4186
4271
  name_id_or_prefix: Union[str, UUID],
4187
4272
  version: Optional[str] = None,
4273
+ workspace: Optional[Union[str, UUID]] = None,
4188
4274
  hydrate: bool = True,
4189
4275
  ) -> ArtifactVersionResponse:
4190
4276
  """Get an artifact version by ID or artifact name.
@@ -4195,6 +4281,7 @@ class Client(metaclass=ClientMetaClass):
4195
4281
  version: The version of the artifact to get. Only used if
4196
4282
  `name_id_or_prefix` is the name of the artifact. If not
4197
4283
  specified, the latest version is returned.
4284
+ workspace: The workspace name/ID to filter by.
4198
4285
  hydrate: Flag deciding whether to hydrate the output model(s)
4199
4286
  by including metadata fields in the response.
4200
4287
 
@@ -4207,6 +4294,7 @@ class Client(metaclass=ClientMetaClass):
4207
4294
  method_name="get_artifact_version",
4208
4295
  name_id_or_prefix=name_id_or_prefix,
4209
4296
  version=version,
4297
+ workspace=workspace,
4210
4298
  hydrate=hydrate,
4211
4299
  ):
4212
4300
  return cll # type: ignore[return-value]
@@ -4216,6 +4304,7 @@ class Client(metaclass=ClientMetaClass):
4216
4304
  list_method=self.list_artifact_versions,
4217
4305
  name_id_or_prefix=name_id_or_prefix,
4218
4306
  version=version,
4307
+ workspace=workspace,
4219
4308
  hydrate=hydrate,
4220
4309
  )
4221
4310
  try:
@@ -4240,7 +4329,7 @@ class Client(metaclass=ClientMetaClass):
4240
4329
  id: Optional[Union[UUID, str]] = None,
4241
4330
  created: Optional[Union[datetime, str]] = None,
4242
4331
  updated: Optional[Union[datetime, str]] = None,
4243
- artifact_id: Optional[Union[str, UUID]] = None,
4332
+ artifact: Optional[Union[str, UUID]] = None,
4244
4333
  name: Optional[str] = None,
4245
4334
  version: Optional[Union[str, int]] = None,
4246
4335
  version_number: Optional[int] = None,
@@ -4249,8 +4338,7 @@ class Client(metaclass=ClientMetaClass):
4249
4338
  data_type: Optional[str] = None,
4250
4339
  uri: Optional[str] = None,
4251
4340
  materializer: Optional[str] = None,
4252
- workspace_id: Optional[Union[str, UUID]] = None,
4253
- user_id: Optional[Union[str, UUID]] = None,
4341
+ workspace: Optional[Union[str, UUID]] = None,
4254
4342
  model_version_id: Optional[Union[str, UUID]] = None,
4255
4343
  only_unused: Optional[bool] = False,
4256
4344
  has_custom_name: Optional[bool] = None,
@@ -4259,6 +4347,7 @@ class Client(metaclass=ClientMetaClass):
4259
4347
  pipeline_run: Optional[Union[UUID, str]] = None,
4260
4348
  run_metadata: Optional[Dict[str, Any]] = None,
4261
4349
  tag: Optional[str] = None,
4350
+ tags: Optional[List[str]] = None,
4262
4351
  hydrate: bool = False,
4263
4352
  ) -> Page[ArtifactVersionResponse]:
4264
4353
  """Get a list of artifact versions.
@@ -4271,7 +4360,7 @@ class Client(metaclass=ClientMetaClass):
4271
4360
  id: Use the id of artifact version to filter by.
4272
4361
  created: Use to filter by time of creation
4273
4362
  updated: Use the last updated date for filtering
4274
- artifact_id: The id of the artifact to filter by.
4363
+ artifact: The name or ID of the artifact to filter by.
4275
4364
  name: The name of the artifact to filter by.
4276
4365
  version: The version of the artifact to filter by.
4277
4366
  version_number: The version number of the artifact to filter by.
@@ -4280,13 +4369,13 @@ class Client(metaclass=ClientMetaClass):
4280
4369
  data_type: The data type of the artifact to filter by.
4281
4370
  uri: The uri of the artifact to filter by.
4282
4371
  materializer: The materializer of the artifact to filter by.
4283
- workspace_id: The id of the workspace to filter by.
4284
- user_id: The id of the user to filter by.
4372
+ workspace: The workspace name/ID to filter by.
4285
4373
  model_version_id: Filter by model version ID.
4286
4374
  only_unused: Only return artifact versions that are not used in
4287
4375
  any pipeline runs.
4288
4376
  has_custom_name: Filter artifacts with/without custom names.
4289
4377
  tag: A tag to filter by.
4378
+ tags: Tags to filter by.
4290
4379
  user: Filter by user name or ID.
4291
4380
  model: Filter by model name or ID.
4292
4381
  pipeline_run: Filter by pipeline run name or ID.
@@ -4297,6 +4386,9 @@ class Client(metaclass=ClientMetaClass):
4297
4386
  Returns:
4298
4387
  A list of artifact versions.
4299
4388
  """
4389
+ if name:
4390
+ artifact = name
4391
+
4300
4392
  artifact_version_filter_model = ArtifactVersionFilter(
4301
4393
  sort_by=sort_by,
4302
4394
  page=page,
@@ -4305,8 +4397,7 @@ class Client(metaclass=ClientMetaClass):
4305
4397
  id=id,
4306
4398
  created=created,
4307
4399
  updated=updated,
4308
- artifact_id=artifact_id,
4309
- name=name,
4400
+ artifact=artifact,
4310
4401
  version=str(version) if version else None,
4311
4402
  version_number=version_number,
4312
4403
  artifact_store_id=artifact_store_id,
@@ -4314,20 +4405,17 @@ class Client(metaclass=ClientMetaClass):
4314
4405
  data_type=data_type,
4315
4406
  uri=uri,
4316
4407
  materializer=materializer,
4317
- workspace_id=workspace_id,
4318
- user_id=user_id,
4408
+ workspace=workspace or self.active_workspace.id,
4319
4409
  model_version_id=model_version_id,
4320
4410
  only_unused=only_unused,
4321
4411
  has_custom_name=has_custom_name,
4322
4412
  tag=tag,
4413
+ tags=tags,
4323
4414
  user=user,
4324
4415
  model=model,
4325
4416
  pipeline_run=pipeline_run,
4326
4417
  run_metadata=run_metadata,
4327
4418
  )
4328
- artifact_version_filter_model.set_scope_workspace(
4329
- self.active_workspace.id
4330
- )
4331
4419
  return self.zen_store.list_artifact_versions(
4332
4420
  artifact_version_filter_model,
4333
4421
  hydrate=hydrate,
@@ -4339,6 +4427,7 @@ class Client(metaclass=ClientMetaClass):
4339
4427
  version: Optional[str] = None,
4340
4428
  add_tags: Optional[List[str]] = None,
4341
4429
  remove_tags: Optional[List[str]] = None,
4430
+ workspace: Optional[Union[str, UUID]] = None,
4342
4431
  ) -> ArtifactVersionResponse:
4343
4432
  """Update an artifact version.
4344
4433
 
@@ -4349,6 +4438,7 @@ class Client(metaclass=ClientMetaClass):
4349
4438
  specified, the latest version is updated.
4350
4439
  add_tags: Tags to add to the artifact version.
4351
4440
  remove_tags: Tags to remove from the artifact version.
4441
+ workspace: The workspace name/ID to filter by.
4352
4442
 
4353
4443
  Returns:
4354
4444
  The updated artifact version.
@@ -4356,6 +4446,7 @@ class Client(metaclass=ClientMetaClass):
4356
4446
  artifact_version = self.get_artifact_version(
4357
4447
  name_id_or_prefix=name_id_or_prefix,
4358
4448
  version=version,
4449
+ workspace=workspace,
4359
4450
  )
4360
4451
  artifact_version_update = ArtifactVersionUpdate(
4361
4452
  add_tags=add_tags, remove_tags=remove_tags
@@ -4371,6 +4462,7 @@ class Client(metaclass=ClientMetaClass):
4371
4462
  version: Optional[str] = None,
4372
4463
  delete_metadata: bool = True,
4373
4464
  delete_from_artifact_store: bool = False,
4465
+ workspace: Optional[Union[str, UUID]] = None,
4374
4466
  ) -> None:
4375
4467
  """Delete an artifact version.
4376
4468
 
@@ -4384,10 +4476,13 @@ class Client(metaclass=ClientMetaClass):
4384
4476
  delete_metadata: If True, delete the metadata of the artifact
4385
4477
  version from the database.
4386
4478
  delete_from_artifact_store: If True, delete the artifact object
4387
- itself from the artifact store.
4479
+ itself from the artifact store.
4480
+ workspace: The workspace name/ID to filter by.
4388
4481
  """
4389
4482
  artifact_version = self.get_artifact_version(
4390
- name_id_or_prefix=name_id_or_prefix, version=version
4483
+ name_id_or_prefix=name_id_or_prefix,
4484
+ version=version,
4485
+ workspace=workspace,
4391
4486
  )
4392
4487
  if delete_from_artifact_store:
4393
4488
  self._delete_artifact_from_artifact_store(
@@ -4511,7 +4606,6 @@ class Client(metaclass=ClientMetaClass):
4511
4606
 
4512
4607
  run_metadata = RunMetadataRequest(
4513
4608
  workspace=self.active_workspace.id,
4514
- user=self.active_user.id,
4515
4609
  resources=resources,
4516
4610
  stack_component_id=stack_component_id,
4517
4611
  publisher_step_id=publisher_step_id,
@@ -4526,14 +4620,15 @@ class Client(metaclass=ClientMetaClass):
4526
4620
  self,
4527
4621
  name: str,
4528
4622
  values: Dict[str, str],
4529
- scope: SecretScope = SecretScope.WORKSPACE,
4623
+ private: bool = False,
4530
4624
  ) -> SecretResponse:
4531
4625
  """Creates a new secret.
4532
4626
 
4533
4627
  Args:
4534
4628
  name: The name of the secret.
4535
4629
  values: The values of the secret.
4536
- scope: The scope of the secret.
4630
+ private: Whether the secret is private. A private secret is only
4631
+ accessible to the user who created it.
4537
4632
 
4538
4633
  Returns:
4539
4634
  The created secret (in model form).
@@ -4545,9 +4640,7 @@ class Client(metaclass=ClientMetaClass):
4545
4640
  create_secret_request = SecretRequest(
4546
4641
  name=name,
4547
4642
  values=values,
4548
- scope=scope,
4549
- user=self.active_user.id,
4550
- workspace=self.active_workspace.id,
4643
+ private=private,
4551
4644
  )
4552
4645
  try:
4553
4646
  return self.zen_store.create_secret(secret=create_secret_request)
@@ -4560,7 +4653,7 @@ class Client(metaclass=ClientMetaClass):
4560
4653
  def get_secret(
4561
4654
  self,
4562
4655
  name_id_or_prefix: Union[str, UUID],
4563
- scope: Optional[SecretScope] = None,
4656
+ private: Optional[bool] = None,
4564
4657
  allow_partial_name_match: bool = True,
4565
4658
  allow_partial_id_match: bool = True,
4566
4659
  hydrate: bool = True,
@@ -4570,18 +4663,17 @@ class Client(metaclass=ClientMetaClass):
4570
4663
  Get a secret identified by a name, ID or prefix of the name or ID and
4571
4664
  optionally a scope.
4572
4665
 
4573
- If a scope is not provided, the secret will be searched for in all
4574
- scopes starting with the innermost scope (user) to the outermost scope
4575
- (workspace). When a name or prefix is used instead of a UUID value, each
4576
- scope is first searched for an exact match, then for a ID prefix or
4577
- name substring match before moving on to the next scope.
4666
+ If a private status is not provided, privately scoped secrets will be
4667
+ searched for first, followed by publicly scoped secrets. When a name or
4668
+ prefix is used instead of a UUID value, each scope is first searched for
4669
+ an exact match, then for a ID prefix or name substring match before
4670
+ moving on to the next scope.
4578
4671
 
4579
4672
  Args:
4580
4673
  name_id_or_prefix: The name, ID or prefix to the id of the secret
4581
4674
  to get.
4582
- scope: The scope of the secret. If not set, all scopes will be
4583
- searched starting with the innermost scope (user) to the
4584
- outermost scope (global) until a secret is found.
4675
+ private: Whether the secret is private. If not set, all secrets will
4676
+ be searched for, prioritizing privately scoped secrets.
4585
4677
  allow_partial_name_match: If True, allow partial name matches.
4586
4678
  allow_partial_id_match: If True, allow partial ID matches.
4587
4679
  hydrate: Flag deciding whether to hydrate the output model(s)
@@ -4608,7 +4700,7 @@ class Client(metaclass=ClientMetaClass):
4608
4700
  else name_id_or_prefix,
4609
4701
  hydrate=hydrate,
4610
4702
  )
4611
- if scope is not None and secret.scope != scope:
4703
+ if private is not None and secret.private != private:
4612
4704
  raise KeyError(
4613
4705
  f"No secret found with ID {str(name_id_or_prefix)}"
4614
4706
  )
@@ -4623,11 +4715,9 @@ class Client(metaclass=ClientMetaClass):
4623
4715
  # If not a UUID, try to find by name and then by prefix
4624
4716
  assert not isinstance(name_id_or_prefix, UUID)
4625
4717
 
4626
- # Scopes to search in order of priority
4627
- search_scopes = (
4628
- [SecretScope.USER, SecretScope.WORKSPACE]
4629
- if scope is None
4630
- else [scope]
4718
+ # Private statuses to search in order of priority
4719
+ search_private_statuses = (
4720
+ [False, True] if private is None else [private]
4631
4721
  )
4632
4722
 
4633
4723
  secrets = self.list_secrets(
@@ -4641,10 +4731,10 @@ class Client(metaclass=ClientMetaClass):
4641
4731
  hydrate=hydrate,
4642
4732
  )
4643
4733
 
4644
- for search_scope in search_scopes:
4734
+ for search_private_status in search_private_statuses:
4645
4735
  partial_matches: List[SecretResponse] = []
4646
4736
  for secret in secrets.items:
4647
- if secret.scope != search_scope:
4737
+ if secret.private != search_private_status:
4648
4738
  continue
4649
4739
  # Exact match
4650
4740
  if secret.name == name_id_or_prefix:
@@ -4679,10 +4769,13 @@ class Client(metaclass=ClientMetaClass):
4679
4769
  secret_id=partial_matches[0].id,
4680
4770
  hydrate=hydrate,
4681
4771
  )
4682
-
4683
- msg = f"No secret found with name, ID or prefix '{name_id_or_prefix}'"
4684
- if scope is not None:
4685
- msg += f" in scope '{scope}'"
4772
+ private_status = ""
4773
+ if private is not None:
4774
+ private_status = "private " if private else "public "
4775
+ msg = (
4776
+ f"No {private_status}secret found with name, ID or prefix "
4777
+ f"'{name_id_or_prefix}'"
4778
+ )
4686
4779
 
4687
4780
  raise KeyError(msg)
4688
4781
 
@@ -4696,9 +4789,7 @@ class Client(metaclass=ClientMetaClass):
4696
4789
  created: Optional[datetime] = None,
4697
4790
  updated: Optional[datetime] = None,
4698
4791
  name: Optional[str] = None,
4699
- scope: Optional[SecretScope] = None,
4700
- workspace_id: Optional[Union[str, UUID]] = None,
4701
- user_id: Optional[Union[str, UUID]] = None,
4792
+ private: Optional[bool] = None,
4702
4793
  user: Optional[Union[UUID, str]] = None,
4703
4794
  hydrate: bool = False,
4704
4795
  ) -> Page[SecretResponse]:
@@ -4716,9 +4807,7 @@ class Client(metaclass=ClientMetaClass):
4716
4807
  created: Use to secrets by time of creation
4717
4808
  updated: Use the last updated date for filtering
4718
4809
  name: The name of the secret to filter by.
4719
- scope: The scope of the secret to filter by.
4720
- workspace_id: The id of the workspace to filter by.
4721
- user_id: The id of the user to filter by.
4810
+ private: The private status of the secret to filter by.
4722
4811
  user: Filter by user name/ID.
4723
4812
  hydrate: Flag deciding whether to hydrate the output model(s)
4724
4813
  by including metadata fields in the response.
@@ -4735,16 +4824,13 @@ class Client(metaclass=ClientMetaClass):
4735
4824
  size=size,
4736
4825
  sort_by=sort_by,
4737
4826
  logical_operator=logical_operator,
4738
- user_id=user_id,
4739
4827
  user=user,
4740
- workspace_id=workspace_id,
4741
4828
  name=name,
4742
- scope=scope,
4829
+ private=private,
4743
4830
  id=id,
4744
4831
  created=created,
4745
4832
  updated=updated,
4746
4833
  )
4747
- secret_filter_model.set_scope_workspace(self.active_workspace.id)
4748
4834
  try:
4749
4835
  return self.zen_store.list_secrets(
4750
4836
  secret_filter_model=secret_filter_model,
@@ -4759,9 +4845,9 @@ class Client(metaclass=ClientMetaClass):
4759
4845
  def update_secret(
4760
4846
  self,
4761
4847
  name_id_or_prefix: Union[str, UUID],
4762
- scope: Optional[SecretScope] = None,
4848
+ private: Optional[bool] = None,
4763
4849
  new_name: Optional[str] = None,
4764
- new_scope: Optional[SecretScope] = None,
4850
+ update_private: Optional[bool] = None,
4765
4851
  add_or_update_values: Optional[Dict[str, str]] = None,
4766
4852
  remove_values: Optional[List[str]] = None,
4767
4853
  ) -> SecretResponse:
@@ -4770,9 +4856,10 @@ class Client(metaclass=ClientMetaClass):
4770
4856
  Args:
4771
4857
  name_id_or_prefix: The name, id or prefix of the id for the
4772
4858
  secret to update.
4773
- scope: The scope of the secret to update.
4859
+ private: The private status of the secret to update.
4774
4860
  new_name: The new name of the secret.
4775
- new_scope: The new scope of the secret.
4861
+ update_private: New value used to update the private status of the
4862
+ secret.
4776
4863
  add_or_update_values: The values to add or update.
4777
4864
  remove_values: The values to remove.
4778
4865
 
@@ -4786,7 +4873,7 @@ class Client(metaclass=ClientMetaClass):
4786
4873
  """
4787
4874
  secret = self.get_secret(
4788
4875
  name_id_or_prefix=name_id_or_prefix,
4789
- scope=scope,
4876
+ private=private,
4790
4877
  # Don't allow partial name matches, but allow partial ID matches
4791
4878
  allow_partial_name_match=False,
4792
4879
  allow_partial_id_match=True,
@@ -4795,8 +4882,8 @@ class Client(metaclass=ClientMetaClass):
4795
4882
 
4796
4883
  secret_update = SecretUpdate(name=new_name or secret.name)
4797
4884
 
4798
- if new_scope:
4799
- secret_update.scope = new_scope
4885
+ if update_private:
4886
+ secret_update.private = update_private
4800
4887
  values: Dict[str, Optional[SecretStr]] = {}
4801
4888
  if add_or_update_values:
4802
4889
  values.update(
@@ -4826,17 +4913,17 @@ class Client(metaclass=ClientMetaClass):
4826
4913
  )
4827
4914
 
4828
4915
  def delete_secret(
4829
- self, name_id_or_prefix: str, scope: Optional[SecretScope] = None
4916
+ self, name_id_or_prefix: str, private: Optional[bool] = None
4830
4917
  ) -> None:
4831
4918
  """Deletes a secret.
4832
4919
 
4833
4920
  Args:
4834
4921
  name_id_or_prefix: The name or ID of the secret.
4835
- scope: The scope of the secret to delete.
4922
+ private: The private status of the secret to delete.
4836
4923
  """
4837
4924
  secret = self.get_secret(
4838
4925
  name_id_or_prefix=name_id_or_prefix,
4839
- scope=scope,
4926
+ private=private,
4840
4927
  # Don't allow partial name matches, but allow partial ID matches
4841
4928
  allow_partial_name_match=False,
4842
4929
  allow_partial_id_match=True,
@@ -4844,23 +4931,24 @@ class Client(metaclass=ClientMetaClass):
4844
4931
 
4845
4932
  self.zen_store.delete_secret(secret_id=secret.id)
4846
4933
 
4847
- def get_secret_by_name_and_scope(
4934
+ def get_secret_by_name_and_private_status(
4848
4935
  self,
4849
4936
  name: str,
4850
- scope: Optional[SecretScope] = None,
4937
+ private: Optional[bool] = None,
4851
4938
  hydrate: bool = True,
4852
4939
  ) -> SecretResponse:
4853
- """Fetches a registered secret with a given name and optional scope.
4940
+ """Fetches a registered secret with a given name and optional private status.
4854
4941
 
4855
4942
  This is a version of get_secret that restricts the search to a given
4856
- name and an optional scope, without doing any prefix or UUID matching.
4943
+ name and an optional private status, without doing any prefix or UUID
4944
+ matching.
4857
4945
 
4858
- If no scope is provided, the search will be done first in the user
4859
- scope, then in the workspace scope.
4946
+ If no private status is provided, the search will be done first for
4947
+ private secrets, then for public secrets.
4860
4948
 
4861
4949
  Args:
4862
4950
  name: The name of the secret to get.
4863
- scope: The scope of the secret to get.
4951
+ private: The private status of the secret to get.
4864
4952
  hydrate: Flag deciding whether to hydrate the output model(s)
4865
4953
  by including metadata fields in the response.
4866
4954
 
@@ -4871,21 +4959,20 @@ class Client(metaclass=ClientMetaClass):
4871
4959
  KeyError: If no secret exists for the given name in the given scope.
4872
4960
  """
4873
4961
  logger.debug(
4874
- f"Fetching the secret with name '{name}' and scope '{scope}'."
4962
+ f"Fetching the secret with name '{name}' and private status "
4963
+ f"'{private}'."
4875
4964
  )
4876
4965
 
4877
- # Scopes to search in order of priority
4878
- search_scopes = (
4879
- [SecretScope.USER, SecretScope.WORKSPACE]
4880
- if scope is None
4881
- else [scope]
4966
+ # Private statuses to search in order of priority
4967
+ search_private_statuses = (
4968
+ [False, True] if private is None else [private]
4882
4969
  )
4883
4970
 
4884
- for search_scope in search_scopes:
4971
+ for search_private_status in search_private_statuses:
4885
4972
  secrets = self.list_secrets(
4886
4973
  logical_operator=LogicalOperators.AND,
4887
4974
  name=f"equals:{name}",
4888
- scope=search_scope,
4975
+ private=search_private_status,
4889
4976
  hydrate=hydrate,
4890
4977
  )
4891
4978
 
@@ -4895,33 +4982,34 @@ class Client(metaclass=ClientMetaClass):
4895
4982
  secret_id=secrets.items[0].id, hydrate=hydrate
4896
4983
  )
4897
4984
 
4898
- msg = f"No secret with name '{name}' was found"
4899
- if scope is not None:
4900
- msg += f" in scope '{scope.value}'"
4985
+ private_status = ""
4986
+ if private is not None:
4987
+ private_status = "private " if private else "public "
4988
+ msg = f"No {private_status}secret with name '{name}' was found"
4901
4989
 
4902
4990
  raise KeyError(msg)
4903
4991
 
4904
- def list_secrets_in_scope(
4992
+ def list_secrets_by_private_status(
4905
4993
  self,
4906
- scope: SecretScope,
4994
+ private: bool,
4907
4995
  hydrate: bool = False,
4908
4996
  ) -> Page[SecretResponse]:
4909
- """Fetches the list of secret in a given scope.
4997
+ """Fetches the list of secrets with a given private status.
4910
4998
 
4911
4999
  The returned secrets do not contain the secret values. To get the
4912
5000
  secret values, use `get_secret` individually for each secret.
4913
5001
 
4914
5002
  Args:
4915
- scope: The secrets scope to search for.
5003
+ private: The private status of the secrets to search for.
4916
5004
  hydrate: Flag deciding whether to hydrate the output model(s)
4917
5005
  by including metadata fields in the response.
4918
5006
 
4919
5007
  Returns:
4920
5008
  The list of secrets in the given scope without the secret values.
4921
5009
  """
4922
- logger.debug(f"Fetching the secrets in scope {scope.value}.")
5010
+ logger.debug(f"Fetching the secrets with private status '{private}'.")
4923
5011
 
4924
- return self.list_secrets(scope=scope, hydrate=hydrate)
5012
+ return self.list_secrets(private=private, hydrate=hydrate)
4925
5013
 
4926
5014
  def backup_secrets(
4927
5015
  self,
@@ -5012,7 +5100,6 @@ class Client(metaclass=ClientMetaClass):
5012
5100
  """
5013
5101
  self._validate_code_repository_config(source=source, config=config)
5014
5102
  repo_request = CodeRepositoryRequest(
5015
- user=self.active_user.id,
5016
5103
  workspace=self.active_workspace.id,
5017
5104
  name=name,
5018
5105
  config=config,
@@ -5028,6 +5115,7 @@ class Client(metaclass=ClientMetaClass):
5028
5115
  self,
5029
5116
  name_id_or_prefix: Union[str, UUID],
5030
5117
  allow_name_prefix_match: bool = True,
5118
+ workspace: Optional[Union[str, UUID]] = None,
5031
5119
  hydrate: bool = True,
5032
5120
  ) -> CodeRepositoryResponse:
5033
5121
  """Get a code repository by name, id or prefix.
@@ -5035,6 +5123,7 @@ class Client(metaclass=ClientMetaClass):
5035
5123
  Args:
5036
5124
  name_id_or_prefix: The name, ID or ID prefix of the code repository.
5037
5125
  allow_name_prefix_match: If True, allow matching by name prefix.
5126
+ workspace: The workspace name/ID to filter by.
5038
5127
  hydrate: Flag deciding whether to hydrate the output model(s)
5039
5128
  by including metadata fields in the response.
5040
5129
 
@@ -5047,6 +5136,7 @@ class Client(metaclass=ClientMetaClass):
5047
5136
  name_id_or_prefix=name_id_or_prefix,
5048
5137
  allow_name_prefix_match=allow_name_prefix_match,
5049
5138
  hydrate=hydrate,
5139
+ workspace=workspace,
5050
5140
  )
5051
5141
 
5052
5142
  def list_code_repositories(
@@ -5059,8 +5149,7 @@ class Client(metaclass=ClientMetaClass):
5059
5149
  created: Optional[Union[datetime, str]] = None,
5060
5150
  updated: Optional[Union[datetime, str]] = None,
5061
5151
  name: Optional[str] = None,
5062
- workspace_id: Optional[Union[str, UUID]] = None,
5063
- user_id: Optional[Union[str, UUID]] = None,
5152
+ workspace: Optional[Union[str, UUID]] = None,
5064
5153
  user: Optional[Union[UUID, str]] = None,
5065
5154
  hydrate: bool = False,
5066
5155
  ) -> Page[CodeRepositoryResponse]:
@@ -5075,8 +5164,7 @@ class Client(metaclass=ClientMetaClass):
5075
5164
  created: Use to filter by time of creation.
5076
5165
  updated: Use the last updated date for filtering.
5077
5166
  name: The name of the code repository to filter by.
5078
- workspace_id: The id of the workspace to filter by.
5079
- user_id: The id of the user to filter by.
5167
+ workspace: The workspace name/ID to filter by.
5080
5168
  user: Filter by user name/ID.
5081
5169
  hydrate: Flag deciding whether to hydrate the output model(s)
5082
5170
  by including metadata fields in the response.
@@ -5093,11 +5181,9 @@ class Client(metaclass=ClientMetaClass):
5093
5181
  created=created,
5094
5182
  updated=updated,
5095
5183
  name=name,
5096
- workspace_id=workspace_id,
5097
- user_id=user_id,
5184
+ workspace=workspace or self.active_workspace.id,
5098
5185
  user=user,
5099
5186
  )
5100
- filter_model.set_scope_workspace(self.active_workspace.id)
5101
5187
  return self.zen_store.list_code_repositories(
5102
5188
  filter_model=filter_model,
5103
5189
  hydrate=hydrate,
@@ -5110,6 +5196,7 @@ class Client(metaclass=ClientMetaClass):
5110
5196
  description: Optional[str] = None,
5111
5197
  logo_url: Optional[str] = None,
5112
5198
  config: Optional[Dict[str, Any]] = None,
5199
+ workspace: Optional[Union[str, UUID]] = None,
5113
5200
  ) -> CodeRepositoryResponse:
5114
5201
  """Update a code repository.
5115
5202
 
@@ -5123,12 +5210,15 @@ class Client(metaclass=ClientMetaClass):
5123
5210
  be used to update the existing configuration values. To remove
5124
5211
  values from the existing configuration, set the value for that
5125
5212
  key to `None`.
5213
+ workspace: The workspace name/ID to filter by.
5126
5214
 
5127
5215
  Returns:
5128
5216
  The updated code repository.
5129
5217
  """
5130
5218
  repo = self.get_code_repository(
5131
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
5219
+ name_id_or_prefix=name_id_or_prefix,
5220
+ allow_name_prefix_match=False,
5221
+ workspace=workspace,
5132
5222
  )
5133
5223
  update = CodeRepositoryUpdate(
5134
5224
  name=name, description=description, logo_url=logo_url
@@ -5152,14 +5242,18 @@ class Client(metaclass=ClientMetaClass):
5152
5242
  def delete_code_repository(
5153
5243
  self,
5154
5244
  name_id_or_prefix: Union[str, UUID],
5245
+ workspace: Optional[Union[str, UUID]] = None,
5155
5246
  ) -> None:
5156
5247
  """Delete a code repository.
5157
5248
 
5158
5249
  Args:
5159
5250
  name_id_or_prefix: The name, ID or prefix of the code repository.
5251
+ workspace: The workspace name/ID to filter by.
5160
5252
  """
5161
5253
  repo = self.get_code_repository(
5162
- name_id_or_prefix=name_id_or_prefix, allow_name_prefix_match=False
5254
+ name_id_or_prefix=name_id_or_prefix,
5255
+ allow_name_prefix_match=False,
5256
+ workspace=workspace,
5163
5257
  )
5164
5258
  self.zen_store.delete_code_repository(code_repository_id=repo.id)
5165
5259
 
@@ -5276,7 +5370,6 @@ class Client(metaclass=ClientMetaClass):
5276
5370
  assert connector_instance is not None
5277
5371
  connector_request = connector_instance.to_model(
5278
5372
  name=name,
5279
- user=self.active_user.id,
5280
5373
  workspace=self.active_workspace.id,
5281
5374
  description=description or "",
5282
5375
  labels=labels,
@@ -5324,7 +5417,6 @@ class Client(metaclass=ClientMetaClass):
5324
5417
  expiration_seconds=expiration_seconds,
5325
5418
  expires_at=expires_at,
5326
5419
  expires_skew_tolerance=expires_skew_tolerance,
5327
- user=self.active_user.id,
5328
5420
  workspace=self.active_workspace.id,
5329
5421
  labels=labels or {},
5330
5422
  )
@@ -5407,32 +5499,9 @@ class Client(metaclass=ClientMetaClass):
5407
5499
  Returns:
5408
5500
  The registered service connector.
5409
5501
  """
5410
-
5411
- def scoped_list_method(
5412
- hydrate: bool = False,
5413
- **kwargs: Any,
5414
- ) -> Page[ServiceConnectorResponse]:
5415
- """Call `zen_store.list_service_connectors` with workspace scoping.
5416
-
5417
- Args:
5418
- hydrate: Flag deciding whether to hydrate the output model(s)
5419
- by including metadata fields in the response.
5420
- **kwargs: Keyword arguments to pass to
5421
- `ServiceConnectorFilterModel`.
5422
-
5423
- Returns:
5424
- The list of service connectors.
5425
- """
5426
- filter_model = ServiceConnectorFilter(**kwargs)
5427
- filter_model.set_scope_workspace(self.active_workspace.id)
5428
- return self.zen_store.list_service_connectors(
5429
- filter_model=filter_model,
5430
- hydrate=hydrate,
5431
- )
5432
-
5433
5502
  connector = self._get_entity_by_id_or_name_or_prefix(
5434
5503
  get_method=self.zen_store.get_service_connector,
5435
- list_method=scoped_list_method,
5504
+ list_method=self.list_service_connectors,
5436
5505
  name_id_or_prefix=name_id_or_prefix,
5437
5506
  allow_name_prefix_match=allow_name_prefix_match,
5438
5507
  hydrate=hydrate,
@@ -5471,8 +5540,6 @@ class Client(metaclass=ClientMetaClass):
5471
5540
  auth_method: Optional[str] = None,
5472
5541
  resource_type: Optional[str] = None,
5473
5542
  resource_id: Optional[str] = None,
5474
- workspace_id: Optional[Union[str, UUID]] = None,
5475
- user_id: Optional[Union[str, UUID]] = None,
5476
5543
  user: Optional[Union[UUID, str]] = None,
5477
5544
  labels: Optional[Dict[str, Optional[str]]] = None,
5478
5545
  secret_id: Optional[Union[str, UUID]] = None,
@@ -5494,8 +5561,6 @@ class Client(metaclass=ClientMetaClass):
5494
5561
  they can give access to.
5495
5562
  resource_id: Filter service connectors by the resource id that
5496
5563
  they can give access to.
5497
- workspace_id: The id of the workspace to filter by.
5498
- user_id: The id of the user to filter by.
5499
5564
  user: Filter by user name/ID.
5500
5565
  name: The name of the service connector to filter by.
5501
5566
  labels: The labels of the service connector to filter by.
@@ -5512,8 +5577,6 @@ class Client(metaclass=ClientMetaClass):
5512
5577
  size=size,
5513
5578
  sort_by=sort_by,
5514
5579
  logical_operator=logical_operator,
5515
- workspace_id=workspace_id or self.active_workspace.id,
5516
- user_id=user_id,
5517
5580
  user=user,
5518
5581
  name=name,
5519
5582
  connector_type=connector_type,
@@ -5526,7 +5589,6 @@ class Client(metaclass=ClientMetaClass):
5526
5589
  labels=labels,
5527
5590
  secret_id=secret_id,
5528
5591
  )
5529
- connector_filter_model.set_scope_workspace(self.active_workspace.id)
5530
5592
  return self.zen_store.list_service_connectors(
5531
5593
  filter_model=connector_filter_model,
5532
5594
  hydrate=hydrate,
@@ -5705,7 +5767,6 @@ class Client(metaclass=ClientMetaClass):
5705
5767
  # Convert the update model to a request model for validation
5706
5768
  connector_request_dict = connector_update.model_dump()
5707
5769
  connector_request_dict.update(
5708
- user=self.active_user.id,
5709
5770
  workspace=self.active_workspace.id,
5710
5771
  )
5711
5772
  connector_request = ServiceConnectorRequest.model_validate(
@@ -5979,6 +6040,7 @@ class Client(metaclass=ClientMetaClass):
5979
6040
  connector_type: Optional[str] = None,
5980
6041
  resource_type: Optional[str] = None,
5981
6042
  resource_id: Optional[str] = None,
6043
+ workspace_id: Optional[UUID] = None,
5982
6044
  ) -> List[ServiceConnectorResourcesModel]:
5983
6045
  """List resources that can be accessed by service connectors.
5984
6046
 
@@ -5986,16 +6048,20 @@ class Client(metaclass=ClientMetaClass):
5986
6048
  connector_type: The type of service connector to filter by.
5987
6049
  resource_type: The type of resource to filter by.
5988
6050
  resource_id: The ID of a particular resource instance to filter by.
6051
+ workspace_id: The ID of the workspace to filter by. If not provided,
6052
+ the active workspace will be used.
5989
6053
 
5990
6054
  Returns:
5991
6055
  The matching list of resources that available service
5992
6056
  connectors have access to.
5993
6057
  """
5994
6058
  return self.zen_store.list_service_connector_resources(
5995
- workspace_name_or_id=self.active_workspace.id,
5996
- connector_type=connector_type,
5997
- resource_type=resource_type,
5998
- resource_id=resource_id,
6059
+ ServiceConnectorFilter(
6060
+ workspace_id=workspace_id or self.active_workspace.id,
6061
+ connector_type=connector_type,
6062
+ resource_type=resource_type,
6063
+ resource_id=resource_id,
6064
+ )
5999
6065
  )
6000
6066
 
6001
6067
  def list_service_connector_types(
@@ -6082,19 +6148,26 @@ class Client(metaclass=ClientMetaClass):
6082
6148
  trade_offs=trade_offs,
6083
6149
  ethics=ethics,
6084
6150
  tags=tags,
6085
- user=self.active_user.id,
6086
6151
  workspace=self.active_workspace.id,
6087
6152
  save_models_to_registry=save_models_to_registry,
6088
6153
  )
6089
6154
  )
6090
6155
 
6091
- def delete_model(self, model_name_or_id: Union[str, UUID]) -> None:
6156
+ def delete_model(
6157
+ self,
6158
+ model_name_or_id: Union[str, UUID],
6159
+ workspace: Optional[Union[str, UUID]] = None,
6160
+ ) -> None:
6092
6161
  """Deletes a model from Model Control Plane.
6093
6162
 
6094
6163
  Args:
6095
6164
  model_name_or_id: name or id of the model to be deleted.
6165
+ workspace: The workspace name/ID to filter by.
6096
6166
  """
6097
- self.zen_store.delete_model(model_name_or_id=model_name_or_id)
6167
+ model = self.get_model(
6168
+ model_name_or_id=model_name_or_id, workspace=workspace
6169
+ )
6170
+ self.zen_store.delete_model(model_id=model.id)
6098
6171
 
6099
6172
  def update_model(
6100
6173
  self,
@@ -6110,6 +6183,7 @@ class Client(metaclass=ClientMetaClass):
6110
6183
  add_tags: Optional[List[str]] = None,
6111
6184
  remove_tags: Optional[List[str]] = None,
6112
6185
  save_models_to_registry: Optional[bool] = None,
6186
+ workspace: Optional[Union[str, UUID]] = None,
6113
6187
  ) -> ModelResponse:
6114
6188
  """Updates an existing model in Model Control Plane.
6115
6189
 
@@ -6127,14 +6201,16 @@ class Client(metaclass=ClientMetaClass):
6127
6201
  remove_tags: Tags to remove from to the model.
6128
6202
  save_models_to_registry: Whether to save the model to the
6129
6203
  registry.
6204
+ workspace: The workspace name/ID to filter by.
6130
6205
 
6131
6206
  Returns:
6132
6207
  The updated model.
6133
6208
  """
6134
- if not is_valid_uuid(model_name_or_id):
6135
- model_name_or_id = self.zen_store.get_model(model_name_or_id).id
6209
+ model = self.get_model(
6210
+ model_name_or_id=model_name_or_id, workspace=workspace
6211
+ )
6136
6212
  return self.zen_store.update_model(
6137
- model_id=model_name_or_id, # type:ignore[arg-type]
6213
+ model_id=model.id,
6138
6214
  model_update=ModelUpdate(
6139
6215
  name=name,
6140
6216
  license=license,
@@ -6153,24 +6229,36 @@ class Client(metaclass=ClientMetaClass):
6153
6229
  def get_model(
6154
6230
  self,
6155
6231
  model_name_or_id: Union[str, UUID],
6232
+ workspace: Optional[Union[str, UUID]] = None,
6156
6233
  hydrate: bool = True,
6234
+ bypass_lazy_loader: bool = False,
6157
6235
  ) -> ModelResponse:
6158
6236
  """Get an existing model from Model Control Plane.
6159
6237
 
6160
6238
  Args:
6161
6239
  model_name_or_id: name or id of the model to be retrieved.
6240
+ workspace: The workspace name/ID to filter by.
6162
6241
  hydrate: Flag deciding whether to hydrate the output model(s)
6163
6242
  by including metadata fields in the response.
6243
+ bypass_lazy_loader: Whether to bypass the lazy loader.
6164
6244
 
6165
6245
  Returns:
6166
6246
  The model of interest.
6167
6247
  """
6168
- if cll := client_lazy_loader(
6169
- "get_model", model_name_or_id=model_name_or_id, hydrate=hydrate
6170
- ):
6171
- return cll # type: ignore[return-value]
6172
- return self.zen_store.get_model(
6173
- model_name_or_id=model_name_or_id,
6248
+ if not bypass_lazy_loader:
6249
+ if cll := client_lazy_loader(
6250
+ "get_model",
6251
+ model_name_or_id=model_name_or_id,
6252
+ hydrate=hydrate,
6253
+ workspace=workspace,
6254
+ ):
6255
+ return cll # type: ignore[return-value]
6256
+
6257
+ return self._get_entity_by_id_or_name_or_prefix(
6258
+ get_method=self.zen_store.get_model,
6259
+ list_method=self.list_models,
6260
+ name_id_or_prefix=model_name_or_id,
6261
+ workspace=workspace,
6174
6262
  hydrate=hydrate,
6175
6263
  )
6176
6264
 
@@ -6183,9 +6271,12 @@ class Client(metaclass=ClientMetaClass):
6183
6271
  created: Optional[Union[datetime, str]] = None,
6184
6272
  updated: Optional[Union[datetime, str]] = None,
6185
6273
  name: Optional[str] = None,
6274
+ id: Optional[Union[UUID, str]] = None,
6186
6275
  user: Optional[Union[UUID, str]] = None,
6276
+ workspace: Optional[Union[str, UUID]] = None,
6187
6277
  hydrate: bool = False,
6188
6278
  tag: Optional[str] = None,
6279
+ tags: Optional[List[str]] = None,
6189
6280
  ) -> Page[ModelResponse]:
6190
6281
  """Get models by filter from Model Control Plane.
6191
6282
 
@@ -6197,16 +6288,20 @@ class Client(metaclass=ClientMetaClass):
6197
6288
  created: Use to filter by time of creation
6198
6289
  updated: Use the last updated date for filtering
6199
6290
  name: The name of the model to filter by.
6291
+ id: The id of the model to filter by.
6200
6292
  user: Filter by user name/ID.
6293
+ workspace: The workspace name/ID to filter by.
6201
6294
  hydrate: Flag deciding whether to hydrate the output model(s)
6202
6295
  by including metadata fields in the response.
6203
6296
  tag: The tag of the model to filter by.
6297
+ tags: Tags to filter by.
6204
6298
 
6205
6299
  Returns:
6206
6300
  A page object with all models.
6207
6301
  """
6208
6302
  filter = ModelFilter(
6209
6303
  name=name,
6304
+ id=id,
6210
6305
  sort_by=sort_by,
6211
6306
  page=page,
6212
6307
  size=size,
@@ -6214,7 +6309,9 @@ class Client(metaclass=ClientMetaClass):
6214
6309
  created=created,
6215
6310
  updated=updated,
6216
6311
  tag=tag,
6312
+ tags=tags,
6217
6313
  user=user,
6314
+ workspace=workspace or self.active_workspace.id,
6218
6315
  )
6219
6316
 
6220
6317
  return self.zen_store.list_models(
@@ -6231,6 +6328,7 @@ class Client(metaclass=ClientMetaClass):
6231
6328
  name: Optional[str] = None,
6232
6329
  description: Optional[str] = None,
6233
6330
  tags: Optional[List[str]] = None,
6331
+ workspace: Optional[Union[str, UUID]] = None,
6234
6332
  ) -> ModelVersionResponse:
6235
6333
  """Creates a new model version in Model Control Plane.
6236
6334
 
@@ -6240,19 +6338,20 @@ class Client(metaclass=ClientMetaClass):
6240
6338
  name: the name of the Model Version to be created.
6241
6339
  description: the description of the Model Version to be created.
6242
6340
  tags: Tags associated with the model.
6341
+ workspace: The workspace name/ID to filter by.
6243
6342
 
6244
6343
  Returns:
6245
6344
  The newly created model version.
6246
6345
  """
6247
- if not is_valid_uuid(model_name_or_id):
6248
- model_name_or_id = self.get_model(model_name_or_id).id
6346
+ model = self.get_model(
6347
+ model_name_or_id=model_name_or_id, workspace=workspace
6348
+ )
6249
6349
  return self.zen_store.create_model_version(
6250
6350
  model_version=ModelVersionRequest(
6251
6351
  name=name,
6252
6352
  description=description,
6253
- user=self.active_user.id,
6254
- workspace=self.active_workspace.id,
6255
- model=model_name_or_id,
6353
+ workspace=workspace or self.active_workspace.id,
6354
+ model=model.id,
6256
6355
  tags=tags,
6257
6356
  )
6258
6357
  )
@@ -6276,6 +6375,7 @@ class Client(metaclass=ClientMetaClass):
6276
6375
  model_version_name_or_number_or_id: Optional[
6277
6376
  Union[str, int, ModelStages, UUID]
6278
6377
  ] = None,
6378
+ workspace: Optional[Union[str, UUID]] = None,
6279
6379
  hydrate: bool = True,
6280
6380
  ) -> ModelVersionResponse:
6281
6381
  """Get an existing model version from Model Control Plane.
@@ -6286,6 +6386,7 @@ class Client(metaclass=ClientMetaClass):
6286
6386
  model_version_name_or_number_or_id: name, id, stage or number of
6287
6387
  the model version to be retrieved. If skipped - latest version
6288
6388
  is retrieved.
6389
+ workspace: The workspace name/ID to filter by.
6289
6390
  hydrate: Flag deciding whether to hydrate the output model(s)
6290
6391
  by including metadata fields in the response.
6291
6392
 
@@ -6310,6 +6411,7 @@ class Client(metaclass=ClientMetaClass):
6310
6411
  "get_model_version",
6311
6412
  model_name_or_id=model_name_or_id,
6312
6413
  model_version_name_or_number_or_id=model_version_name_or_number_or_id,
6414
+ workspace=workspace,
6313
6415
  hydrate=hydrate,
6314
6416
  ):
6315
6417
  return cll # type: ignore[return-value]
@@ -6324,18 +6426,20 @@ class Client(metaclass=ClientMetaClass):
6324
6426
  )
6325
6427
  elif isinstance(model_version_name_or_number_or_id, int):
6326
6428
  model_versions = self.zen_store.list_model_versions(
6327
- model_name_or_id=model_name_or_id,
6328
6429
  model_version_filter_model=ModelVersionFilter(
6430
+ model=model_name_or_id,
6329
6431
  number=model_version_name_or_number_or_id,
6432
+ workspace=workspace or self.active_workspace.id,
6330
6433
  ),
6331
6434
  hydrate=hydrate,
6332
6435
  ).items
6333
6436
  elif isinstance(model_version_name_or_number_or_id, str):
6334
6437
  if model_version_name_or_number_or_id == ModelStages.LATEST:
6335
6438
  model_versions = self.zen_store.list_model_versions(
6336
- model_name_or_id=model_name_or_id,
6337
6439
  model_version_filter_model=ModelVersionFilter(
6338
- sort_by=f"{SorterOps.DESCENDING}:number"
6440
+ model=model_name_or_id,
6441
+ sort_by=f"{SorterOps.DESCENDING}:number",
6442
+ workspace=workspace or self.active_workspace.id,
6339
6443
  ),
6340
6444
  hydrate=hydrate,
6341
6445
  ).items
@@ -6346,17 +6450,19 @@ class Client(metaclass=ClientMetaClass):
6346
6450
  model_versions = []
6347
6451
  elif model_version_name_or_number_or_id in ModelStages.values():
6348
6452
  model_versions = self.zen_store.list_model_versions(
6349
- model_name_or_id=model_name_or_id,
6350
6453
  model_version_filter_model=ModelVersionFilter(
6351
- stage=model_version_name_or_number_or_id
6454
+ model=model_name_or_id,
6455
+ stage=model_version_name_or_number_or_id,
6456
+ workspace=workspace or self.active_workspace.id,
6352
6457
  ),
6353
6458
  hydrate=hydrate,
6354
6459
  ).items
6355
6460
  else:
6356
6461
  model_versions = self.zen_store.list_model_versions(
6357
- model_name_or_id=model_name_or_id,
6358
6462
  model_version_filter_model=ModelVersionFilter(
6359
- name=model_version_name_or_number_or_id
6463
+ model=model_name_or_id,
6464
+ name=model_version_name_or_number_or_id,
6465
+ workspace=workspace or self.active_workspace.id,
6360
6466
  ),
6361
6467
  hydrate=hydrate,
6362
6468
  ).items
@@ -6384,7 +6490,7 @@ class Client(metaclass=ClientMetaClass):
6384
6490
 
6385
6491
  def list_model_versions(
6386
6492
  self,
6387
- model_name_or_id: Optional[Union[str, UUID]] = None,
6493
+ model_name_or_id: Union[str, UUID],
6388
6494
  sort_by: str = "number",
6389
6495
  page: int = PAGINATION_STARTING_PAGE,
6390
6496
  size: int = PAGE_SIZE_DEFAULT,
@@ -6392,11 +6498,15 @@ class Client(metaclass=ClientMetaClass):
6392
6498
  created: Optional[Union[datetime, str]] = None,
6393
6499
  updated: Optional[Union[datetime, str]] = None,
6394
6500
  name: Optional[str] = None,
6501
+ id: Optional[Union[UUID, str]] = None,
6395
6502
  number: Optional[int] = None,
6396
6503
  stage: Optional[Union[str, ModelStages]] = None,
6504
+ run_metadata: Optional[Dict[str, str]] = None,
6397
6505
  user: Optional[Union[UUID, str]] = None,
6398
6506
  hydrate: bool = False,
6399
6507
  tag: Optional[str] = None,
6508
+ tags: Optional[List[str]] = None,
6509
+ workspace: Optional[Union[str, UUID]] = None,
6400
6510
  ) -> Page[ModelVersionResponse]:
6401
6511
  """Get model versions by filter from Model Control Plane.
6402
6512
 
@@ -6410,12 +6520,16 @@ class Client(metaclass=ClientMetaClass):
6410
6520
  created: Use to filter by time of creation
6411
6521
  updated: Use the last updated date for filtering
6412
6522
  name: name or id of the model version.
6523
+ id: id of the model version.
6413
6524
  number: number of the model version.
6414
6525
  stage: stage of the model version.
6526
+ run_metadata: run metadata of the model version.
6415
6527
  user: Filter by user name/ID.
6416
6528
  hydrate: Flag deciding whether to hydrate the output model(s)
6417
6529
  by including metadata fields in the response.
6418
6530
  tag: The tag to filter by.
6531
+ tags: Tags to filter by.
6532
+ workspace: The workspace name/ID to filter by.
6419
6533
 
6420
6534
  Returns:
6421
6535
  A page object with all model versions.
@@ -6428,14 +6542,18 @@ class Client(metaclass=ClientMetaClass):
6428
6542
  created=created,
6429
6543
  updated=updated,
6430
6544
  name=name,
6545
+ id=id,
6431
6546
  number=number,
6432
6547
  stage=stage,
6548
+ run_metadata=run_metadata,
6433
6549
  tag=tag,
6550
+ tags=tags,
6434
6551
  user=user,
6552
+ model=model_name_or_id,
6553
+ workspace=workspace or self.active_workspace.id,
6435
6554
  )
6436
6555
 
6437
6556
  return self.zen_store.list_model_versions(
6438
- model_name_or_id=model_name_or_id,
6439
6557
  model_version_filter_model=model_version_filter_model,
6440
6558
  hydrate=hydrate,
6441
6559
  )
@@ -6450,6 +6568,7 @@ class Client(metaclass=ClientMetaClass):
6450
6568
  description: Optional[str] = None,
6451
6569
  add_tags: Optional[List[str]] = None,
6452
6570
  remove_tags: Optional[List[str]] = None,
6571
+ workspace: Optional[Union[str, UUID]] = None,
6453
6572
  ) -> ModelVersionResponse:
6454
6573
  """Get all model versions by filter.
6455
6574
 
@@ -6463,21 +6582,23 @@ class Client(metaclass=ClientMetaClass):
6463
6582
  description: Target model version description to be set.
6464
6583
  add_tags: Tags to add to the model version.
6465
6584
  remove_tags: Tags to remove from to the model version.
6585
+ workspace: The workspace name/ID to filter by.
6466
6586
 
6467
6587
  Returns:
6468
6588
  An updated model version.
6469
6589
  """
6470
6590
  if not is_valid_uuid(model_name_or_id):
6471
- model_name_or_id = self.get_model(model_name_or_id).id
6591
+ model = self.get_model(model_name_or_id, workspace=workspace)
6592
+ model_name_or_id = model.id
6593
+ workspace = workspace or model.workspace.id
6472
6594
  if not is_valid_uuid(version_name_or_id):
6473
6595
  version_name_or_id = self.get_model_version(
6474
- model_name_or_id, version_name_or_id
6596
+ model_name_or_id, version_name_or_id, workspace=workspace
6475
6597
  ).id
6476
6598
 
6477
6599
  return self.zen_store.update_model_version(
6478
6600
  model_version_id=version_name_or_id, # type:ignore[arg-type]
6479
6601
  model_version_update_model=ModelVersionUpdate(
6480
- model=model_name_or_id,
6481
6602
  stage=stage,
6482
6603
  force=force,
6483
6604
  name=name,
@@ -6826,6 +6947,7 @@ class Client(metaclass=ClientMetaClass):
6826
6947
  logical_operator: LogicalOperators = LogicalOperators.AND,
6827
6948
  trigger_id: Optional[UUID] = None,
6828
6949
  user: Optional[Union[UUID, str]] = None,
6950
+ workspace: Optional[Union[UUID, str]] = None,
6829
6951
  hydrate: bool = False,
6830
6952
  ) -> Page[TriggerExecutionResponse]:
6831
6953
  """List all trigger executions matching the given filter criteria.
@@ -6837,6 +6959,7 @@ class Client(metaclass=ClientMetaClass):
6837
6959
  logical_operator: Which logical operator to use [and, or].
6838
6960
  trigger_id: ID of the trigger to filter by.
6839
6961
  user: Filter by user name/ID.
6962
+ workspace: Filter by workspace name/ID.
6840
6963
  hydrate: Flag deciding whether to hydrate the output model(s)
6841
6964
  by including metadata fields in the response.
6842
6965
 
@@ -6850,8 +6973,8 @@ class Client(metaclass=ClientMetaClass):
6850
6973
  size=size,
6851
6974
  user=user,
6852
6975
  logical_operator=logical_operator,
6976
+ workspace=workspace or self.active_workspace.id,
6853
6977
  )
6854
- filter_model.set_scope_workspace(self.active_workspace.id)
6855
6978
  return self.zen_store.list_trigger_executions(
6856
6979
  trigger_execution_filter_model=filter_model, hydrate=hydrate
6857
6980
  )
@@ -6874,6 +6997,7 @@ class Client(metaclass=ClientMetaClass):
6874
6997
  list_method: Callable[..., Page[AnyResponse]],
6875
6998
  name_id_or_prefix: Union[str, UUID],
6876
6999
  allow_name_prefix_match: bool = True,
7000
+ workspace: Optional[Union[str, UUID]] = None,
6877
7001
  hydrate: bool = True,
6878
7002
  ) -> AnyResponse:
6879
7003
  """Fetches an entity using the id, name, or partial id/name.
@@ -6886,6 +7010,7 @@ class Client(metaclass=ClientMetaClass):
6886
7010
  allow_name_prefix_match: If True, allow matching by name prefix.
6887
7011
  hydrate: Flag deciding whether to hydrate the output model(s)
6888
7012
  by including metadata fields in the response.
7013
+ workspace: The workspace name/ID to filter by.
6889
7014
 
6890
7015
  Returns:
6891
7016
  The entity with the given name, id or partial id.
@@ -6904,10 +7029,15 @@ class Client(metaclass=ClientMetaClass):
6904
7029
 
6905
7030
  # If not a UUID, try to find by name
6906
7031
  assert not isinstance(name_id_or_prefix, UUID)
6907
- entity = list_method(
7032
+ list_kwargs: Dict[str, Any] = dict(
6908
7033
  name=f"equals:{name_id_or_prefix}",
6909
7034
  hydrate=hydrate,
6910
7035
  )
7036
+ scope = ""
7037
+ if workspace:
7038
+ scope = f"in workspace {workspace} "
7039
+ list_kwargs["workspace"] = workspace
7040
+ entity = list_method(**list_kwargs)
6911
7041
 
6912
7042
  # If only a single entity is found, return it
6913
7043
  if entity.total == 1:
@@ -6920,6 +7050,7 @@ class Client(metaclass=ClientMetaClass):
6920
7050
  list_method=list_method,
6921
7051
  partial_id_or_name=name_id_or_prefix,
6922
7052
  allow_name_prefix_match=allow_name_prefix_match,
7053
+ workspace=workspace,
6923
7054
  hydrate=hydrate,
6924
7055
  )
6925
7056
 
@@ -6931,7 +7062,7 @@ class Client(metaclass=ClientMetaClass):
6931
7062
  for item in entity.items
6932
7063
  ]
6933
7064
  raise ZenKeyError(
6934
- f"{entity.total} {entity_label} have been found that have "
7065
+ f"{entity.total} {entity_label} have been found {scope}that have "
6935
7066
  f"a name that matches the provided "
6936
7067
  f"string '{name_id_or_prefix}':\n"
6937
7068
  f"{formatted_entity_items}.\n"
@@ -6945,6 +7076,7 @@ class Client(metaclass=ClientMetaClass):
6945
7076
  list_method: Callable[..., Page[AnyResponse]],
6946
7077
  name_id_or_prefix: Union[str, UUID],
6947
7078
  version: Optional[str],
7079
+ workspace: Optional[Union[str, UUID]] = None,
6948
7080
  hydrate: bool = True,
6949
7081
  ) -> "AnyResponse":
6950
7082
  from zenml.utils.uuid_utils import is_valid_uuid
@@ -6964,13 +7096,18 @@ class Client(metaclass=ClientMetaClass):
6964
7096
  return get_method(name_id_or_prefix, hydrate=hydrate)
6965
7097
 
6966
7098
  assert not isinstance(name_id_or_prefix, UUID)
6967
- exact_name_matches = list_method(
7099
+ list_kwargs: Dict[str, Any] = dict(
6968
7100
  size=1,
6969
7101
  sort_by="desc:created",
6970
7102
  name=name_id_or_prefix,
6971
7103
  version=version,
6972
7104
  hydrate=hydrate,
6973
7105
  )
7106
+ scope = ""
7107
+ if workspace:
7108
+ scope = f" in workspace {workspace}"
7109
+ list_kwargs["workspace"] = workspace
7110
+ exact_name_matches = list_method(**list_kwargs)
6974
7111
 
6975
7112
  if len(exact_name_matches) == 1:
6976
7113
  # If the name matches exactly, use the explicitly specified version
@@ -6992,13 +7129,13 @@ class Client(metaclass=ClientMetaClass):
6992
7129
  elif partial_id_matches.total == 0:
6993
7130
  raise KeyError(
6994
7131
  f"No {entity_label} found for name, ID or prefix "
6995
- f"{name_id_or_prefix}."
7132
+ f"{name_id_or_prefix}{scope}."
6996
7133
  )
6997
7134
  else:
6998
7135
  raise ZenKeyError(
6999
- f"{partial_id_matches.total} {entity_label} have been found "
7000
- "that have an id prefix that matches the provided string "
7001
- f"'{name_id_or_prefix}':\n"
7136
+ f"{partial_id_matches.total} {entity_label} have been found"
7137
+ f"{scope} that have an id prefix that matches the provided "
7138
+ f"string '{name_id_or_prefix}':\n"
7002
7139
  f"{partial_id_matches.items}.\n"
7003
7140
  f"Please provide more characters to uniquely identify "
7004
7141
  f"only one of the {entity_label}s."
@@ -7010,6 +7147,7 @@ class Client(metaclass=ClientMetaClass):
7010
7147
  list_method: Callable[..., Page[AnyResponse]],
7011
7148
  partial_id_or_name: str,
7012
7149
  allow_name_prefix_match: bool,
7150
+ workspace: Optional[Union[str, UUID]] = None,
7013
7151
  hydrate: bool = True,
7014
7152
  ) -> AnyResponse:
7015
7153
  """Fetches an entity using a partial ID or name.
@@ -7021,6 +7159,7 @@ class Client(metaclass=ClientMetaClass):
7021
7159
  allow_name_prefix_match: If True, allow matching by name prefix.
7022
7160
  hydrate: Flag deciding whether to hydrate the output model(s)
7023
7161
  by including metadata fields in the response.
7162
+ workspace: The workspace name/ID to filter by.
7024
7163
 
7025
7164
  Returns:
7026
7165
  The entity with the given partial ID or name.
@@ -7037,6 +7176,10 @@ class Client(metaclass=ClientMetaClass):
7037
7176
  }
7038
7177
  if allow_name_prefix_match:
7039
7178
  list_method_args["name"] = f"startswith:{partial_id_or_name}"
7179
+ scope = ""
7180
+ if workspace:
7181
+ scope = f"in workspace {workspace} "
7182
+ list_method_args["workspace"] = workspace
7040
7183
 
7041
7184
  entity = list_method(**list_method_args)
7042
7185
 
@@ -7056,7 +7199,7 @@ class Client(metaclass=ClientMetaClass):
7056
7199
  # If no entity is found, raise an error.
7057
7200
  if entity.total == 0:
7058
7201
  raise KeyError(
7059
- f"No {entity_label} have been found that have "
7202
+ f"No {entity_label} have been found{scope} that have "
7060
7203
  f"{prefix_description} that matches the provided string "
7061
7204
  f"'{partial_id_or_name}'."
7062
7205
  )
@@ -7070,7 +7213,7 @@ class Client(metaclass=ClientMetaClass):
7070
7213
  else:
7071
7214
  ambiguous_entities.append(str(model.id))
7072
7215
  raise ZenKeyError(
7073
- f"{entity.total} {entity_label} have been found that have "
7216
+ f"{entity.total} {entity_label} have been found{scope} that have "
7074
7217
  f"{prefix_description} that matches the provided "
7075
7218
  f"string '{partial_id_or_name}':\n"
7076
7219
  f"{ambiguous_entities}.\n"
@@ -7505,57 +7648,97 @@ class Client(metaclass=ClientMetaClass):
7505
7648
  api_key_name_or_id=api_key.id,
7506
7649
  )
7507
7650
 
7508
- #############################################
7509
- # Tags
7510
- #
7511
- # Note: tag<>resource are not exposed and
7512
- # can be accessed via relevant resources
7513
- #############################################
7514
-
7515
- def create_tag(self, tag: TagRequest) -> TagResponse:
7651
+ # ---------------------------------- Tags ----------------------------------
7652
+ def create_tag(
7653
+ self,
7654
+ name: str,
7655
+ exclusive: bool = False,
7656
+ color: Optional[Union[str, ColorVariants]] = None,
7657
+ ) -> TagResponse:
7516
7658
  """Creates a new tag.
7517
7659
 
7518
7660
  Args:
7519
- tag: the Tag to be created.
7661
+ name: the name of the tag.
7662
+ exclusive: the boolean to decide whether the tag is an exclusive tag.
7663
+ An exclusive tag means that the tag can exist only for a single:
7664
+ - pipeline run within the scope of a pipeline
7665
+ - artifact version within the scope of an artifact
7666
+ - run template
7667
+ color: the color of the tag
7520
7668
 
7521
7669
  Returns:
7522
7670
  The newly created tag.
7523
7671
  """
7524
- return self.zen_store.create_tag(tag=tag)
7672
+ request_model = TagRequest(name=name, exclusive=exclusive)
7673
+
7674
+ if color is not None:
7675
+ request_model.color = ColorVariants(color)
7676
+
7677
+ return self.zen_store.create_tag(tag=request_model)
7525
7678
 
7526
- def delete_tag(self, tag_name_or_id: Union[str, UUID]) -> None:
7679
+ def delete_tag(
7680
+ self,
7681
+ tag_name_or_id: Union[str, UUID],
7682
+ ) -> None:
7527
7683
  """Deletes a tag.
7528
7684
 
7529
7685
  Args:
7530
7686
  tag_name_or_id: name or id of the tag to be deleted.
7531
7687
  """
7532
- self.zen_store.delete_tag(tag_name_or_id=tag_name_or_id)
7688
+ self.zen_store.delete_tag(
7689
+ tag_name_or_id=tag_name_or_id,
7690
+ )
7533
7691
 
7534
7692
  def update_tag(
7535
7693
  self,
7536
7694
  tag_name_or_id: Union[str, UUID],
7537
- tag_update_model: TagUpdate,
7695
+ name: Optional[str] = None,
7696
+ exclusive: Optional[bool] = None,
7697
+ color: Optional[Union[str, ColorVariants]] = None,
7538
7698
  ) -> TagResponse:
7539
7699
  """Updates an existing tag.
7540
7700
 
7541
7701
  Args:
7542
7702
  tag_name_or_id: name or UUID of the tag to be updated.
7543
- tag_update_model: the tag to be updated.
7703
+ name: the name of the tag.
7704
+ exclusive: the boolean to decide whether the tag is an exclusive tag.
7705
+ An exclusive tag means that the tag can exist only for a single:
7706
+ - pipeline run within the scope of a pipeline
7707
+ - artifact version within the scope of an artifact
7708
+ - run template
7709
+ color: the color of the tag
7544
7710
 
7545
7711
  Returns:
7546
7712
  The updated tag.
7547
7713
  """
7714
+ update_model = TagUpdate()
7715
+
7716
+ if name is not None:
7717
+ update_model.name = name
7718
+
7719
+ if exclusive is not None:
7720
+ update_model.exclusive = exclusive
7721
+
7722
+ if color is not None:
7723
+ if isinstance(color, str):
7724
+ update_model.color = ColorVariants(color)
7725
+ else:
7726
+ update_model.color = color
7727
+
7548
7728
  return self.zen_store.update_tag(
7549
- tag_name_or_id=tag_name_or_id, tag_update_model=tag_update_model
7729
+ tag_name_or_id=tag_name_or_id,
7730
+ tag_update_model=update_model,
7550
7731
  )
7551
7732
 
7552
7733
  def get_tag(
7553
- self, tag_name_or_id: Union[str, UUID], hydrate: bool = True
7734
+ self,
7735
+ tag_name_or_id: Union[str, UUID],
7736
+ hydrate: bool = True,
7554
7737
  ) -> TagResponse:
7555
7738
  """Get an existing tag.
7556
7739
 
7557
7740
  Args:
7558
- tag_name_or_id: name or id of the model to be retrieved.
7741
+ tag_name_or_id: name or id of the tag to be retrieved.
7559
7742
  hydrate: Flag deciding whether to hydrate the output model(s)
7560
7743
  by including metadata fields in the response.
7561
7744
 
@@ -7563,19 +7746,39 @@ class Client(metaclass=ClientMetaClass):
7563
7746
  The tag of interest.
7564
7747
  """
7565
7748
  return self.zen_store.get_tag(
7566
- tag_name_or_id=tag_name_or_id, hydrate=hydrate
7749
+ tag_name_or_id=tag_name_or_id,
7750
+ hydrate=hydrate,
7567
7751
  )
7568
7752
 
7569
7753
  def list_tags(
7570
7754
  self,
7571
- tag_filter_model: TagFilter,
7755
+ sort_by: str = "created",
7756
+ page: int = PAGINATION_STARTING_PAGE,
7757
+ size: int = PAGE_SIZE_DEFAULT,
7758
+ logical_operator: LogicalOperators = LogicalOperators.AND,
7759
+ id: Optional[Union[UUID, str]] = None,
7760
+ user: Optional[Union[UUID, str]] = None,
7761
+ created: Optional[Union[datetime, str]] = None,
7762
+ updated: Optional[Union[datetime, str]] = None,
7763
+ name: Optional[str] = None,
7764
+ color: Optional[Union[str, ColorVariants]] = None,
7765
+ exclusive: Optional[bool] = None,
7572
7766
  hydrate: bool = False,
7573
7767
  ) -> Page[TagResponse]:
7574
7768
  """Get tags by filter.
7575
7769
 
7576
7770
  Args:
7577
- tag_filter_model: All filter parameters including pagination
7578
- params.
7771
+ sort_by: The column to sort by.
7772
+ page: The page of items.
7773
+ size: The maximum size of all pages.
7774
+ logical_operator: Which logical operator to use [and, or].
7775
+ id: Use the id of stacks to filter by.
7776
+ user: Use the user to filter by.
7777
+ created: Use to filter by time of creation.
7778
+ updated: Use the last updated date for filtering.
7779
+ name: The name of the tag.
7780
+ color: The color of the tag.
7781
+ exclusive: Flag indicating whether the tag is exclusive.
7579
7782
  hydrate: Flag deciding whether to hydrate the output model(s)
7580
7783
  by including metadata fields in the response.
7581
7784
 
@@ -7583,5 +7786,72 @@ class Client(metaclass=ClientMetaClass):
7583
7786
  A page of all tags.
7584
7787
  """
7585
7788
  return self.zen_store.list_tags(
7586
- tag_filter_model=tag_filter_model, hydrate=hydrate
7789
+ tag_filter_model=TagFilter(
7790
+ sort_by=sort_by,
7791
+ page=page,
7792
+ size=size,
7793
+ logical_operator=logical_operator,
7794
+ id=id,
7795
+ user=user,
7796
+ created=created,
7797
+ updated=updated,
7798
+ name=name,
7799
+ color=color,
7800
+ exclusive=exclusive,
7801
+ ),
7802
+ hydrate=hydrate,
7803
+ )
7804
+
7805
+ def attach_tag(
7806
+ self,
7807
+ tag_name_or_id: Union[str, UUID],
7808
+ resources: List[TagResource],
7809
+ ) -> None:
7810
+ """Attach a tag to resources.
7811
+
7812
+ Args:
7813
+ tag_name_or_id: name or id of the tag to be attached.
7814
+ resources: the resources to attach the tag to.
7815
+ """
7816
+ if isinstance(tag_name_or_id, str):
7817
+ try:
7818
+ tag_model = self.create_tag(name=tag_name_or_id)
7819
+ except EntityExistsError:
7820
+ tag_model = self.get_tag(tag_name_or_id)
7821
+ else:
7822
+ tag_model = self.get_tag(tag_name_or_id)
7823
+
7824
+ self.zen_store.batch_create_tag_resource(
7825
+ tag_resources=[
7826
+ TagResourceRequest(
7827
+ tag_id=tag_model.id,
7828
+ resource_id=resource.id,
7829
+ resource_type=resource.type,
7830
+ )
7831
+ for resource in resources
7832
+ ]
7833
+ )
7834
+
7835
+ def detach_tag(
7836
+ self,
7837
+ tag_name_or_id: Union[str, UUID],
7838
+ resources: List[TagResource],
7839
+ ) -> None:
7840
+ """Detach a tag from resources.
7841
+
7842
+ Args:
7843
+ tag_name_or_id: name or id of the tag to be detached.
7844
+ resources: the resources to detach the tag from.
7845
+ """
7846
+ tag_model = self.get_tag(tag_name_or_id)
7847
+
7848
+ self.zen_store.batch_delete_tag_resource(
7849
+ tag_resources=[
7850
+ TagResourceRequest(
7851
+ tag_id=tag_model.id,
7852
+ resource_id=resource.id,
7853
+ resource_type=resource.type,
7854
+ )
7855
+ for resource in resources
7856
+ ]
7587
7857
  )