zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250313__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. zenml/VERSION +1 -1
  2. zenml/__init__.py +2 -0
  3. zenml/analytics/context.py +7 -0
  4. zenml/artifacts/utils.py +0 -2
  5. zenml/cli/login.py +6 -0
  6. zenml/cli/model.py +7 -15
  7. zenml/cli/secret.py +47 -44
  8. zenml/cli/service_connectors.py +0 -1
  9. zenml/cli/stack.py +0 -1
  10. zenml/cli/tag.py +3 -5
  11. zenml/cli/utils.py +25 -23
  12. zenml/cli/workspace.py +79 -5
  13. zenml/client.py +615 -348
  14. zenml/config/global_config.py +16 -3
  15. zenml/config/pipeline_configurations.py +3 -2
  16. zenml/config/pipeline_run_configuration.py +2 -1
  17. zenml/config/secret_reference_mixin.py +1 -1
  18. zenml/constants.py +1 -3
  19. zenml/enums.py +0 -7
  20. zenml/event_hub/event_hub.py +3 -1
  21. zenml/exceptions.py +0 -24
  22. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
  23. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
  24. zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
  25. zenml/integrations/mlflow/steps/mlflow_registry.py +1 -1
  26. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
  27. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +3 -3
  28. zenml/model/model.py +8 -8
  29. zenml/models/__init__.py +18 -1
  30. zenml/models/v2/base/base.py +0 -5
  31. zenml/models/v2/base/filter.py +1 -1
  32. zenml/models/v2/base/scoped.py +104 -121
  33. zenml/models/v2/core/api_key.py +1 -1
  34. zenml/models/v2/core/artifact.py +31 -18
  35. zenml/models/v2/core/artifact_version.py +42 -25
  36. zenml/models/v2/core/component.py +22 -33
  37. zenml/models/v2/core/device.py +3 -2
  38. zenml/models/v2/core/event_source.py +2 -2
  39. zenml/models/v2/core/flavor.py +19 -47
  40. zenml/models/v2/core/logs.py +1 -2
  41. zenml/models/v2/core/model.py +7 -4
  42. zenml/models/v2/core/model_version.py +36 -27
  43. zenml/models/v2/core/pipeline.py +1 -1
  44. zenml/models/v2/core/pipeline_run.py +5 -13
  45. zenml/models/v2/core/run_template.py +1 -2
  46. zenml/models/v2/core/schedule.py +0 -9
  47. zenml/models/v2/core/secret.py +93 -127
  48. zenml/models/v2/core/server_settings.py +2 -2
  49. zenml/models/v2/core/service.py +43 -12
  50. zenml/models/v2/core/service_connector.py +14 -16
  51. zenml/models/v2/core/stack.py +24 -26
  52. zenml/models/v2/core/step_run.py +3 -15
  53. zenml/models/v2/core/tag.py +41 -15
  54. zenml/models/v2/core/user.py +19 -2
  55. zenml/models/v2/misc/statistics.py +45 -0
  56. zenml/models/v2/misc/tag.py +27 -0
  57. zenml/orchestrators/cache_utils.py +1 -1
  58. zenml/orchestrators/input_utils.py +1 -0
  59. zenml/orchestrators/step_launcher.py +0 -1
  60. zenml/orchestrators/step_run_utils.py +0 -2
  61. zenml/orchestrators/step_runner.py +10 -1
  62. zenml/pipelines/build_utils.py +0 -2
  63. zenml/pipelines/pipeline_decorator.py +3 -2
  64. zenml/pipelines/pipeline_definition.py +4 -5
  65. zenml/pipelines/run_utils.py +3 -3
  66. zenml/service_connectors/service_connector.py +0 -7
  67. zenml/service_connectors/service_connector_utils.py +0 -1
  68. zenml/stack/authentication_mixin.py +1 -1
  69. zenml/stack/flavor.py +3 -14
  70. zenml/stack/stack_component.py +1 -5
  71. zenml/steps/step_context.py +19 -0
  72. zenml/utils/string_utils.py +1 -1
  73. zenml/utils/tag_utils.py +642 -0
  74. zenml/zen_server/cloud_utils.py +21 -0
  75. zenml/zen_server/exceptions.py +0 -6
  76. zenml/zen_server/rbac/endpoint_utils.py +134 -46
  77. zenml/zen_server/rbac/models.py +65 -3
  78. zenml/zen_server/rbac/rbac_interface.py +9 -0
  79. zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
  80. zenml/zen_server/rbac/utils.py +156 -29
  81. zenml/zen_server/rbac/zenml_cloud_rbac.py +43 -11
  82. zenml/zen_server/routers/actions_endpoints.py +3 -5
  83. zenml/zen_server/routers/artifact_endpoint.py +0 -5
  84. zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
  85. zenml/zen_server/routers/auth_endpoints.py +22 -7
  86. zenml/zen_server/routers/code_repositories_endpoints.py +56 -3
  87. zenml/zen_server/routers/devices_endpoints.py +0 -4
  88. zenml/zen_server/routers/event_source_endpoints.py +0 -5
  89. zenml/zen_server/routers/flavors_endpoints.py +0 -5
  90. zenml/zen_server/routers/logs_endpoints.py +0 -1
  91. zenml/zen_server/routers/model_versions_endpoints.py +102 -23
  92. zenml/zen_server/routers/models_endpoints.py +51 -68
  93. zenml/zen_server/routers/pipeline_builds_endpoints.py +58 -4
  94. zenml/zen_server/routers/pipeline_deployments_endpoints.py +58 -4
  95. zenml/zen_server/routers/pipelines_endpoints.py +73 -4
  96. zenml/zen_server/routers/plugin_endpoints.py +0 -1
  97. zenml/zen_server/routers/run_metadata_endpoints.py +99 -0
  98. zenml/zen_server/routers/run_templates_endpoints.py +66 -3
  99. zenml/zen_server/routers/runs_endpoints.py +60 -8
  100. zenml/zen_server/routers/schedule_endpoints.py +69 -6
  101. zenml/zen_server/routers/secrets_endpoints.py +40 -4
  102. zenml/zen_server/routers/server_endpoints.py +53 -1
  103. zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
  104. zenml/zen_server/routers/service_connectors_endpoints.py +96 -14
  105. zenml/zen_server/routers/service_endpoints.py +20 -7
  106. zenml/zen_server/routers/stack_components_endpoints.py +68 -7
  107. zenml/zen_server/routers/stacks_endpoints.py +98 -7
  108. zenml/zen_server/routers/steps_endpoints.py +17 -11
  109. zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
  110. zenml/zen_server/routers/tags_endpoints.py +6 -17
  111. zenml/zen_server/routers/triggers_endpoints.py +5 -8
  112. zenml/zen_server/routers/users_endpoints.py +47 -12
  113. zenml/zen_server/routers/workspaces_endpoints.py +56 -1285
  114. zenml/zen_server/template_execution/utils.py +5 -4
  115. zenml/zen_server/utils.py +21 -0
  116. zenml/zen_server/zen_server_api.py +4 -0
  117. zenml/zen_stores/base_zen_store.py +29 -44
  118. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
  119. zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
  120. zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
  121. zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
  122. zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
  123. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
  124. zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
  125. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
  126. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
  127. zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
  128. zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
  129. zenml/zen_stores/rest_zen_store.py +172 -171
  130. zenml/zen_stores/schemas/action_schemas.py +8 -1
  131. zenml/zen_stores/schemas/api_key_schemas.py +8 -1
  132. zenml/zen_stores/schemas/artifact_schemas.py +28 -1
  133. zenml/zen_stores/schemas/code_repository_schemas.py +8 -1
  134. zenml/zen_stores/schemas/component_schemas.py +9 -14
  135. zenml/zen_stores/schemas/event_source_schemas.py +8 -1
  136. zenml/zen_stores/schemas/flavor_schemas.py +14 -20
  137. zenml/zen_stores/schemas/model_schemas.py +3 -0
  138. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -1
  139. zenml/zen_stores/schemas/pipeline_run_schemas.py +0 -3
  140. zenml/zen_stores/schemas/run_template_schemas.py +8 -4
  141. zenml/zen_stores/schemas/schedule_schema.py +9 -14
  142. zenml/zen_stores/schemas/secret_schemas.py +15 -25
  143. zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
  144. zenml/zen_stores/schemas/service_schemas.py +0 -1
  145. zenml/zen_stores/schemas/stack_schemas.py +12 -15
  146. zenml/zen_stores/schemas/step_run_schemas.py +7 -8
  147. zenml/zen_stores/schemas/tag_schemas.py +30 -2
  148. zenml/zen_stores/schemas/trigger_schemas.py +8 -1
  149. zenml/zen_stores/schemas/user_schemas.py +24 -2
  150. zenml/zen_stores/schemas/utils.py +16 -0
  151. zenml/zen_stores/schemas/workspace_schemas.py +7 -25
  152. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
  153. zenml/zen_stores/sql_zen_store.py +2905 -2280
  154. zenml/zen_stores/template_utils.py +1 -1
  155. zenml/zen_stores/zen_store_interface.py +82 -58
  156. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
  157. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +160 -147
  158. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
  159. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
  160. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
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,
@@ -2687,8 +2686,7 @@ class Client(metaclass=ClientMetaClass):
2687
2686
  id: Use the id of build to filter by.
2688
2687
  created: Use to filter by time of creation
2689
2688
  updated: Use the last updated date for filtering
2690
- workspace_id: The id of the workspace to filter by.
2691
- user_id: The id of the user to filter by.
2689
+ workspace: The workspace name/ID to filter by.
2692
2690
  user: Filter by user name/ID.
2693
2691
  pipeline_id: The id of the pipeline to filter by.
2694
2692
  stack_id: The id of the stack to filter by.
@@ -2715,8 +2713,7 @@ class Client(metaclass=ClientMetaClass):
2715
2713
  id=id,
2716
2714
  created=created,
2717
2715
  updated=updated,
2718
- workspace_id=workspace_id,
2719
- user_id=user_id,
2716
+ workspace=workspace or self.active_workspace.id,
2720
2717
  user=user,
2721
2718
  pipeline_id=pipeline_id,
2722
2719
  stack_id=stack_id,
@@ -2729,19 +2726,21 @@ class Client(metaclass=ClientMetaClass):
2729
2726
  stack_checksum=stack_checksum,
2730
2727
  duration=duration,
2731
2728
  )
2732
- build_filter_model.set_scope_workspace(self.active_workspace.id)
2733
2729
  return self.zen_store.list_builds(
2734
2730
  build_filter_model=build_filter_model,
2735
2731
  hydrate=hydrate,
2736
2732
  )
2737
2733
 
2738
- 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:
2739
2737
  """Delete a build.
2740
2738
 
2741
2739
  Args:
2742
2740
  id_or_prefix: The id or id prefix of the build.
2741
+ workspace: The workspace name/ID to filter by.
2743
2742
  """
2744
- build = self.get_build(id_or_prefix=id_or_prefix)
2743
+ build = self.get_build(id_or_prefix=id_or_prefix, workspace=workspace)
2745
2744
  self.zen_store.delete_build(build_id=build.id)
2746
2745
 
2747
2746
  # --------------------------------- Event Sources -------------------------
@@ -2774,7 +2773,6 @@ class Client(metaclass=ClientMetaClass):
2774
2773
  flavor=flavor,
2775
2774
  plugin_type=PluginType.EVENT_SOURCE,
2776
2775
  plugin_subtype=event_source_subtype,
2777
- user=self.active_user.id,
2778
2776
  workspace=self.active_workspace.id,
2779
2777
  )
2780
2778
 
@@ -2785,6 +2783,7 @@ class Client(metaclass=ClientMetaClass):
2785
2783
  self,
2786
2784
  name_id_or_prefix: Union[UUID, str],
2787
2785
  allow_name_prefix_match: bool = True,
2786
+ workspace: Optional[Union[str, UUID]] = None,
2788
2787
  hydrate: bool = True,
2789
2788
  ) -> EventSourceResponse:
2790
2789
  """Get an event source by name, ID or prefix.
@@ -2792,6 +2791,7 @@ class Client(metaclass=ClientMetaClass):
2792
2791
  Args:
2793
2792
  name_id_or_prefix: The name, ID or prefix of the stack.
2794
2793
  allow_name_prefix_match: If True, allow matching by name prefix.
2794
+ workspace: The workspace name/ID to filter by.
2795
2795
  hydrate: Flag deciding whether to hydrate the output model(s)
2796
2796
  by including metadata fields in the response.
2797
2797
 
@@ -2803,6 +2803,7 @@ class Client(metaclass=ClientMetaClass):
2803
2803
  list_method=self.list_event_sources,
2804
2804
  name_id_or_prefix=name_id_or_prefix,
2805
2805
  allow_name_prefix_match=allow_name_prefix_match,
2806
+ workspace=workspace,
2806
2807
  hydrate=hydrate,
2807
2808
  )
2808
2809
 
@@ -2818,8 +2819,7 @@ class Client(metaclass=ClientMetaClass):
2818
2819
  name: Optional[str] = None,
2819
2820
  flavor: Optional[str] = None,
2820
2821
  event_source_type: Optional[str] = None,
2821
- workspace_id: Optional[Union[str, UUID]] = None,
2822
- user_id: Optional[Union[str, UUID]] = None,
2822
+ workspace: Optional[Union[str, UUID]] = None,
2823
2823
  user: Optional[Union[UUID, str]] = None,
2824
2824
  hydrate: bool = False,
2825
2825
  ) -> Page[EventSourceResponse]:
@@ -2833,8 +2833,7 @@ class Client(metaclass=ClientMetaClass):
2833
2833
  id: Use the id of event_sources to filter by.
2834
2834
  created: Use to filter by time of creation
2835
2835
  updated: Use the last updated date for filtering
2836
- workspace_id: The id of the workspace to filter by.
2837
- user_id: The id of the user to filter by.
2836
+ workspace: The workspace name/ID to filter by.
2838
2837
  user: Filter by user name/ID.
2839
2838
  name: The name of the event_source to filter by.
2840
2839
  flavor: The flavor of the event_source to filter by.
@@ -2850,8 +2849,7 @@ class Client(metaclass=ClientMetaClass):
2850
2849
  size=size,
2851
2850
  sort_by=sort_by,
2852
2851
  logical_operator=logical_operator,
2853
- workspace_id=workspace_id,
2854
- user_id=user_id,
2852
+ workspace=workspace or self.active_workspace.id,
2855
2853
  user=user,
2856
2854
  name=name,
2857
2855
  flavor=flavor,
@@ -2860,7 +2858,6 @@ class Client(metaclass=ClientMetaClass):
2860
2858
  created=created,
2861
2859
  updated=updated,
2862
2860
  )
2863
- event_source_filter_model.set_scope_workspace(self.active_workspace.id)
2864
2861
  return self.zen_store.list_event_sources(
2865
2862
  event_source_filter_model, hydrate=hydrate
2866
2863
  )
@@ -2874,8 +2871,9 @@ class Client(metaclass=ClientMetaClass):
2874
2871
  configuration: Optional[Dict[str, Any]] = None,
2875
2872
  rotate_secret: Optional[bool] = None,
2876
2873
  is_active: Optional[bool] = None,
2874
+ workspace: Optional[Union[str, UUID]] = None,
2877
2875
  ) -> EventSourceResponse:
2878
- """Updates a event_source.
2876
+ """Updates an event_source.
2879
2877
 
2880
2878
  Args:
2881
2879
  name_id_or_prefix: The name, id or prefix of the event_source to update.
@@ -2886,6 +2884,7 @@ class Client(metaclass=ClientMetaClass):
2886
2884
  contain the new secret value
2887
2885
  is_active: Optional[bool] = Allows for activation/deactivating the
2888
2886
  event source
2887
+ workspace: The workspace name/ID to filter by.
2889
2888
 
2890
2889
  Returns:
2891
2890
  The model of the updated event_source.
@@ -2895,7 +2894,9 @@ class Client(metaclass=ClientMetaClass):
2895
2894
  """
2896
2895
  # First, get the eve
2897
2896
  event_source = self.get_event_source(
2898
- 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,
2899
2900
  )
2900
2901
 
2901
2902
  # Create the update model
@@ -2921,15 +2922,22 @@ class Client(metaclass=ClientMetaClass):
2921
2922
  return updated_event_source
2922
2923
 
2923
2924
  @_fail_for_sql_zen_store
2924
- 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:
2925
2930
  """Deletes an event_source.
2926
2931
 
2927
2932
  Args:
2928
2933
  name_id_or_prefix: The name, id or prefix id of the event_source
2929
2934
  to deregister.
2935
+ workspace: The workspace name/ID to filter by.
2930
2936
  """
2931
2937
  event_source = self.get_event_source(
2932
- 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,
2933
2941
  )
2934
2942
 
2935
2943
  self.zen_store.delete_event_source(event_source_id=event_source.id)
@@ -2973,7 +2981,6 @@ class Client(metaclass=ClientMetaClass):
2973
2981
  configuration=configuration,
2974
2982
  service_account_id=service_account_id,
2975
2983
  auth_window=auth_window,
2976
- user=self.active_user.id,
2977
2984
  workspace=self.active_workspace.id,
2978
2985
  )
2979
2986
 
@@ -2984,6 +2991,7 @@ class Client(metaclass=ClientMetaClass):
2984
2991
  self,
2985
2992
  name_id_or_prefix: Union[UUID, str],
2986
2993
  allow_name_prefix_match: bool = True,
2994
+ workspace: Optional[Union[str, UUID]] = None,
2987
2995
  hydrate: bool = True,
2988
2996
  ) -> ActionResponse:
2989
2997
  """Get an action by name, ID or prefix.
@@ -2991,6 +2999,7 @@ class Client(metaclass=ClientMetaClass):
2991
2999
  Args:
2992
3000
  name_id_or_prefix: The name, ID or prefix of the action.
2993
3001
  allow_name_prefix_match: If True, allow matching by name prefix.
3002
+ workspace: The workspace name/ID to filter by.
2994
3003
  hydrate: Flag deciding whether to hydrate the output model(s)
2995
3004
  by including metadata fields in the response.
2996
3005
 
@@ -3002,6 +3011,7 @@ class Client(metaclass=ClientMetaClass):
3002
3011
  list_method=self.list_actions,
3003
3012
  name_id_or_prefix=name_id_or_prefix,
3004
3013
  allow_name_prefix_match=allow_name_prefix_match,
3014
+ workspace=workspace,
3005
3015
  hydrate=hydrate,
3006
3016
  )
3007
3017
 
@@ -3018,8 +3028,7 @@ class Client(metaclass=ClientMetaClass):
3018
3028
  name: Optional[str] = None,
3019
3029
  flavor: Optional[str] = None,
3020
3030
  action_type: Optional[str] = None,
3021
- workspace_id: Optional[Union[str, UUID]] = None,
3022
- user_id: Optional[Union[str, UUID]] = None,
3031
+ workspace: Optional[Union[str, UUID]] = None,
3023
3032
  user: Optional[Union[UUID, str]] = None,
3024
3033
  hydrate: bool = False,
3025
3034
  ) -> Page[ActionResponse]:
@@ -3033,8 +3042,7 @@ class Client(metaclass=ClientMetaClass):
3033
3042
  id: Use the id of the action to filter by.
3034
3043
  created: Use to filter by time of creation
3035
3044
  updated: Use the last updated date for filtering
3036
- workspace_id: The id of the workspace to filter by.
3037
- user_id: The id of the user to filter by.
3045
+ workspace: The workspace name/ID to filter by.
3038
3046
  user: Filter by user name/ID.
3039
3047
  name: The name of the action to filter by.
3040
3048
  flavor: The flavor of the action to filter by.
@@ -3050,8 +3058,7 @@ class Client(metaclass=ClientMetaClass):
3050
3058
  size=size,
3051
3059
  sort_by=sort_by,
3052
3060
  logical_operator=logical_operator,
3053
- workspace_id=workspace_id,
3054
- user_id=user_id,
3061
+ workspace=workspace or self.active_workspace.id,
3055
3062
  user=user,
3056
3063
  name=name,
3057
3064
  id=id,
@@ -3060,7 +3067,6 @@ class Client(metaclass=ClientMetaClass):
3060
3067
  created=created,
3061
3068
  updated=updated,
3062
3069
  )
3063
- filter_model.set_scope_workspace(self.active_workspace.id)
3064
3070
  return self.zen_store.list_actions(filter_model, hydrate=hydrate)
3065
3071
 
3066
3072
  @_fail_for_sql_zen_store
@@ -3072,6 +3078,7 @@ class Client(metaclass=ClientMetaClass):
3072
3078
  configuration: Optional[Dict[str, Any]] = None,
3073
3079
  service_account_id: Optional[UUID] = None,
3074
3080
  auth_window: Optional[int] = None,
3081
+ workspace: Optional[Union[str, UUID]] = None,
3075
3082
  ) -> ActionResponse:
3076
3083
  """Update an action.
3077
3084
 
@@ -3085,12 +3092,15 @@ class Client(metaclass=ClientMetaClass):
3085
3092
  auth_window: The new time window in minutes for which the service
3086
3093
  account is authorized to execute the action. Set this to 0 to
3087
3094
  authorize the service account indefinitely (not recommended).
3095
+ workspace: The workspace name/ID to filter by.
3088
3096
 
3089
3097
  Returns:
3090
3098
  The updated action.
3091
3099
  """
3092
3100
  action = self.get_action(
3093
- 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,
3094
3104
  )
3095
3105
 
3096
3106
  update_model = ActionUpdate(
@@ -3107,15 +3117,22 @@ class Client(metaclass=ClientMetaClass):
3107
3117
  )
3108
3118
 
3109
3119
  @_fail_for_sql_zen_store
3110
- 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:
3111
3125
  """Delete an action.
3112
3126
 
3113
3127
  Args:
3114
3128
  name_id_or_prefix: The name, id or prefix id of the action
3115
3129
  to delete.
3130
+ workspace: The workspace name/ID to filter by.
3116
3131
  """
3117
3132
  action = self.get_action(
3118
- 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,
3119
3136
  )
3120
3137
 
3121
3138
  self.zen_store.delete_action(action_id=action.id)
@@ -3150,7 +3167,6 @@ class Client(metaclass=ClientMetaClass):
3150
3167
  event_source_id=event_source_id,
3151
3168
  event_filter=event_filter,
3152
3169
  action_id=action_id,
3153
- user=self.active_user.id,
3154
3170
  workspace=self.active_workspace.id,
3155
3171
  )
3156
3172
 
@@ -3161,6 +3177,7 @@ class Client(metaclass=ClientMetaClass):
3161
3177
  self,
3162
3178
  name_id_or_prefix: Union[UUID, str],
3163
3179
  allow_name_prefix_match: bool = True,
3180
+ workspace: Optional[Union[str, UUID]] = None,
3164
3181
  hydrate: bool = True,
3165
3182
  ) -> TriggerResponse:
3166
3183
  """Get a trigger by name, ID or prefix.
@@ -3168,6 +3185,7 @@ class Client(metaclass=ClientMetaClass):
3168
3185
  Args:
3169
3186
  name_id_or_prefix: The name, ID or prefix of the trigger.
3170
3187
  allow_name_prefix_match: If True, allow matching by name prefix.
3188
+ workspace: The workspace name/ID to filter by.
3171
3189
  hydrate: Flag deciding whether to hydrate the output model(s)
3172
3190
  by including metadata fields in the response.
3173
3191
 
@@ -3179,6 +3197,7 @@ class Client(metaclass=ClientMetaClass):
3179
3197
  list_method=self.list_triggers,
3180
3198
  name_id_or_prefix=name_id_or_prefix,
3181
3199
  allow_name_prefix_match=allow_name_prefix_match,
3200
+ workspace=workspace,
3182
3201
  hydrate=hydrate,
3183
3202
  )
3184
3203
 
@@ -3199,8 +3218,7 @@ class Client(metaclass=ClientMetaClass):
3199
3218
  event_source_subtype: Optional[str] = None,
3200
3219
  action_flavor: Optional[str] = None,
3201
3220
  action_subtype: Optional[str] = None,
3202
- workspace_id: Optional[Union[str, UUID]] = None,
3203
- user_id: Optional[Union[str, UUID]] = None,
3221
+ workspace: Optional[Union[str, UUID]] = None,
3204
3222
  user: Optional[Union[UUID, str]] = None,
3205
3223
  hydrate: bool = False,
3206
3224
  ) -> Page[TriggerResponse]:
@@ -3214,8 +3232,7 @@ class Client(metaclass=ClientMetaClass):
3214
3232
  id: Use the id of triggers to filter by.
3215
3233
  created: Use to filter by time of creation
3216
3234
  updated: Use the last updated date for filtering
3217
- workspace_id: The id of the workspace to filter by.
3218
- user_id: The id of the user to filter by.
3235
+ workspace: The workspace name/ID to filter by.
3219
3236
  user: Filter by user name/ID.
3220
3237
  name: The name of the trigger to filter by.
3221
3238
  event_source_id: The event source associated with the trigger.
@@ -3237,8 +3254,7 @@ class Client(metaclass=ClientMetaClass):
3237
3254
  size=size,
3238
3255
  sort_by=sort_by,
3239
3256
  logical_operator=logical_operator,
3240
- workspace_id=workspace_id,
3241
- user_id=user_id,
3257
+ workspace=workspace or self.active_workspace.id,
3242
3258
  user=user,
3243
3259
  name=name,
3244
3260
  event_source_id=event_source_id,
@@ -3251,7 +3267,6 @@ class Client(metaclass=ClientMetaClass):
3251
3267
  created=created,
3252
3268
  updated=updated,
3253
3269
  )
3254
- trigger_filter_model.set_scope_workspace(self.active_workspace.id)
3255
3270
  return self.zen_store.list_triggers(
3256
3271
  trigger_filter_model, hydrate=hydrate
3257
3272
  )
@@ -3264,6 +3279,7 @@ class Client(metaclass=ClientMetaClass):
3264
3279
  description: Optional[str] = None,
3265
3280
  event_filter: Optional[Dict[str, Any]] = None,
3266
3281
  is_active: Optional[bool] = None,
3282
+ workspace: Optional[Union[str, UUID]] = None,
3267
3283
  ) -> TriggerResponse:
3268
3284
  """Updates a trigger.
3269
3285
 
@@ -3273,6 +3289,7 @@ class Client(metaclass=ClientMetaClass):
3273
3289
  description: the new description of the trigger.
3274
3290
  event_filter: The event filter configuration.
3275
3291
  is_active: Whether the trigger is active or not.
3292
+ workspace: The workspace name/ID to filter by.
3276
3293
 
3277
3294
  Returns:
3278
3295
  The model of the updated trigger.
@@ -3282,7 +3299,9 @@ class Client(metaclass=ClientMetaClass):
3282
3299
  """
3283
3300
  # First, get the eve
3284
3301
  trigger = self.get_trigger(
3285
- 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,
3286
3305
  )
3287
3306
 
3288
3307
  # Create the update model
@@ -3307,15 +3326,22 @@ class Client(metaclass=ClientMetaClass):
3307
3326
  return updated_trigger
3308
3327
 
3309
3328
  @_fail_for_sql_zen_store
3310
- 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:
3311
3334
  """Deletes an trigger.
3312
3335
 
3313
3336
  Args:
3314
3337
  name_id_or_prefix: The name, id or prefix id of the trigger
3315
3338
  to deregister.
3339
+ workspace: The workspace name/ID to filter by.
3316
3340
  """
3317
3341
  trigger = self.get_trigger(
3318
- 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,
3319
3345
  )
3320
3346
 
3321
3347
  self.zen_store.delete_trigger(trigger_id=trigger.id)
@@ -3326,12 +3352,14 @@ class Client(metaclass=ClientMetaClass):
3326
3352
  def get_deployment(
3327
3353
  self,
3328
3354
  id_or_prefix: Union[str, UUID],
3355
+ workspace: Optional[Union[str, UUID]] = None,
3329
3356
  hydrate: bool = True,
3330
3357
  ) -> PipelineDeploymentResponse:
3331
3358
  """Get a deployment by id or prefix.
3332
3359
 
3333
3360
  Args:
3334
3361
  id_or_prefix: The id or id prefix of the deployment.
3362
+ workspace: The workspace name/ID to filter by.
3335
3363
  hydrate: Flag deciding whether to hydrate the output model(s)
3336
3364
  by including metadata fields in the response.
3337
3365
 
@@ -3354,10 +3382,16 @@ class Client(metaclass=ClientMetaClass):
3354
3382
  )
3355
3383
  return self.zen_store.get_deployment(id_, hydrate=hydrate)
3356
3384
 
3357
- entity = self.list_deployments(
3385
+ list_kwargs: Dict[str, Any] = dict(
3358
3386
  id=f"startswith:{id_or_prefix}",
3359
3387
  hydrate=hydrate,
3360
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)
3361
3395
 
3362
3396
  # If only a single entity is found, return it.
3363
3397
  if entity.total == 1:
@@ -3367,11 +3401,11 @@ class Client(metaclass=ClientMetaClass):
3367
3401
  if entity.total == 0:
3368
3402
  raise KeyError(
3369
3403
  f"No deployment have been found that have either an id or "
3370
- f"prefix that matches the provided string '{id_or_prefix}'."
3404
+ f"prefix that matches the provided string '{id_or_prefix}'{scope}."
3371
3405
  )
3372
3406
 
3373
3407
  raise ZenKeyError(
3374
- f"{entity.total} deployments have been found that have "
3408
+ f"{entity.total} deployments have been found{scope} that have "
3375
3409
  f"an ID that matches the provided "
3376
3410
  f"string '{id_or_prefix}':\n"
3377
3411
  f"{[entity.items]}.\n"
@@ -3388,8 +3422,7 @@ class Client(metaclass=ClientMetaClass):
3388
3422
  id: Optional[Union[UUID, str]] = None,
3389
3423
  created: Optional[Union[datetime, str]] = None,
3390
3424
  updated: Optional[Union[datetime, str]] = None,
3391
- workspace_id: Optional[Union[str, UUID]] = None,
3392
- user_id: Optional[Union[str, UUID]] = None,
3425
+ workspace: Optional[Union[str, UUID]] = None,
3393
3426
  user: Optional[Union[UUID, str]] = None,
3394
3427
  pipeline_id: Optional[Union[str, UUID]] = None,
3395
3428
  stack_id: Optional[Union[str, UUID]] = None,
@@ -3407,8 +3440,7 @@ class Client(metaclass=ClientMetaClass):
3407
3440
  id: Use the id of build to filter by.
3408
3441
  created: Use to filter by time of creation
3409
3442
  updated: Use the last updated date for filtering
3410
- workspace_id: The id of the workspace to filter by.
3411
- user_id: The id of the user to filter by.
3443
+ workspace: The workspace name/ID to filter by.
3412
3444
  user: Filter by user name/ID.
3413
3445
  pipeline_id: The id of the pipeline to filter by.
3414
3446
  stack_id: The id of the stack to filter by.
@@ -3428,28 +3460,33 @@ class Client(metaclass=ClientMetaClass):
3428
3460
  id=id,
3429
3461
  created=created,
3430
3462
  updated=updated,
3431
- workspace_id=workspace_id,
3432
- user_id=user_id,
3463
+ workspace=workspace or self.active_workspace.id,
3433
3464
  user=user,
3434
3465
  pipeline_id=pipeline_id,
3435
3466
  stack_id=stack_id,
3436
3467
  build_id=build_id,
3437
3468
  template_id=template_id,
3438
3469
  )
3439
- deployment_filter_model.set_scope_workspace(self.active_workspace.id)
3440
3470
  return self.zen_store.list_deployments(
3441
3471
  deployment_filter_model=deployment_filter_model,
3442
3472
  hydrate=hydrate,
3443
3473
  )
3444
3474
 
3445
- 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:
3446
3480
  """Delete a deployment.
3447
3481
 
3448
3482
  Args:
3449
3483
  id_or_prefix: The id or id prefix of the deployment.
3484
+ workspace: The workspace name/ID to filter by.
3450
3485
  """
3451
3486
  deployment = self.get_deployment(
3452
- id_or_prefix=id_or_prefix, hydrate=False
3487
+ id_or_prefix=id_or_prefix,
3488
+ workspace=workspace,
3489
+ hydrate=False,
3453
3490
  )
3454
3491
  self.zen_store.delete_deployment(deployment_id=deployment.id)
3455
3492
 
@@ -3480,7 +3517,6 @@ class Client(metaclass=ClientMetaClass):
3480
3517
  description=description,
3481
3518
  source_deployment_id=deployment_id,
3482
3519
  tags=tags,
3483
- user=self.active_user.id,
3484
3520
  workspace=self.active_workspace.id,
3485
3521
  )
3486
3522
  )
@@ -3488,12 +3524,14 @@ class Client(metaclass=ClientMetaClass):
3488
3524
  def get_run_template(
3489
3525
  self,
3490
3526
  name_id_or_prefix: Union[str, UUID],
3527
+ workspace: Optional[Union[str, UUID]] = None,
3491
3528
  hydrate: bool = True,
3492
3529
  ) -> RunTemplateResponse:
3493
3530
  """Get a run template.
3494
3531
 
3495
3532
  Args:
3496
3533
  name_id_or_prefix: Name/ID/ID prefix of the template to get.
3534
+ workspace: The workspace name/ID to filter by.
3497
3535
  hydrate: Flag deciding whether to hydrate the output model(s)
3498
3536
  by including metadata fields in the response.
3499
3537
 
@@ -3505,6 +3543,7 @@ class Client(metaclass=ClientMetaClass):
3505
3543
  list_method=self.list_run_templates,
3506
3544
  name_id_or_prefix=name_id_or_prefix,
3507
3545
  allow_name_prefix_match=False,
3546
+ workspace=workspace,
3508
3547
  hydrate=hydrate,
3509
3548
  )
3510
3549
 
@@ -3519,8 +3558,7 @@ class Client(metaclass=ClientMetaClass):
3519
3558
  id: Optional[Union[UUID, str]] = None,
3520
3559
  name: Optional[str] = None,
3521
3560
  tag: Optional[str] = None,
3522
- workspace_id: Optional[Union[str, UUID]] = None,
3523
- user_id: Optional[Union[str, UUID]] = None,
3561
+ workspace: Optional[Union[str, UUID]] = None,
3524
3562
  pipeline_id: Optional[Union[str, UUID]] = None,
3525
3563
  build_id: Optional[Union[str, UUID]] = None,
3526
3564
  stack_id: Optional[Union[str, UUID]] = None,
@@ -3542,8 +3580,7 @@ class Client(metaclass=ClientMetaClass):
3542
3580
  id: Filter by run template ID.
3543
3581
  name: Filter by run template name.
3544
3582
  tag: Filter by run template tags.
3545
- workspace_id: Filter by workspace ID.
3546
- user_id: Filter by user ID.
3583
+ workspace: Filter by workspace name/ID.
3547
3584
  pipeline_id: Filter by pipeline ID.
3548
3585
  build_id: Filter by build ID.
3549
3586
  stack_id: Filter by stack ID.
@@ -3567,8 +3604,7 @@ class Client(metaclass=ClientMetaClass):
3567
3604
  id=id,
3568
3605
  name=name,
3569
3606
  tag=tag,
3570
- workspace_id=workspace_id,
3571
- user_id=user_id,
3607
+ workspace=workspace,
3572
3608
  pipeline_id=pipeline_id,
3573
3609
  build_id=build_id,
3574
3610
  stack_id=stack_id,
@@ -3589,6 +3625,7 @@ class Client(metaclass=ClientMetaClass):
3589
3625
  description: Optional[str] = None,
3590
3626
  add_tags: Optional[List[str]] = None,
3591
3627
  remove_tags: Optional[List[str]] = None,
3628
+ workspace: Optional[Union[str, UUID]] = None,
3592
3629
  ) -> RunTemplateResponse:
3593
3630
  """Update a run template.
3594
3631
 
@@ -3598,6 +3635,7 @@ class Client(metaclass=ClientMetaClass):
3598
3635
  description: The new description of the run template.
3599
3636
  add_tags: Tags to add to the run template.
3600
3637
  remove_tags: Tags to remove from the run template.
3638
+ workspace: The workspace name/ID to filter by.
3601
3639
 
3602
3640
  Returns:
3603
3641
  The updated run template.
@@ -3610,7 +3648,9 @@ class Client(metaclass=ClientMetaClass):
3610
3648
  )
3611
3649
  else:
3612
3650
  template_id = self.get_run_template(
3613
- name_id_or_prefix, hydrate=False
3651
+ name_id_or_prefix,
3652
+ workspace=workspace,
3653
+ hydrate=False,
3614
3654
  ).id
3615
3655
 
3616
3656
  return self.zen_store.update_run_template(
@@ -3623,11 +3663,16 @@ class Client(metaclass=ClientMetaClass):
3623
3663
  ),
3624
3664
  )
3625
3665
 
3626
- 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:
3627
3671
  """Delete a run template.
3628
3672
 
3629
3673
  Args:
3630
3674
  name_id_or_prefix: Name/ID/ID prefix of the template to delete.
3675
+ workspace: The workspace name/ID to filter by.
3631
3676
  """
3632
3677
  if is_valid_uuid(name_id_or_prefix):
3633
3678
  template_id = (
@@ -3637,7 +3682,9 @@ class Client(metaclass=ClientMetaClass):
3637
3682
  )
3638
3683
  else:
3639
3684
  template_id = self.get_run_template(
3640
- name_id_or_prefix, hydrate=False
3685
+ name_id_or_prefix,
3686
+ workspace=workspace,
3687
+ hydrate=False,
3641
3688
  ).id
3642
3689
 
3643
3690
  self.zen_store.delete_run_template(template_id=template_id)
@@ -3648,6 +3695,7 @@ class Client(metaclass=ClientMetaClass):
3648
3695
  self,
3649
3696
  name_id_or_prefix: Union[str, UUID],
3650
3697
  allow_name_prefix_match: bool = True,
3698
+ workspace: Optional[Union[str, UUID]] = None,
3651
3699
  hydrate: bool = True,
3652
3700
  ) -> ScheduleResponse:
3653
3701
  """Get a schedule by name, id or prefix.
@@ -3655,6 +3703,7 @@ class Client(metaclass=ClientMetaClass):
3655
3703
  Args:
3656
3704
  name_id_or_prefix: The name, id or prefix of the schedule.
3657
3705
  allow_name_prefix_match: If True, allow matching by name prefix.
3706
+ workspace: The workspace name/ID to filter by.
3658
3707
  hydrate: Flag deciding whether to hydrate the output model(s)
3659
3708
  by including metadata fields in the response.
3660
3709
 
@@ -3666,6 +3715,7 @@ class Client(metaclass=ClientMetaClass):
3666
3715
  list_method=self.list_schedules,
3667
3716
  name_id_or_prefix=name_id_or_prefix,
3668
3717
  allow_name_prefix_match=allow_name_prefix_match,
3718
+ workspace=workspace,
3669
3719
  hydrate=hydrate,
3670
3720
  )
3671
3721
 
@@ -3679,8 +3729,7 @@ class Client(metaclass=ClientMetaClass):
3679
3729
  created: Optional[Union[datetime, str]] = None,
3680
3730
  updated: Optional[Union[datetime, str]] = None,
3681
3731
  name: Optional[str] = None,
3682
- workspace_id: Optional[Union[str, UUID]] = None,
3683
- user_id: Optional[Union[str, UUID]] = None,
3732
+ workspace: Optional[Union[str, UUID]] = None,
3684
3733
  user: Optional[Union[UUID, str]] = None,
3685
3734
  pipeline_id: Optional[Union[str, UUID]] = None,
3686
3735
  orchestrator_id: Optional[Union[str, UUID]] = None,
@@ -3704,8 +3753,7 @@ class Client(metaclass=ClientMetaClass):
3704
3753
  created: Use to filter by time of creation
3705
3754
  updated: Use the last updated date for filtering
3706
3755
  name: The name of the stack to filter by.
3707
- workspace_id: The id of the workspace to filter by.
3708
- user_id: The id of the user to filter by.
3756
+ workspace: The workspace name/ID to filter by.
3709
3757
  user: Filter by user name/ID.
3710
3758
  pipeline_id: The id of the pipeline to filter by.
3711
3759
  orchestrator_id: The id of the orchestrator to filter by.
@@ -3731,8 +3779,7 @@ class Client(metaclass=ClientMetaClass):
3731
3779
  created=created,
3732
3780
  updated=updated,
3733
3781
  name=name,
3734
- workspace_id=workspace_id,
3735
- user_id=user_id,
3782
+ workspace=workspace or self.active_workspace.id,
3736
3783
  user=user,
3737
3784
  pipeline_id=pipeline_id,
3738
3785
  orchestrator_id=orchestrator_id,
@@ -3744,21 +3791,27 @@ class Client(metaclass=ClientMetaClass):
3744
3791
  catchup=catchup,
3745
3792
  run_once_start_time=run_once_start_time,
3746
3793
  )
3747
- schedule_filter_model.set_scope_workspace(self.active_workspace.id)
3748
3794
  return self.zen_store.list_schedules(
3749
3795
  schedule_filter_model=schedule_filter_model,
3750
3796
  hydrate=hydrate,
3751
3797
  )
3752
3798
 
3753
- 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:
3754
3804
  """Delete a schedule.
3755
3805
 
3756
3806
  Args:
3757
3807
  name_id_or_prefix: The name, id or prefix id of the schedule
3758
3808
  to delete.
3809
+ workspace: The workspace name/ID to filter by.
3759
3810
  """
3760
3811
  schedule = self.get_schedule(
3761
- 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,
3762
3815
  )
3763
3816
  logger.warning(
3764
3817
  f"Deleting schedule '{name_id_or_prefix}'... This will only delete "
@@ -3773,6 +3826,7 @@ class Client(metaclass=ClientMetaClass):
3773
3826
  self,
3774
3827
  name_id_or_prefix: Union[str, UUID],
3775
3828
  allow_name_prefix_match: bool = True,
3829
+ workspace: Optional[Union[str, UUID]] = None,
3776
3830
  hydrate: bool = True,
3777
3831
  ) -> PipelineRunResponse:
3778
3832
  """Gets a pipeline run by name, ID, or prefix.
@@ -3780,6 +3834,7 @@ class Client(metaclass=ClientMetaClass):
3780
3834
  Args:
3781
3835
  name_id_or_prefix: Name, ID, or prefix of the pipeline run.
3782
3836
  allow_name_prefix_match: If True, allow matching by name prefix.
3837
+ workspace: The workspace name/ID to filter by.
3783
3838
  hydrate: Flag deciding whether to hydrate the output model(s)
3784
3839
  by including metadata fields in the response.
3785
3840
 
@@ -3791,6 +3846,7 @@ class Client(metaclass=ClientMetaClass):
3791
3846
  list_method=self.list_pipeline_runs,
3792
3847
  name_id_or_prefix=name_id_or_prefix,
3793
3848
  allow_name_prefix_match=allow_name_prefix_match,
3849
+ workspace=workspace,
3794
3850
  hydrate=hydrate,
3795
3851
  )
3796
3852
 
@@ -3804,10 +3860,9 @@ class Client(metaclass=ClientMetaClass):
3804
3860
  created: Optional[Union[datetime, str]] = None,
3805
3861
  updated: Optional[Union[datetime, str]] = None,
3806
3862
  name: Optional[str] = None,
3807
- workspace_id: Optional[Union[str, UUID]] = None,
3863
+ workspace: Optional[Union[str, UUID]] = None,
3808
3864
  pipeline_id: Optional[Union[str, UUID]] = None,
3809
3865
  pipeline_name: Optional[str] = None,
3810
- user_id: Optional[Union[str, UUID]] = None,
3811
3866
  stack_id: Optional[Union[str, UUID]] = None,
3812
3867
  schedule_id: Optional[Union[str, UUID]] = None,
3813
3868
  build_id: Optional[Union[str, UUID]] = None,
@@ -3819,10 +3874,10 @@ class Client(metaclass=ClientMetaClass):
3819
3874
  status: Optional[str] = None,
3820
3875
  start_time: Optional[Union[datetime, str]] = None,
3821
3876
  end_time: Optional[Union[datetime, str]] = None,
3822
- num_steps: Optional[Union[int, str]] = None,
3823
3877
  unlisted: Optional[bool] = None,
3824
3878
  templatable: Optional[bool] = None,
3825
3879
  tag: Optional[str] = None,
3880
+ tags: Optional[List[str]] = None,
3826
3881
  user: Optional[Union[UUID, str]] = None,
3827
3882
  run_metadata: Optional[Dict[str, Any]] = None,
3828
3883
  pipeline: Optional[Union[UUID, str]] = None,
@@ -3842,11 +3897,10 @@ class Client(metaclass=ClientMetaClass):
3842
3897
  id: The id of the runs to filter by.
3843
3898
  created: Use to filter by time of creation
3844
3899
  updated: Use the last updated date for filtering
3845
- workspace_id: The id of the workspace to filter by.
3900
+ workspace: The workspace name/ID to filter by.
3846
3901
  pipeline_id: The id of the pipeline to filter by.
3847
3902
  pipeline_name: DEPRECATED. Use `pipeline` instead to filter by
3848
3903
  pipeline name.
3849
- user_id: The id of the user to filter by.
3850
3904
  stack_id: The id of the stack to filter by.
3851
3905
  schedule_id: The id of the schedule to filter by.
3852
3906
  build_id: The id of the build to filter by.
@@ -3859,10 +3913,10 @@ class Client(metaclass=ClientMetaClass):
3859
3913
  status: The status of the pipeline run
3860
3914
  start_time: The start_time for the pipeline run
3861
3915
  end_time: The end_time for the pipeline run
3862
- num_steps: The number of steps for the pipeline run
3863
3916
  unlisted: If the runs should be unlisted or not.
3864
3917
  templatable: If the runs should be templatable or not.
3865
3918
  tag: Tag to filter by.
3919
+ tags: Tags to filter by.
3866
3920
  user: The name/ID of the user to filter by.
3867
3921
  run_metadata: The run_metadata of the run to filter by.
3868
3922
  pipeline: The name/ID of the pipeline to filter by.
@@ -3885,7 +3939,7 @@ class Client(metaclass=ClientMetaClass):
3885
3939
  created=created,
3886
3940
  updated=updated,
3887
3941
  name=name,
3888
- workspace_id=workspace_id,
3942
+ workspace=workspace or self.active_workspace.id,
3889
3943
  pipeline_id=pipeline_id,
3890
3944
  pipeline_name=pipeline_name,
3891
3945
  schedule_id=schedule_id,
@@ -3895,13 +3949,12 @@ class Client(metaclass=ClientMetaClass):
3895
3949
  template_id=template_id,
3896
3950
  model_version_id=model_version_id,
3897
3951
  orchestrator_run_id=orchestrator_run_id,
3898
- user_id=user_id,
3899
3952
  stack_id=stack_id,
3900
3953
  status=status,
3901
3954
  start_time=start_time,
3902
3955
  end_time=end_time,
3903
- num_steps=num_steps,
3904
3956
  tag=tag,
3957
+ tags=tags,
3905
3958
  unlisted=unlisted,
3906
3959
  user=user,
3907
3960
  run_metadata=run_metadata,
@@ -3912,7 +3965,6 @@ class Client(metaclass=ClientMetaClass):
3912
3965
  stack_component=stack_component,
3913
3966
  templatable=templatable,
3914
3967
  )
3915
- runs_filter_model.set_scope_workspace(self.active_workspace.id)
3916
3968
  return self.zen_store.list_runs(
3917
3969
  runs_filter_model=runs_filter_model,
3918
3970
  hydrate=hydrate,
@@ -3921,14 +3973,18 @@ class Client(metaclass=ClientMetaClass):
3921
3973
  def delete_pipeline_run(
3922
3974
  self,
3923
3975
  name_id_or_prefix: Union[str, UUID],
3976
+ workspace: Optional[Union[str, UUID]] = None,
3924
3977
  ) -> None:
3925
3978
  """Deletes a pipeline run.
3926
3979
 
3927
3980
  Args:
3928
3981
  name_id_or_prefix: Name, ID, or prefix of the pipeline run.
3982
+ workspace: The workspace name/ID to filter by.
3929
3983
  """
3930
3984
  run = self.get_pipeline_run(
3931
- 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,
3932
3988
  )
3933
3989
  self.zen_store.delete_run(run_id=run.id)
3934
3990
 
@@ -3972,8 +4028,7 @@ class Client(metaclass=ClientMetaClass):
3972
4028
  pipeline_run_id: Optional[Union[str, UUID]] = None,
3973
4029
  deployment_id: Optional[Union[str, UUID]] = None,
3974
4030
  original_step_run_id: Optional[Union[str, UUID]] = None,
3975
- workspace_id: Optional[Union[str, UUID]] = None,
3976
- user_id: Optional[Union[str, UUID]] = None,
4031
+ workspace: Optional[Union[str, UUID]] = None,
3977
4032
  user: Optional[Union[UUID, str]] = None,
3978
4033
  model_version_id: Optional[Union[str, UUID]] = None,
3979
4034
  model: Optional[Union[UUID, str]] = None,
@@ -3992,8 +4047,7 @@ class Client(metaclass=ClientMetaClass):
3992
4047
  updated: Use the last updated date for filtering
3993
4048
  start_time: Use to filter by the time when the step started running
3994
4049
  end_time: Use to filter by the time when the step finished running
3995
- workspace_id: The id of the workspace to filter by.
3996
- user_id: The id of the user to filter by.
4050
+ workspace: The workspace name/ID to filter by.
3997
4051
  user: Filter by user name/ID.
3998
4052
  pipeline_run_id: The id of the pipeline run to filter by.
3999
4053
  deployment_id: The id of the deployment to filter by.
@@ -4028,14 +4082,12 @@ class Client(metaclass=ClientMetaClass):
4028
4082
  start_time=start_time,
4029
4083
  end_time=end_time,
4030
4084
  name=name,
4031
- workspace_id=workspace_id,
4032
- user_id=user_id,
4085
+ workspace=workspace or self.active_workspace.id,
4033
4086
  user=user,
4034
4087
  model_version_id=model_version_id,
4035
4088
  model=model,
4036
4089
  run_metadata=run_metadata,
4037
4090
  )
4038
- step_run_filter_model.set_scope_workspace(self.active_workspace.id)
4039
4091
  return self.zen_store.list_run_steps(
4040
4092
  step_run_filter_model=step_run_filter_model,
4041
4093
  hydrate=hydrate,
@@ -4046,12 +4098,14 @@ class Client(metaclass=ClientMetaClass):
4046
4098
  def get_artifact(
4047
4099
  self,
4048
4100
  name_id_or_prefix: Union[str, UUID],
4101
+ workspace: Optional[Union[str, UUID]] = None,
4049
4102
  hydrate: bool = False,
4050
4103
  ) -> ArtifactResponse:
4051
4104
  """Get an artifact by name, id or prefix.
4052
4105
 
4053
4106
  Args:
4054
4107
  name_id_or_prefix: The name, ID or prefix of the artifact to get.
4108
+ workspace: The workspace name/ID to filter by.
4055
4109
  hydrate: Flag deciding whether to hydrate the output model(s)
4056
4110
  by including metadata fields in the response.
4057
4111
 
@@ -4062,6 +4116,7 @@ class Client(metaclass=ClientMetaClass):
4062
4116
  get_method=self.zen_store.get_artifact,
4063
4117
  list_method=self.list_artifacts,
4064
4118
  name_id_or_prefix=name_id_or_prefix,
4119
+ workspace=workspace,
4065
4120
  hydrate=hydrate,
4066
4121
  )
4067
4122
 
@@ -4076,8 +4131,11 @@ class Client(metaclass=ClientMetaClass):
4076
4131
  updated: Optional[Union[datetime, str]] = None,
4077
4132
  name: Optional[str] = None,
4078
4133
  has_custom_name: Optional[bool] = None,
4134
+ user: Optional[Union[UUID, str]] = None,
4135
+ workspace: Optional[Union[str, UUID]] = None,
4079
4136
  hydrate: bool = False,
4080
4137
  tag: Optional[str] = None,
4138
+ tags: Optional[List[str]] = None,
4081
4139
  ) -> Page[ArtifactResponse]:
4082
4140
  """Get a list of artifacts.
4083
4141
 
@@ -4091,9 +4149,12 @@ class Client(metaclass=ClientMetaClass):
4091
4149
  updated: Use the last updated date for filtering
4092
4150
  name: The name of the artifact to filter by.
4093
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.
4094
4154
  hydrate: Flag deciding whether to hydrate the output model(s)
4095
4155
  by including metadata fields in the response.
4096
4156
  tag: Filter artifacts by tag.
4157
+ tags: Tags to filter by.
4097
4158
 
4098
4159
  Returns:
4099
4160
  A list of artifacts.
@@ -4109,6 +4170,9 @@ class Client(metaclass=ClientMetaClass):
4109
4170
  name=name,
4110
4171
  has_custom_name=has_custom_name,
4111
4172
  tag=tag,
4173
+ tags=tags,
4174
+ user=user,
4175
+ workspace=workspace or self.active_workspace.id,
4112
4176
  )
4113
4177
  return self.zen_store.list_artifacts(
4114
4178
  artifact_filter_model,
@@ -4122,6 +4186,7 @@ class Client(metaclass=ClientMetaClass):
4122
4186
  add_tags: Optional[List[str]] = None,
4123
4187
  remove_tags: Optional[List[str]] = None,
4124
4188
  has_custom_name: Optional[bool] = None,
4189
+ workspace: Optional[Union[str, UUID]] = None,
4125
4190
  ) -> ArtifactResponse:
4126
4191
  """Update an artifact.
4127
4192
 
@@ -4131,11 +4196,15 @@ class Client(metaclass=ClientMetaClass):
4131
4196
  add_tags: Tags to add to the artifact.
4132
4197
  remove_tags: Tags to remove from the artifact.
4133
4198
  has_custom_name: Whether the artifact has a custom name.
4199
+ workspace: The workspace name/ID to filter by.
4134
4200
 
4135
4201
  Returns:
4136
4202
  The updated artifact.
4137
4203
  """
4138
- 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
+ )
4139
4208
  artifact_update = ArtifactUpdate(
4140
4209
  name=new_name,
4141
4210
  add_tags=add_tags,
@@ -4149,13 +4218,18 @@ class Client(metaclass=ClientMetaClass):
4149
4218
  def delete_artifact(
4150
4219
  self,
4151
4220
  name_id_or_prefix: Union[str, UUID],
4221
+ workspace: Optional[Union[str, UUID]] = None,
4152
4222
  ) -> None:
4153
4223
  """Delete an artifact.
4154
4224
 
4155
4225
  Args:
4156
4226
  name_id_or_prefix: The name, ID or prefix of the artifact to delete.
4227
+ workspace: The workspace name/ID to filter by.
4157
4228
  """
4158
- 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
+ )
4159
4233
  self.zen_store.delete_artifact(artifact_id=artifact.id)
4160
4234
  logger.info(f"Deleted artifact '{artifact.name}'.")
4161
4235
 
@@ -4163,23 +4237,31 @@ class Client(metaclass=ClientMetaClass):
4163
4237
  self,
4164
4238
  only_versions: bool = True,
4165
4239
  delete_from_artifact_store: bool = False,
4240
+ workspace: Optional[Union[str, UUID]] = None,
4166
4241
  ) -> None:
4167
4242
  """Delete all unused artifacts and artifact versions.
4168
4243
 
4169
4244
  Args:
4170
4245
  only_versions: Only delete artifact versions, keeping artifacts
4171
4246
  delete_from_artifact_store: Delete data from artifact metadata
4247
+ workspace: The workspace name/ID to filter by.
4172
4248
  """
4173
4249
  if delete_from_artifact_store:
4174
4250
  unused_artifact_versions = depaginate(
4175
- self.list_artifact_versions, only_unused=True
4251
+ self.list_artifact_versions,
4252
+ only_unused=True,
4253
+ workspace=workspace,
4176
4254
  )
4177
4255
  for unused_artifact_version in unused_artifact_versions:
4178
4256
  self._delete_artifact_from_artifact_store(
4179
4257
  unused_artifact_version
4180
4258
  )
4181
4259
 
4182
- 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
+ )
4183
4265
  logger.info("All unused artifacts and artifact versions deleted.")
4184
4266
 
4185
4267
  # --------------------------- Artifact Versions ---------------------------
@@ -4188,6 +4270,7 @@ class Client(metaclass=ClientMetaClass):
4188
4270
  self,
4189
4271
  name_id_or_prefix: Union[str, UUID],
4190
4272
  version: Optional[str] = None,
4273
+ workspace: Optional[Union[str, UUID]] = None,
4191
4274
  hydrate: bool = True,
4192
4275
  ) -> ArtifactVersionResponse:
4193
4276
  """Get an artifact version by ID or artifact name.
@@ -4198,6 +4281,7 @@ class Client(metaclass=ClientMetaClass):
4198
4281
  version: The version of the artifact to get. Only used if
4199
4282
  `name_id_or_prefix` is the name of the artifact. If not
4200
4283
  specified, the latest version is returned.
4284
+ workspace: The workspace name/ID to filter by.
4201
4285
  hydrate: Flag deciding whether to hydrate the output model(s)
4202
4286
  by including metadata fields in the response.
4203
4287
 
@@ -4210,6 +4294,7 @@ class Client(metaclass=ClientMetaClass):
4210
4294
  method_name="get_artifact_version",
4211
4295
  name_id_or_prefix=name_id_or_prefix,
4212
4296
  version=version,
4297
+ workspace=workspace,
4213
4298
  hydrate=hydrate,
4214
4299
  ):
4215
4300
  return cll # type: ignore[return-value]
@@ -4219,6 +4304,7 @@ class Client(metaclass=ClientMetaClass):
4219
4304
  list_method=self.list_artifact_versions,
4220
4305
  name_id_or_prefix=name_id_or_prefix,
4221
4306
  version=version,
4307
+ workspace=workspace,
4222
4308
  hydrate=hydrate,
4223
4309
  )
4224
4310
  try:
@@ -4243,7 +4329,7 @@ class Client(metaclass=ClientMetaClass):
4243
4329
  id: Optional[Union[UUID, str]] = None,
4244
4330
  created: Optional[Union[datetime, str]] = None,
4245
4331
  updated: Optional[Union[datetime, str]] = None,
4246
- artifact_id: Optional[Union[str, UUID]] = None,
4332
+ artifact: Optional[Union[str, UUID]] = None,
4247
4333
  name: Optional[str] = None,
4248
4334
  version: Optional[Union[str, int]] = None,
4249
4335
  version_number: Optional[int] = None,
@@ -4252,8 +4338,7 @@ class Client(metaclass=ClientMetaClass):
4252
4338
  data_type: Optional[str] = None,
4253
4339
  uri: Optional[str] = None,
4254
4340
  materializer: Optional[str] = None,
4255
- workspace_id: Optional[Union[str, UUID]] = None,
4256
- user_id: Optional[Union[str, UUID]] = None,
4341
+ workspace: Optional[Union[str, UUID]] = None,
4257
4342
  model_version_id: Optional[Union[str, UUID]] = None,
4258
4343
  only_unused: Optional[bool] = False,
4259
4344
  has_custom_name: Optional[bool] = None,
@@ -4262,6 +4347,7 @@ class Client(metaclass=ClientMetaClass):
4262
4347
  pipeline_run: Optional[Union[UUID, str]] = None,
4263
4348
  run_metadata: Optional[Dict[str, Any]] = None,
4264
4349
  tag: Optional[str] = None,
4350
+ tags: Optional[List[str]] = None,
4265
4351
  hydrate: bool = False,
4266
4352
  ) -> Page[ArtifactVersionResponse]:
4267
4353
  """Get a list of artifact versions.
@@ -4274,7 +4360,7 @@ class Client(metaclass=ClientMetaClass):
4274
4360
  id: Use the id of artifact version to filter by.
4275
4361
  created: Use to filter by time of creation
4276
4362
  updated: Use the last updated date for filtering
4277
- artifact_id: The id of the artifact to filter by.
4363
+ artifact: The name or ID of the artifact to filter by.
4278
4364
  name: The name of the artifact to filter by.
4279
4365
  version: The version of the artifact to filter by.
4280
4366
  version_number: The version number of the artifact to filter by.
@@ -4283,13 +4369,13 @@ class Client(metaclass=ClientMetaClass):
4283
4369
  data_type: The data type of the artifact to filter by.
4284
4370
  uri: The uri of the artifact to filter by.
4285
4371
  materializer: The materializer of the artifact to filter by.
4286
- workspace_id: The id of the workspace to filter by.
4287
- user_id: The id of the user to filter by.
4372
+ workspace: The workspace name/ID to filter by.
4288
4373
  model_version_id: Filter by model version ID.
4289
4374
  only_unused: Only return artifact versions that are not used in
4290
4375
  any pipeline runs.
4291
4376
  has_custom_name: Filter artifacts with/without custom names.
4292
4377
  tag: A tag to filter by.
4378
+ tags: Tags to filter by.
4293
4379
  user: Filter by user name or ID.
4294
4380
  model: Filter by model name or ID.
4295
4381
  pipeline_run: Filter by pipeline run name or ID.
@@ -4300,6 +4386,9 @@ class Client(metaclass=ClientMetaClass):
4300
4386
  Returns:
4301
4387
  A list of artifact versions.
4302
4388
  """
4389
+ if name:
4390
+ artifact = name
4391
+
4303
4392
  artifact_version_filter_model = ArtifactVersionFilter(
4304
4393
  sort_by=sort_by,
4305
4394
  page=page,
@@ -4308,8 +4397,7 @@ class Client(metaclass=ClientMetaClass):
4308
4397
  id=id,
4309
4398
  created=created,
4310
4399
  updated=updated,
4311
- artifact_id=artifact_id,
4312
- name=name,
4400
+ artifact=artifact,
4313
4401
  version=str(version) if version else None,
4314
4402
  version_number=version_number,
4315
4403
  artifact_store_id=artifact_store_id,
@@ -4317,20 +4405,17 @@ class Client(metaclass=ClientMetaClass):
4317
4405
  data_type=data_type,
4318
4406
  uri=uri,
4319
4407
  materializer=materializer,
4320
- workspace_id=workspace_id,
4321
- user_id=user_id,
4408
+ workspace=workspace or self.active_workspace.id,
4322
4409
  model_version_id=model_version_id,
4323
4410
  only_unused=only_unused,
4324
4411
  has_custom_name=has_custom_name,
4325
4412
  tag=tag,
4413
+ tags=tags,
4326
4414
  user=user,
4327
4415
  model=model,
4328
4416
  pipeline_run=pipeline_run,
4329
4417
  run_metadata=run_metadata,
4330
4418
  )
4331
- artifact_version_filter_model.set_scope_workspace(
4332
- self.active_workspace.id
4333
- )
4334
4419
  return self.zen_store.list_artifact_versions(
4335
4420
  artifact_version_filter_model,
4336
4421
  hydrate=hydrate,
@@ -4342,6 +4427,7 @@ class Client(metaclass=ClientMetaClass):
4342
4427
  version: Optional[str] = None,
4343
4428
  add_tags: Optional[List[str]] = None,
4344
4429
  remove_tags: Optional[List[str]] = None,
4430
+ workspace: Optional[Union[str, UUID]] = None,
4345
4431
  ) -> ArtifactVersionResponse:
4346
4432
  """Update an artifact version.
4347
4433
 
@@ -4352,6 +4438,7 @@ class Client(metaclass=ClientMetaClass):
4352
4438
  specified, the latest version is updated.
4353
4439
  add_tags: Tags to add to the artifact version.
4354
4440
  remove_tags: Tags to remove from the artifact version.
4441
+ workspace: The workspace name/ID to filter by.
4355
4442
 
4356
4443
  Returns:
4357
4444
  The updated artifact version.
@@ -4359,6 +4446,7 @@ class Client(metaclass=ClientMetaClass):
4359
4446
  artifact_version = self.get_artifact_version(
4360
4447
  name_id_or_prefix=name_id_or_prefix,
4361
4448
  version=version,
4449
+ workspace=workspace,
4362
4450
  )
4363
4451
  artifact_version_update = ArtifactVersionUpdate(
4364
4452
  add_tags=add_tags, remove_tags=remove_tags
@@ -4374,6 +4462,7 @@ class Client(metaclass=ClientMetaClass):
4374
4462
  version: Optional[str] = None,
4375
4463
  delete_metadata: bool = True,
4376
4464
  delete_from_artifact_store: bool = False,
4465
+ workspace: Optional[Union[str, UUID]] = None,
4377
4466
  ) -> None:
4378
4467
  """Delete an artifact version.
4379
4468
 
@@ -4387,10 +4476,13 @@ class Client(metaclass=ClientMetaClass):
4387
4476
  delete_metadata: If True, delete the metadata of the artifact
4388
4477
  version from the database.
4389
4478
  delete_from_artifact_store: If True, delete the artifact object
4390
- itself from the artifact store.
4479
+ itself from the artifact store.
4480
+ workspace: The workspace name/ID to filter by.
4391
4481
  """
4392
4482
  artifact_version = self.get_artifact_version(
4393
- 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,
4394
4486
  )
4395
4487
  if delete_from_artifact_store:
4396
4488
  self._delete_artifact_from_artifact_store(
@@ -4514,7 +4606,6 @@ class Client(metaclass=ClientMetaClass):
4514
4606
 
4515
4607
  run_metadata = RunMetadataRequest(
4516
4608
  workspace=self.active_workspace.id,
4517
- user=self.active_user.id,
4518
4609
  resources=resources,
4519
4610
  stack_component_id=stack_component_id,
4520
4611
  publisher_step_id=publisher_step_id,
@@ -4529,14 +4620,15 @@ class Client(metaclass=ClientMetaClass):
4529
4620
  self,
4530
4621
  name: str,
4531
4622
  values: Dict[str, str],
4532
- scope: SecretScope = SecretScope.WORKSPACE,
4623
+ private: bool = False,
4533
4624
  ) -> SecretResponse:
4534
4625
  """Creates a new secret.
4535
4626
 
4536
4627
  Args:
4537
4628
  name: The name of the secret.
4538
4629
  values: The values of the secret.
4539
- 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.
4540
4632
 
4541
4633
  Returns:
4542
4634
  The created secret (in model form).
@@ -4548,9 +4640,7 @@ class Client(metaclass=ClientMetaClass):
4548
4640
  create_secret_request = SecretRequest(
4549
4641
  name=name,
4550
4642
  values=values,
4551
- scope=scope,
4552
- user=self.active_user.id,
4553
- workspace=self.active_workspace.id,
4643
+ private=private,
4554
4644
  )
4555
4645
  try:
4556
4646
  return self.zen_store.create_secret(secret=create_secret_request)
@@ -4563,7 +4653,7 @@ class Client(metaclass=ClientMetaClass):
4563
4653
  def get_secret(
4564
4654
  self,
4565
4655
  name_id_or_prefix: Union[str, UUID],
4566
- scope: Optional[SecretScope] = None,
4656
+ private: Optional[bool] = None,
4567
4657
  allow_partial_name_match: bool = True,
4568
4658
  allow_partial_id_match: bool = True,
4569
4659
  hydrate: bool = True,
@@ -4573,18 +4663,17 @@ class Client(metaclass=ClientMetaClass):
4573
4663
  Get a secret identified by a name, ID or prefix of the name or ID and
4574
4664
  optionally a scope.
4575
4665
 
4576
- If a scope is not provided, the secret will be searched for in all
4577
- scopes starting with the innermost scope (user) to the outermost scope
4578
- (workspace). When a name or prefix is used instead of a UUID value, each
4579
- scope is first searched for an exact match, then for a ID prefix or
4580
- 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.
4581
4671
 
4582
4672
  Args:
4583
4673
  name_id_or_prefix: The name, ID or prefix to the id of the secret
4584
4674
  to get.
4585
- scope: The scope of the secret. If not set, all scopes will be
4586
- searched starting with the innermost scope (user) to the
4587
- 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.
4588
4677
  allow_partial_name_match: If True, allow partial name matches.
4589
4678
  allow_partial_id_match: If True, allow partial ID matches.
4590
4679
  hydrate: Flag deciding whether to hydrate the output model(s)
@@ -4611,7 +4700,7 @@ class Client(metaclass=ClientMetaClass):
4611
4700
  else name_id_or_prefix,
4612
4701
  hydrate=hydrate,
4613
4702
  )
4614
- if scope is not None and secret.scope != scope:
4703
+ if private is not None and secret.private != private:
4615
4704
  raise KeyError(
4616
4705
  f"No secret found with ID {str(name_id_or_prefix)}"
4617
4706
  )
@@ -4626,11 +4715,9 @@ class Client(metaclass=ClientMetaClass):
4626
4715
  # If not a UUID, try to find by name and then by prefix
4627
4716
  assert not isinstance(name_id_or_prefix, UUID)
4628
4717
 
4629
- # Scopes to search in order of priority
4630
- search_scopes = (
4631
- [SecretScope.USER, SecretScope.WORKSPACE]
4632
- if scope is None
4633
- else [scope]
4718
+ # Private statuses to search in order of priority
4719
+ search_private_statuses = (
4720
+ [False, True] if private is None else [private]
4634
4721
  )
4635
4722
 
4636
4723
  secrets = self.list_secrets(
@@ -4644,10 +4731,10 @@ class Client(metaclass=ClientMetaClass):
4644
4731
  hydrate=hydrate,
4645
4732
  )
4646
4733
 
4647
- for search_scope in search_scopes:
4734
+ for search_private_status in search_private_statuses:
4648
4735
  partial_matches: List[SecretResponse] = []
4649
4736
  for secret in secrets.items:
4650
- if secret.scope != search_scope:
4737
+ if secret.private != search_private_status:
4651
4738
  continue
4652
4739
  # Exact match
4653
4740
  if secret.name == name_id_or_prefix:
@@ -4682,10 +4769,13 @@ class Client(metaclass=ClientMetaClass):
4682
4769
  secret_id=partial_matches[0].id,
4683
4770
  hydrate=hydrate,
4684
4771
  )
4685
-
4686
- msg = f"No secret found with name, ID or prefix '{name_id_or_prefix}'"
4687
- if scope is not None:
4688
- 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
+ )
4689
4779
 
4690
4780
  raise KeyError(msg)
4691
4781
 
@@ -4699,9 +4789,7 @@ class Client(metaclass=ClientMetaClass):
4699
4789
  created: Optional[datetime] = None,
4700
4790
  updated: Optional[datetime] = None,
4701
4791
  name: Optional[str] = None,
4702
- scope: Optional[SecretScope] = None,
4703
- workspace_id: Optional[Union[str, UUID]] = None,
4704
- user_id: Optional[Union[str, UUID]] = None,
4792
+ private: Optional[bool] = None,
4705
4793
  user: Optional[Union[UUID, str]] = None,
4706
4794
  hydrate: bool = False,
4707
4795
  ) -> Page[SecretResponse]:
@@ -4719,9 +4807,7 @@ class Client(metaclass=ClientMetaClass):
4719
4807
  created: Use to secrets by time of creation
4720
4808
  updated: Use the last updated date for filtering
4721
4809
  name: The name of the secret to filter by.
4722
- scope: The scope of the secret to filter by.
4723
- workspace_id: The id of the workspace to filter by.
4724
- user_id: The id of the user to filter by.
4810
+ private: The private status of the secret to filter by.
4725
4811
  user: Filter by user name/ID.
4726
4812
  hydrate: Flag deciding whether to hydrate the output model(s)
4727
4813
  by including metadata fields in the response.
@@ -4738,16 +4824,13 @@ class Client(metaclass=ClientMetaClass):
4738
4824
  size=size,
4739
4825
  sort_by=sort_by,
4740
4826
  logical_operator=logical_operator,
4741
- user_id=user_id,
4742
4827
  user=user,
4743
- workspace_id=workspace_id,
4744
4828
  name=name,
4745
- scope=scope,
4829
+ private=private,
4746
4830
  id=id,
4747
4831
  created=created,
4748
4832
  updated=updated,
4749
4833
  )
4750
- secret_filter_model.set_scope_workspace(self.active_workspace.id)
4751
4834
  try:
4752
4835
  return self.zen_store.list_secrets(
4753
4836
  secret_filter_model=secret_filter_model,
@@ -4762,9 +4845,9 @@ class Client(metaclass=ClientMetaClass):
4762
4845
  def update_secret(
4763
4846
  self,
4764
4847
  name_id_or_prefix: Union[str, UUID],
4765
- scope: Optional[SecretScope] = None,
4848
+ private: Optional[bool] = None,
4766
4849
  new_name: Optional[str] = None,
4767
- new_scope: Optional[SecretScope] = None,
4850
+ update_private: Optional[bool] = None,
4768
4851
  add_or_update_values: Optional[Dict[str, str]] = None,
4769
4852
  remove_values: Optional[List[str]] = None,
4770
4853
  ) -> SecretResponse:
@@ -4773,9 +4856,10 @@ class Client(metaclass=ClientMetaClass):
4773
4856
  Args:
4774
4857
  name_id_or_prefix: The name, id or prefix of the id for the
4775
4858
  secret to update.
4776
- scope: The scope of the secret to update.
4859
+ private: The private status of the secret to update.
4777
4860
  new_name: The new name of the secret.
4778
- new_scope: The new scope of the secret.
4861
+ update_private: New value used to update the private status of the
4862
+ secret.
4779
4863
  add_or_update_values: The values to add or update.
4780
4864
  remove_values: The values to remove.
4781
4865
 
@@ -4789,7 +4873,7 @@ class Client(metaclass=ClientMetaClass):
4789
4873
  """
4790
4874
  secret = self.get_secret(
4791
4875
  name_id_or_prefix=name_id_or_prefix,
4792
- scope=scope,
4876
+ private=private,
4793
4877
  # Don't allow partial name matches, but allow partial ID matches
4794
4878
  allow_partial_name_match=False,
4795
4879
  allow_partial_id_match=True,
@@ -4798,8 +4882,8 @@ class Client(metaclass=ClientMetaClass):
4798
4882
 
4799
4883
  secret_update = SecretUpdate(name=new_name or secret.name)
4800
4884
 
4801
- if new_scope:
4802
- secret_update.scope = new_scope
4885
+ if update_private:
4886
+ secret_update.private = update_private
4803
4887
  values: Dict[str, Optional[SecretStr]] = {}
4804
4888
  if add_or_update_values:
4805
4889
  values.update(
@@ -4829,17 +4913,17 @@ class Client(metaclass=ClientMetaClass):
4829
4913
  )
4830
4914
 
4831
4915
  def delete_secret(
4832
- self, name_id_or_prefix: str, scope: Optional[SecretScope] = None
4916
+ self, name_id_or_prefix: str, private: Optional[bool] = None
4833
4917
  ) -> None:
4834
4918
  """Deletes a secret.
4835
4919
 
4836
4920
  Args:
4837
4921
  name_id_or_prefix: The name or ID of the secret.
4838
- scope: The scope of the secret to delete.
4922
+ private: The private status of the secret to delete.
4839
4923
  """
4840
4924
  secret = self.get_secret(
4841
4925
  name_id_or_prefix=name_id_or_prefix,
4842
- scope=scope,
4926
+ private=private,
4843
4927
  # Don't allow partial name matches, but allow partial ID matches
4844
4928
  allow_partial_name_match=False,
4845
4929
  allow_partial_id_match=True,
@@ -4847,23 +4931,24 @@ class Client(metaclass=ClientMetaClass):
4847
4931
 
4848
4932
  self.zen_store.delete_secret(secret_id=secret.id)
4849
4933
 
4850
- def get_secret_by_name_and_scope(
4934
+ def get_secret_by_name_and_private_status(
4851
4935
  self,
4852
4936
  name: str,
4853
- scope: Optional[SecretScope] = None,
4937
+ private: Optional[bool] = None,
4854
4938
  hydrate: bool = True,
4855
4939
  ) -> SecretResponse:
4856
- """Fetches a registered secret with a given name and optional scope.
4940
+ """Fetches a registered secret with a given name and optional private status.
4857
4941
 
4858
4942
  This is a version of get_secret that restricts the search to a given
4859
- 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.
4860
4945
 
4861
- If no scope is provided, the search will be done first in the user
4862
- 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.
4863
4948
 
4864
4949
  Args:
4865
4950
  name: The name of the secret to get.
4866
- scope: The scope of the secret to get.
4951
+ private: The private status of the secret to get.
4867
4952
  hydrate: Flag deciding whether to hydrate the output model(s)
4868
4953
  by including metadata fields in the response.
4869
4954
 
@@ -4874,21 +4959,20 @@ class Client(metaclass=ClientMetaClass):
4874
4959
  KeyError: If no secret exists for the given name in the given scope.
4875
4960
  """
4876
4961
  logger.debug(
4877
- f"Fetching the secret with name '{name}' and scope '{scope}'."
4962
+ f"Fetching the secret with name '{name}' and private status "
4963
+ f"'{private}'."
4878
4964
  )
4879
4965
 
4880
- # Scopes to search in order of priority
4881
- search_scopes = (
4882
- [SecretScope.USER, SecretScope.WORKSPACE]
4883
- if scope is None
4884
- else [scope]
4966
+ # Private statuses to search in order of priority
4967
+ search_private_statuses = (
4968
+ [False, True] if private is None else [private]
4885
4969
  )
4886
4970
 
4887
- for search_scope in search_scopes:
4971
+ for search_private_status in search_private_statuses:
4888
4972
  secrets = self.list_secrets(
4889
4973
  logical_operator=LogicalOperators.AND,
4890
4974
  name=f"equals:{name}",
4891
- scope=search_scope,
4975
+ private=search_private_status,
4892
4976
  hydrate=hydrate,
4893
4977
  )
4894
4978
 
@@ -4898,33 +4982,34 @@ class Client(metaclass=ClientMetaClass):
4898
4982
  secret_id=secrets.items[0].id, hydrate=hydrate
4899
4983
  )
4900
4984
 
4901
- msg = f"No secret with name '{name}' was found"
4902
- if scope is not None:
4903
- 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"
4904
4989
 
4905
4990
  raise KeyError(msg)
4906
4991
 
4907
- def list_secrets_in_scope(
4992
+ def list_secrets_by_private_status(
4908
4993
  self,
4909
- scope: SecretScope,
4994
+ private: bool,
4910
4995
  hydrate: bool = False,
4911
4996
  ) -> Page[SecretResponse]:
4912
- """Fetches the list of secret in a given scope.
4997
+ """Fetches the list of secrets with a given private status.
4913
4998
 
4914
4999
  The returned secrets do not contain the secret values. To get the
4915
5000
  secret values, use `get_secret` individually for each secret.
4916
5001
 
4917
5002
  Args:
4918
- scope: The secrets scope to search for.
5003
+ private: The private status of the secrets to search for.
4919
5004
  hydrate: Flag deciding whether to hydrate the output model(s)
4920
5005
  by including metadata fields in the response.
4921
5006
 
4922
5007
  Returns:
4923
5008
  The list of secrets in the given scope without the secret values.
4924
5009
  """
4925
- logger.debug(f"Fetching the secrets in scope {scope.value}.")
5010
+ logger.debug(f"Fetching the secrets with private status '{private}'.")
4926
5011
 
4927
- return self.list_secrets(scope=scope, hydrate=hydrate)
5012
+ return self.list_secrets(private=private, hydrate=hydrate)
4928
5013
 
4929
5014
  def backup_secrets(
4930
5015
  self,
@@ -5015,7 +5100,6 @@ class Client(metaclass=ClientMetaClass):
5015
5100
  """
5016
5101
  self._validate_code_repository_config(source=source, config=config)
5017
5102
  repo_request = CodeRepositoryRequest(
5018
- user=self.active_user.id,
5019
5103
  workspace=self.active_workspace.id,
5020
5104
  name=name,
5021
5105
  config=config,
@@ -5031,6 +5115,7 @@ class Client(metaclass=ClientMetaClass):
5031
5115
  self,
5032
5116
  name_id_or_prefix: Union[str, UUID],
5033
5117
  allow_name_prefix_match: bool = True,
5118
+ workspace: Optional[Union[str, UUID]] = None,
5034
5119
  hydrate: bool = True,
5035
5120
  ) -> CodeRepositoryResponse:
5036
5121
  """Get a code repository by name, id or prefix.
@@ -5038,6 +5123,7 @@ class Client(metaclass=ClientMetaClass):
5038
5123
  Args:
5039
5124
  name_id_or_prefix: The name, ID or ID prefix of the code repository.
5040
5125
  allow_name_prefix_match: If True, allow matching by name prefix.
5126
+ workspace: The workspace name/ID to filter by.
5041
5127
  hydrate: Flag deciding whether to hydrate the output model(s)
5042
5128
  by including metadata fields in the response.
5043
5129
 
@@ -5050,6 +5136,7 @@ class Client(metaclass=ClientMetaClass):
5050
5136
  name_id_or_prefix=name_id_or_prefix,
5051
5137
  allow_name_prefix_match=allow_name_prefix_match,
5052
5138
  hydrate=hydrate,
5139
+ workspace=workspace,
5053
5140
  )
5054
5141
 
5055
5142
  def list_code_repositories(
@@ -5062,8 +5149,7 @@ class Client(metaclass=ClientMetaClass):
5062
5149
  created: Optional[Union[datetime, str]] = None,
5063
5150
  updated: Optional[Union[datetime, str]] = None,
5064
5151
  name: Optional[str] = None,
5065
- workspace_id: Optional[Union[str, UUID]] = None,
5066
- user_id: Optional[Union[str, UUID]] = None,
5152
+ workspace: Optional[Union[str, UUID]] = None,
5067
5153
  user: Optional[Union[UUID, str]] = None,
5068
5154
  hydrate: bool = False,
5069
5155
  ) -> Page[CodeRepositoryResponse]:
@@ -5078,8 +5164,7 @@ class Client(metaclass=ClientMetaClass):
5078
5164
  created: Use to filter by time of creation.
5079
5165
  updated: Use the last updated date for filtering.
5080
5166
  name: The name of the code repository to filter by.
5081
- workspace_id: The id of the workspace to filter by.
5082
- user_id: The id of the user to filter by.
5167
+ workspace: The workspace name/ID to filter by.
5083
5168
  user: Filter by user name/ID.
5084
5169
  hydrate: Flag deciding whether to hydrate the output model(s)
5085
5170
  by including metadata fields in the response.
@@ -5096,11 +5181,9 @@ class Client(metaclass=ClientMetaClass):
5096
5181
  created=created,
5097
5182
  updated=updated,
5098
5183
  name=name,
5099
- workspace_id=workspace_id,
5100
- user_id=user_id,
5184
+ workspace=workspace or self.active_workspace.id,
5101
5185
  user=user,
5102
5186
  )
5103
- filter_model.set_scope_workspace(self.active_workspace.id)
5104
5187
  return self.zen_store.list_code_repositories(
5105
5188
  filter_model=filter_model,
5106
5189
  hydrate=hydrate,
@@ -5113,6 +5196,7 @@ class Client(metaclass=ClientMetaClass):
5113
5196
  description: Optional[str] = None,
5114
5197
  logo_url: Optional[str] = None,
5115
5198
  config: Optional[Dict[str, Any]] = None,
5199
+ workspace: Optional[Union[str, UUID]] = None,
5116
5200
  ) -> CodeRepositoryResponse:
5117
5201
  """Update a code repository.
5118
5202
 
@@ -5126,12 +5210,15 @@ class Client(metaclass=ClientMetaClass):
5126
5210
  be used to update the existing configuration values. To remove
5127
5211
  values from the existing configuration, set the value for that
5128
5212
  key to `None`.
5213
+ workspace: The workspace name/ID to filter by.
5129
5214
 
5130
5215
  Returns:
5131
5216
  The updated code repository.
5132
5217
  """
5133
5218
  repo = self.get_code_repository(
5134
- 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,
5135
5222
  )
5136
5223
  update = CodeRepositoryUpdate(
5137
5224
  name=name, description=description, logo_url=logo_url
@@ -5155,14 +5242,18 @@ class Client(metaclass=ClientMetaClass):
5155
5242
  def delete_code_repository(
5156
5243
  self,
5157
5244
  name_id_or_prefix: Union[str, UUID],
5245
+ workspace: Optional[Union[str, UUID]] = None,
5158
5246
  ) -> None:
5159
5247
  """Delete a code repository.
5160
5248
 
5161
5249
  Args:
5162
5250
  name_id_or_prefix: The name, ID or prefix of the code repository.
5251
+ workspace: The workspace name/ID to filter by.
5163
5252
  """
5164
5253
  repo = self.get_code_repository(
5165
- 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,
5166
5257
  )
5167
5258
  self.zen_store.delete_code_repository(code_repository_id=repo.id)
5168
5259
 
@@ -5279,7 +5370,6 @@ class Client(metaclass=ClientMetaClass):
5279
5370
  assert connector_instance is not None
5280
5371
  connector_request = connector_instance.to_model(
5281
5372
  name=name,
5282
- user=self.active_user.id,
5283
5373
  workspace=self.active_workspace.id,
5284
5374
  description=description or "",
5285
5375
  labels=labels,
@@ -5327,7 +5417,6 @@ class Client(metaclass=ClientMetaClass):
5327
5417
  expiration_seconds=expiration_seconds,
5328
5418
  expires_at=expires_at,
5329
5419
  expires_skew_tolerance=expires_skew_tolerance,
5330
- user=self.active_user.id,
5331
5420
  workspace=self.active_workspace.id,
5332
5421
  labels=labels or {},
5333
5422
  )
@@ -5410,32 +5499,9 @@ class Client(metaclass=ClientMetaClass):
5410
5499
  Returns:
5411
5500
  The registered service connector.
5412
5501
  """
5413
-
5414
- def scoped_list_method(
5415
- hydrate: bool = False,
5416
- **kwargs: Any,
5417
- ) -> Page[ServiceConnectorResponse]:
5418
- """Call `zen_store.list_service_connectors` with workspace scoping.
5419
-
5420
- Args:
5421
- hydrate: Flag deciding whether to hydrate the output model(s)
5422
- by including metadata fields in the response.
5423
- **kwargs: Keyword arguments to pass to
5424
- `ServiceConnectorFilterModel`.
5425
-
5426
- Returns:
5427
- The list of service connectors.
5428
- """
5429
- filter_model = ServiceConnectorFilter(**kwargs)
5430
- filter_model.set_scope_workspace(self.active_workspace.id)
5431
- return self.zen_store.list_service_connectors(
5432
- filter_model=filter_model,
5433
- hydrate=hydrate,
5434
- )
5435
-
5436
5502
  connector = self._get_entity_by_id_or_name_or_prefix(
5437
5503
  get_method=self.zen_store.get_service_connector,
5438
- list_method=scoped_list_method,
5504
+ list_method=self.list_service_connectors,
5439
5505
  name_id_or_prefix=name_id_or_prefix,
5440
5506
  allow_name_prefix_match=allow_name_prefix_match,
5441
5507
  hydrate=hydrate,
@@ -5474,8 +5540,6 @@ class Client(metaclass=ClientMetaClass):
5474
5540
  auth_method: Optional[str] = None,
5475
5541
  resource_type: Optional[str] = None,
5476
5542
  resource_id: Optional[str] = None,
5477
- workspace_id: Optional[Union[str, UUID]] = None,
5478
- user_id: Optional[Union[str, UUID]] = None,
5479
5543
  user: Optional[Union[UUID, str]] = None,
5480
5544
  labels: Optional[Dict[str, Optional[str]]] = None,
5481
5545
  secret_id: Optional[Union[str, UUID]] = None,
@@ -5497,8 +5561,6 @@ class Client(metaclass=ClientMetaClass):
5497
5561
  they can give access to.
5498
5562
  resource_id: Filter service connectors by the resource id that
5499
5563
  they can give access to.
5500
- workspace_id: The id of the workspace to filter by.
5501
- user_id: The id of the user to filter by.
5502
5564
  user: Filter by user name/ID.
5503
5565
  name: The name of the service connector to filter by.
5504
5566
  labels: The labels of the service connector to filter by.
@@ -5515,8 +5577,6 @@ class Client(metaclass=ClientMetaClass):
5515
5577
  size=size,
5516
5578
  sort_by=sort_by,
5517
5579
  logical_operator=logical_operator,
5518
- workspace_id=workspace_id or self.active_workspace.id,
5519
- user_id=user_id,
5520
5580
  user=user,
5521
5581
  name=name,
5522
5582
  connector_type=connector_type,
@@ -5529,7 +5589,6 @@ class Client(metaclass=ClientMetaClass):
5529
5589
  labels=labels,
5530
5590
  secret_id=secret_id,
5531
5591
  )
5532
- connector_filter_model.set_scope_workspace(self.active_workspace.id)
5533
5592
  return self.zen_store.list_service_connectors(
5534
5593
  filter_model=connector_filter_model,
5535
5594
  hydrate=hydrate,
@@ -5708,7 +5767,6 @@ class Client(metaclass=ClientMetaClass):
5708
5767
  # Convert the update model to a request model for validation
5709
5768
  connector_request_dict = connector_update.model_dump()
5710
5769
  connector_request_dict.update(
5711
- user=self.active_user.id,
5712
5770
  workspace=self.active_workspace.id,
5713
5771
  )
5714
5772
  connector_request = ServiceConnectorRequest.model_validate(
@@ -5982,6 +6040,7 @@ class Client(metaclass=ClientMetaClass):
5982
6040
  connector_type: Optional[str] = None,
5983
6041
  resource_type: Optional[str] = None,
5984
6042
  resource_id: Optional[str] = None,
6043
+ workspace_id: Optional[UUID] = None,
5985
6044
  ) -> List[ServiceConnectorResourcesModel]:
5986
6045
  """List resources that can be accessed by service connectors.
5987
6046
 
@@ -5989,16 +6048,20 @@ class Client(metaclass=ClientMetaClass):
5989
6048
  connector_type: The type of service connector to filter by.
5990
6049
  resource_type: The type of resource to filter by.
5991
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.
5992
6053
 
5993
6054
  Returns:
5994
6055
  The matching list of resources that available service
5995
6056
  connectors have access to.
5996
6057
  """
5997
6058
  return self.zen_store.list_service_connector_resources(
5998
- workspace_name_or_id=self.active_workspace.id,
5999
- connector_type=connector_type,
6000
- resource_type=resource_type,
6001
- 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
+ )
6002
6065
  )
6003
6066
 
6004
6067
  def list_service_connector_types(
@@ -6085,19 +6148,26 @@ class Client(metaclass=ClientMetaClass):
6085
6148
  trade_offs=trade_offs,
6086
6149
  ethics=ethics,
6087
6150
  tags=tags,
6088
- user=self.active_user.id,
6089
6151
  workspace=self.active_workspace.id,
6090
6152
  save_models_to_registry=save_models_to_registry,
6091
6153
  )
6092
6154
  )
6093
6155
 
6094
- 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:
6095
6161
  """Deletes a model from Model Control Plane.
6096
6162
 
6097
6163
  Args:
6098
6164
  model_name_or_id: name or id of the model to be deleted.
6165
+ workspace: The workspace name/ID to filter by.
6099
6166
  """
6100
- 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)
6101
6171
 
6102
6172
  def update_model(
6103
6173
  self,
@@ -6113,6 +6183,7 @@ class Client(metaclass=ClientMetaClass):
6113
6183
  add_tags: Optional[List[str]] = None,
6114
6184
  remove_tags: Optional[List[str]] = None,
6115
6185
  save_models_to_registry: Optional[bool] = None,
6186
+ workspace: Optional[Union[str, UUID]] = None,
6116
6187
  ) -> ModelResponse:
6117
6188
  """Updates an existing model in Model Control Plane.
6118
6189
 
@@ -6130,14 +6201,16 @@ class Client(metaclass=ClientMetaClass):
6130
6201
  remove_tags: Tags to remove from to the model.
6131
6202
  save_models_to_registry: Whether to save the model to the
6132
6203
  registry.
6204
+ workspace: The workspace name/ID to filter by.
6133
6205
 
6134
6206
  Returns:
6135
6207
  The updated model.
6136
6208
  """
6137
- if not is_valid_uuid(model_name_or_id):
6138
- 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
+ )
6139
6212
  return self.zen_store.update_model(
6140
- model_id=model_name_or_id, # type:ignore[arg-type]
6213
+ model_id=model.id,
6141
6214
  model_update=ModelUpdate(
6142
6215
  name=name,
6143
6216
  license=license,
@@ -6156,24 +6229,36 @@ class Client(metaclass=ClientMetaClass):
6156
6229
  def get_model(
6157
6230
  self,
6158
6231
  model_name_or_id: Union[str, UUID],
6232
+ workspace: Optional[Union[str, UUID]] = None,
6159
6233
  hydrate: bool = True,
6234
+ bypass_lazy_loader: bool = False,
6160
6235
  ) -> ModelResponse:
6161
6236
  """Get an existing model from Model Control Plane.
6162
6237
 
6163
6238
  Args:
6164
6239
  model_name_or_id: name or id of the model to be retrieved.
6240
+ workspace: The workspace name/ID to filter by.
6165
6241
  hydrate: Flag deciding whether to hydrate the output model(s)
6166
6242
  by including metadata fields in the response.
6243
+ bypass_lazy_loader: Whether to bypass the lazy loader.
6167
6244
 
6168
6245
  Returns:
6169
6246
  The model of interest.
6170
6247
  """
6171
- if cll := client_lazy_loader(
6172
- "get_model", model_name_or_id=model_name_or_id, hydrate=hydrate
6173
- ):
6174
- return cll # type: ignore[return-value]
6175
- return self.zen_store.get_model(
6176
- 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,
6177
6262
  hydrate=hydrate,
6178
6263
  )
6179
6264
 
@@ -6186,9 +6271,12 @@ class Client(metaclass=ClientMetaClass):
6186
6271
  created: Optional[Union[datetime, str]] = None,
6187
6272
  updated: Optional[Union[datetime, str]] = None,
6188
6273
  name: Optional[str] = None,
6274
+ id: Optional[Union[UUID, str]] = None,
6189
6275
  user: Optional[Union[UUID, str]] = None,
6276
+ workspace: Optional[Union[str, UUID]] = None,
6190
6277
  hydrate: bool = False,
6191
6278
  tag: Optional[str] = None,
6279
+ tags: Optional[List[str]] = None,
6192
6280
  ) -> Page[ModelResponse]:
6193
6281
  """Get models by filter from Model Control Plane.
6194
6282
 
@@ -6200,16 +6288,20 @@ class Client(metaclass=ClientMetaClass):
6200
6288
  created: Use to filter by time of creation
6201
6289
  updated: Use the last updated date for filtering
6202
6290
  name: The name of the model to filter by.
6291
+ id: The id of the model to filter by.
6203
6292
  user: Filter by user name/ID.
6293
+ workspace: The workspace name/ID to filter by.
6204
6294
  hydrate: Flag deciding whether to hydrate the output model(s)
6205
6295
  by including metadata fields in the response.
6206
6296
  tag: The tag of the model to filter by.
6297
+ tags: Tags to filter by.
6207
6298
 
6208
6299
  Returns:
6209
6300
  A page object with all models.
6210
6301
  """
6211
6302
  filter = ModelFilter(
6212
6303
  name=name,
6304
+ id=id,
6213
6305
  sort_by=sort_by,
6214
6306
  page=page,
6215
6307
  size=size,
@@ -6217,7 +6309,9 @@ class Client(metaclass=ClientMetaClass):
6217
6309
  created=created,
6218
6310
  updated=updated,
6219
6311
  tag=tag,
6312
+ tags=tags,
6220
6313
  user=user,
6314
+ workspace=workspace or self.active_workspace.id,
6221
6315
  )
6222
6316
 
6223
6317
  return self.zen_store.list_models(
@@ -6234,6 +6328,7 @@ class Client(metaclass=ClientMetaClass):
6234
6328
  name: Optional[str] = None,
6235
6329
  description: Optional[str] = None,
6236
6330
  tags: Optional[List[str]] = None,
6331
+ workspace: Optional[Union[str, UUID]] = None,
6237
6332
  ) -> ModelVersionResponse:
6238
6333
  """Creates a new model version in Model Control Plane.
6239
6334
 
@@ -6243,19 +6338,20 @@ class Client(metaclass=ClientMetaClass):
6243
6338
  name: the name of the Model Version to be created.
6244
6339
  description: the description of the Model Version to be created.
6245
6340
  tags: Tags associated with the model.
6341
+ workspace: The workspace name/ID to filter by.
6246
6342
 
6247
6343
  Returns:
6248
6344
  The newly created model version.
6249
6345
  """
6250
- if not is_valid_uuid(model_name_or_id):
6251
- 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
+ )
6252
6349
  return self.zen_store.create_model_version(
6253
6350
  model_version=ModelVersionRequest(
6254
6351
  name=name,
6255
6352
  description=description,
6256
- user=self.active_user.id,
6257
- workspace=self.active_workspace.id,
6258
- model=model_name_or_id,
6353
+ workspace=workspace or self.active_workspace.id,
6354
+ model=model.id,
6259
6355
  tags=tags,
6260
6356
  )
6261
6357
  )
@@ -6279,6 +6375,7 @@ class Client(metaclass=ClientMetaClass):
6279
6375
  model_version_name_or_number_or_id: Optional[
6280
6376
  Union[str, int, ModelStages, UUID]
6281
6377
  ] = None,
6378
+ workspace: Optional[Union[str, UUID]] = None,
6282
6379
  hydrate: bool = True,
6283
6380
  ) -> ModelVersionResponse:
6284
6381
  """Get an existing model version from Model Control Plane.
@@ -6289,6 +6386,7 @@ class Client(metaclass=ClientMetaClass):
6289
6386
  model_version_name_or_number_or_id: name, id, stage or number of
6290
6387
  the model version to be retrieved. If skipped - latest version
6291
6388
  is retrieved.
6389
+ workspace: The workspace name/ID to filter by.
6292
6390
  hydrate: Flag deciding whether to hydrate the output model(s)
6293
6391
  by including metadata fields in the response.
6294
6392
 
@@ -6313,6 +6411,7 @@ class Client(metaclass=ClientMetaClass):
6313
6411
  "get_model_version",
6314
6412
  model_name_or_id=model_name_or_id,
6315
6413
  model_version_name_or_number_or_id=model_version_name_or_number_or_id,
6414
+ workspace=workspace,
6316
6415
  hydrate=hydrate,
6317
6416
  ):
6318
6417
  return cll # type: ignore[return-value]
@@ -6327,18 +6426,20 @@ class Client(metaclass=ClientMetaClass):
6327
6426
  )
6328
6427
  elif isinstance(model_version_name_or_number_or_id, int):
6329
6428
  model_versions = self.zen_store.list_model_versions(
6330
- model_name_or_id=model_name_or_id,
6331
6429
  model_version_filter_model=ModelVersionFilter(
6430
+ model=model_name_or_id,
6332
6431
  number=model_version_name_or_number_or_id,
6432
+ workspace=workspace or self.active_workspace.id,
6333
6433
  ),
6334
6434
  hydrate=hydrate,
6335
6435
  ).items
6336
6436
  elif isinstance(model_version_name_or_number_or_id, str):
6337
6437
  if model_version_name_or_number_or_id == ModelStages.LATEST:
6338
6438
  model_versions = self.zen_store.list_model_versions(
6339
- model_name_or_id=model_name_or_id,
6340
6439
  model_version_filter_model=ModelVersionFilter(
6341
- 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,
6342
6443
  ),
6343
6444
  hydrate=hydrate,
6344
6445
  ).items
@@ -6349,17 +6450,19 @@ class Client(metaclass=ClientMetaClass):
6349
6450
  model_versions = []
6350
6451
  elif model_version_name_or_number_or_id in ModelStages.values():
6351
6452
  model_versions = self.zen_store.list_model_versions(
6352
- model_name_or_id=model_name_or_id,
6353
6453
  model_version_filter_model=ModelVersionFilter(
6354
- 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,
6355
6457
  ),
6356
6458
  hydrate=hydrate,
6357
6459
  ).items
6358
6460
  else:
6359
6461
  model_versions = self.zen_store.list_model_versions(
6360
- model_name_or_id=model_name_or_id,
6361
6462
  model_version_filter_model=ModelVersionFilter(
6362
- 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,
6363
6466
  ),
6364
6467
  hydrate=hydrate,
6365
6468
  ).items
@@ -6387,7 +6490,7 @@ class Client(metaclass=ClientMetaClass):
6387
6490
 
6388
6491
  def list_model_versions(
6389
6492
  self,
6390
- model_name_or_id: Optional[Union[str, UUID]] = None,
6493
+ model_name_or_id: Union[str, UUID],
6391
6494
  sort_by: str = "number",
6392
6495
  page: int = PAGINATION_STARTING_PAGE,
6393
6496
  size: int = PAGE_SIZE_DEFAULT,
@@ -6395,11 +6498,15 @@ class Client(metaclass=ClientMetaClass):
6395
6498
  created: Optional[Union[datetime, str]] = None,
6396
6499
  updated: Optional[Union[datetime, str]] = None,
6397
6500
  name: Optional[str] = None,
6501
+ id: Optional[Union[UUID, str]] = None,
6398
6502
  number: Optional[int] = None,
6399
6503
  stage: Optional[Union[str, ModelStages]] = None,
6504
+ run_metadata: Optional[Dict[str, str]] = None,
6400
6505
  user: Optional[Union[UUID, str]] = None,
6401
6506
  hydrate: bool = False,
6402
6507
  tag: Optional[str] = None,
6508
+ tags: Optional[List[str]] = None,
6509
+ workspace: Optional[Union[str, UUID]] = None,
6403
6510
  ) -> Page[ModelVersionResponse]:
6404
6511
  """Get model versions by filter from Model Control Plane.
6405
6512
 
@@ -6413,12 +6520,16 @@ class Client(metaclass=ClientMetaClass):
6413
6520
  created: Use to filter by time of creation
6414
6521
  updated: Use the last updated date for filtering
6415
6522
  name: name or id of the model version.
6523
+ id: id of the model version.
6416
6524
  number: number of the model version.
6417
6525
  stage: stage of the model version.
6526
+ run_metadata: run metadata of the model version.
6418
6527
  user: Filter by user name/ID.
6419
6528
  hydrate: Flag deciding whether to hydrate the output model(s)
6420
6529
  by including metadata fields in the response.
6421
6530
  tag: The tag to filter by.
6531
+ tags: Tags to filter by.
6532
+ workspace: The workspace name/ID to filter by.
6422
6533
 
6423
6534
  Returns:
6424
6535
  A page object with all model versions.
@@ -6431,14 +6542,18 @@ class Client(metaclass=ClientMetaClass):
6431
6542
  created=created,
6432
6543
  updated=updated,
6433
6544
  name=name,
6545
+ id=id,
6434
6546
  number=number,
6435
6547
  stage=stage,
6548
+ run_metadata=run_metadata,
6436
6549
  tag=tag,
6550
+ tags=tags,
6437
6551
  user=user,
6552
+ model=model_name_or_id,
6553
+ workspace=workspace or self.active_workspace.id,
6438
6554
  )
6439
6555
 
6440
6556
  return self.zen_store.list_model_versions(
6441
- model_name_or_id=model_name_or_id,
6442
6557
  model_version_filter_model=model_version_filter_model,
6443
6558
  hydrate=hydrate,
6444
6559
  )
@@ -6453,6 +6568,7 @@ class Client(metaclass=ClientMetaClass):
6453
6568
  description: Optional[str] = None,
6454
6569
  add_tags: Optional[List[str]] = None,
6455
6570
  remove_tags: Optional[List[str]] = None,
6571
+ workspace: Optional[Union[str, UUID]] = None,
6456
6572
  ) -> ModelVersionResponse:
6457
6573
  """Get all model versions by filter.
6458
6574
 
@@ -6466,21 +6582,23 @@ class Client(metaclass=ClientMetaClass):
6466
6582
  description: Target model version description to be set.
6467
6583
  add_tags: Tags to add to the model version.
6468
6584
  remove_tags: Tags to remove from to the model version.
6585
+ workspace: The workspace name/ID to filter by.
6469
6586
 
6470
6587
  Returns:
6471
6588
  An updated model version.
6472
6589
  """
6473
6590
  if not is_valid_uuid(model_name_or_id):
6474
- 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
6475
6594
  if not is_valid_uuid(version_name_or_id):
6476
6595
  version_name_or_id = self.get_model_version(
6477
- model_name_or_id, version_name_or_id
6596
+ model_name_or_id, version_name_or_id, workspace=workspace
6478
6597
  ).id
6479
6598
 
6480
6599
  return self.zen_store.update_model_version(
6481
6600
  model_version_id=version_name_or_id, # type:ignore[arg-type]
6482
6601
  model_version_update_model=ModelVersionUpdate(
6483
- model=model_name_or_id,
6484
6602
  stage=stage,
6485
6603
  force=force,
6486
6604
  name=name,
@@ -6829,6 +6947,7 @@ class Client(metaclass=ClientMetaClass):
6829
6947
  logical_operator: LogicalOperators = LogicalOperators.AND,
6830
6948
  trigger_id: Optional[UUID] = None,
6831
6949
  user: Optional[Union[UUID, str]] = None,
6950
+ workspace: Optional[Union[UUID, str]] = None,
6832
6951
  hydrate: bool = False,
6833
6952
  ) -> Page[TriggerExecutionResponse]:
6834
6953
  """List all trigger executions matching the given filter criteria.
@@ -6840,6 +6959,7 @@ class Client(metaclass=ClientMetaClass):
6840
6959
  logical_operator: Which logical operator to use [and, or].
6841
6960
  trigger_id: ID of the trigger to filter by.
6842
6961
  user: Filter by user name/ID.
6962
+ workspace: Filter by workspace name/ID.
6843
6963
  hydrate: Flag deciding whether to hydrate the output model(s)
6844
6964
  by including metadata fields in the response.
6845
6965
 
@@ -6853,8 +6973,8 @@ class Client(metaclass=ClientMetaClass):
6853
6973
  size=size,
6854
6974
  user=user,
6855
6975
  logical_operator=logical_operator,
6976
+ workspace=workspace or self.active_workspace.id,
6856
6977
  )
6857
- filter_model.set_scope_workspace(self.active_workspace.id)
6858
6978
  return self.zen_store.list_trigger_executions(
6859
6979
  trigger_execution_filter_model=filter_model, hydrate=hydrate
6860
6980
  )
@@ -6877,6 +6997,7 @@ class Client(metaclass=ClientMetaClass):
6877
6997
  list_method: Callable[..., Page[AnyResponse]],
6878
6998
  name_id_or_prefix: Union[str, UUID],
6879
6999
  allow_name_prefix_match: bool = True,
7000
+ workspace: Optional[Union[str, UUID]] = None,
6880
7001
  hydrate: bool = True,
6881
7002
  ) -> AnyResponse:
6882
7003
  """Fetches an entity using the id, name, or partial id/name.
@@ -6889,6 +7010,7 @@ class Client(metaclass=ClientMetaClass):
6889
7010
  allow_name_prefix_match: If True, allow matching by name prefix.
6890
7011
  hydrate: Flag deciding whether to hydrate the output model(s)
6891
7012
  by including metadata fields in the response.
7013
+ workspace: The workspace name/ID to filter by.
6892
7014
 
6893
7015
  Returns:
6894
7016
  The entity with the given name, id or partial id.
@@ -6907,10 +7029,15 @@ class Client(metaclass=ClientMetaClass):
6907
7029
 
6908
7030
  # If not a UUID, try to find by name
6909
7031
  assert not isinstance(name_id_or_prefix, UUID)
6910
- entity = list_method(
7032
+ list_kwargs: Dict[str, Any] = dict(
6911
7033
  name=f"equals:{name_id_or_prefix}",
6912
7034
  hydrate=hydrate,
6913
7035
  )
7036
+ scope = ""
7037
+ if workspace:
7038
+ scope = f"in workspace {workspace} "
7039
+ list_kwargs["workspace"] = workspace
7040
+ entity = list_method(**list_kwargs)
6914
7041
 
6915
7042
  # If only a single entity is found, return it
6916
7043
  if entity.total == 1:
@@ -6923,6 +7050,7 @@ class Client(metaclass=ClientMetaClass):
6923
7050
  list_method=list_method,
6924
7051
  partial_id_or_name=name_id_or_prefix,
6925
7052
  allow_name_prefix_match=allow_name_prefix_match,
7053
+ workspace=workspace,
6926
7054
  hydrate=hydrate,
6927
7055
  )
6928
7056
 
@@ -6934,7 +7062,7 @@ class Client(metaclass=ClientMetaClass):
6934
7062
  for item in entity.items
6935
7063
  ]
6936
7064
  raise ZenKeyError(
6937
- f"{entity.total} {entity_label} have been found that have "
7065
+ f"{entity.total} {entity_label} have been found {scope}that have "
6938
7066
  f"a name that matches the provided "
6939
7067
  f"string '{name_id_or_prefix}':\n"
6940
7068
  f"{formatted_entity_items}.\n"
@@ -6948,6 +7076,7 @@ class Client(metaclass=ClientMetaClass):
6948
7076
  list_method: Callable[..., Page[AnyResponse]],
6949
7077
  name_id_or_prefix: Union[str, UUID],
6950
7078
  version: Optional[str],
7079
+ workspace: Optional[Union[str, UUID]] = None,
6951
7080
  hydrate: bool = True,
6952
7081
  ) -> "AnyResponse":
6953
7082
  from zenml.utils.uuid_utils import is_valid_uuid
@@ -6967,13 +7096,18 @@ class Client(metaclass=ClientMetaClass):
6967
7096
  return get_method(name_id_or_prefix, hydrate=hydrate)
6968
7097
 
6969
7098
  assert not isinstance(name_id_or_prefix, UUID)
6970
- exact_name_matches = list_method(
7099
+ list_kwargs: Dict[str, Any] = dict(
6971
7100
  size=1,
6972
7101
  sort_by="desc:created",
6973
7102
  name=name_id_or_prefix,
6974
7103
  version=version,
6975
7104
  hydrate=hydrate,
6976
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)
6977
7111
 
6978
7112
  if len(exact_name_matches) == 1:
6979
7113
  # If the name matches exactly, use the explicitly specified version
@@ -6995,13 +7129,13 @@ class Client(metaclass=ClientMetaClass):
6995
7129
  elif partial_id_matches.total == 0:
6996
7130
  raise KeyError(
6997
7131
  f"No {entity_label} found for name, ID or prefix "
6998
- f"{name_id_or_prefix}."
7132
+ f"{name_id_or_prefix}{scope}."
6999
7133
  )
7000
7134
  else:
7001
7135
  raise ZenKeyError(
7002
- f"{partial_id_matches.total} {entity_label} have been found "
7003
- "that have an id prefix that matches the provided string "
7004
- 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"
7005
7139
  f"{partial_id_matches.items}.\n"
7006
7140
  f"Please provide more characters to uniquely identify "
7007
7141
  f"only one of the {entity_label}s."
@@ -7013,6 +7147,7 @@ class Client(metaclass=ClientMetaClass):
7013
7147
  list_method: Callable[..., Page[AnyResponse]],
7014
7148
  partial_id_or_name: str,
7015
7149
  allow_name_prefix_match: bool,
7150
+ workspace: Optional[Union[str, UUID]] = None,
7016
7151
  hydrate: bool = True,
7017
7152
  ) -> AnyResponse:
7018
7153
  """Fetches an entity using a partial ID or name.
@@ -7024,6 +7159,7 @@ class Client(metaclass=ClientMetaClass):
7024
7159
  allow_name_prefix_match: If True, allow matching by name prefix.
7025
7160
  hydrate: Flag deciding whether to hydrate the output model(s)
7026
7161
  by including metadata fields in the response.
7162
+ workspace: The workspace name/ID to filter by.
7027
7163
 
7028
7164
  Returns:
7029
7165
  The entity with the given partial ID or name.
@@ -7040,6 +7176,10 @@ class Client(metaclass=ClientMetaClass):
7040
7176
  }
7041
7177
  if allow_name_prefix_match:
7042
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
7043
7183
 
7044
7184
  entity = list_method(**list_method_args)
7045
7185
 
@@ -7059,7 +7199,7 @@ class Client(metaclass=ClientMetaClass):
7059
7199
  # If no entity is found, raise an error.
7060
7200
  if entity.total == 0:
7061
7201
  raise KeyError(
7062
- f"No {entity_label} have been found that have "
7202
+ f"No {entity_label} have been found{scope} that have "
7063
7203
  f"{prefix_description} that matches the provided string "
7064
7204
  f"'{partial_id_or_name}'."
7065
7205
  )
@@ -7073,7 +7213,7 @@ class Client(metaclass=ClientMetaClass):
7073
7213
  else:
7074
7214
  ambiguous_entities.append(str(model.id))
7075
7215
  raise ZenKeyError(
7076
- f"{entity.total} {entity_label} have been found that have "
7216
+ f"{entity.total} {entity_label} have been found{scope} that have "
7077
7217
  f"{prefix_description} that matches the provided "
7078
7218
  f"string '{partial_id_or_name}':\n"
7079
7219
  f"{ambiguous_entities}.\n"
@@ -7508,57 +7648,97 @@ class Client(metaclass=ClientMetaClass):
7508
7648
  api_key_name_or_id=api_key.id,
7509
7649
  )
7510
7650
 
7511
- #############################################
7512
- # Tags
7513
- #
7514
- # Note: tag<>resource are not exposed and
7515
- # can be accessed via relevant resources
7516
- #############################################
7517
-
7518
- 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:
7519
7658
  """Creates a new tag.
7520
7659
 
7521
7660
  Args:
7522
- 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
7523
7668
 
7524
7669
  Returns:
7525
7670
  The newly created tag.
7526
7671
  """
7527
- 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)
7528
7678
 
7529
- 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:
7530
7683
  """Deletes a tag.
7531
7684
 
7532
7685
  Args:
7533
7686
  tag_name_or_id: name or id of the tag to be deleted.
7534
7687
  """
7535
- 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
+ )
7536
7691
 
7537
7692
  def update_tag(
7538
7693
  self,
7539
7694
  tag_name_or_id: Union[str, UUID],
7540
- tag_update_model: TagUpdate,
7695
+ name: Optional[str] = None,
7696
+ exclusive: Optional[bool] = None,
7697
+ color: Optional[Union[str, ColorVariants]] = None,
7541
7698
  ) -> TagResponse:
7542
7699
  """Updates an existing tag.
7543
7700
 
7544
7701
  Args:
7545
7702
  tag_name_or_id: name or UUID of the tag to be updated.
7546
- 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
7547
7710
 
7548
7711
  Returns:
7549
7712
  The updated tag.
7550
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
+
7551
7728
  return self.zen_store.update_tag(
7552
- 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,
7553
7731
  )
7554
7732
 
7555
7733
  def get_tag(
7556
- 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,
7557
7737
  ) -> TagResponse:
7558
7738
  """Get an existing tag.
7559
7739
 
7560
7740
  Args:
7561
- 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.
7562
7742
  hydrate: Flag deciding whether to hydrate the output model(s)
7563
7743
  by including metadata fields in the response.
7564
7744
 
@@ -7566,19 +7746,39 @@ class Client(metaclass=ClientMetaClass):
7566
7746
  The tag of interest.
7567
7747
  """
7568
7748
  return self.zen_store.get_tag(
7569
- tag_name_or_id=tag_name_or_id, hydrate=hydrate
7749
+ tag_name_or_id=tag_name_or_id,
7750
+ hydrate=hydrate,
7570
7751
  )
7571
7752
 
7572
7753
  def list_tags(
7573
7754
  self,
7574
- 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,
7575
7766
  hydrate: bool = False,
7576
7767
  ) -> Page[TagResponse]:
7577
7768
  """Get tags by filter.
7578
7769
 
7579
7770
  Args:
7580
- tag_filter_model: All filter parameters including pagination
7581
- 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.
7582
7782
  hydrate: Flag deciding whether to hydrate the output model(s)
7583
7783
  by including metadata fields in the response.
7584
7784
 
@@ -7586,5 +7786,72 @@ class Client(metaclass=ClientMetaClass):
7586
7786
  A page of all tags.
7587
7787
  """
7588
7788
  return self.zen_store.list_tags(
7589
- 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
+ ]
7590
7857
  )