databricks-sdk 0.154.0__tar.gz → 0.155.0__tar.gz

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 (116) hide show
  1. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/CHANGELOG.md +11 -0
  2. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/PKG-INFO +1 -1
  3. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/config.py +5 -0
  4. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/files.py +175 -14
  5. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/billing.py +27 -6
  6. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/bundledeployments.py +7 -6
  7. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/catalog.py +29 -15
  8. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/ml.py +108 -0
  9. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/pipelines.py +2 -2
  10. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/sharing.py +1 -48
  11. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/sql.py +126 -0
  12. databricks_sdk-0.155.0/databricks/sdk/version.py +1 -0
  13. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks_sdk.egg-info/PKG-INFO +1 -1
  14. databricks_sdk-0.154.0/databricks/sdk/version.py +0 -1
  15. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/CONTRIBUTING.md +0 -0
  16. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/DCO +0 -0
  17. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/LICENSE +0 -0
  18. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/MANIFEST.in +0 -0
  19. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/Makefile +0 -0
  20. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/NOTICE +0 -0
  21. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/README.md +0 -0
  22. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/SECURITY.md +0 -0
  23. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/__init__.py +0 -0
  24. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/__init__.py +0 -0
  25. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_base_client.py +0 -0
  26. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_property.py +0 -0
  27. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_sandbox_grpc/__init__.py +0 -0
  28. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_sandbox_grpc/sandbox_service_pb2.py +0 -0
  29. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_sandbox_grpc/sandbox_service_pb2_grpc.py +0 -0
  30. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_widgets/__init__.py +0 -0
  31. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_widgets/default_widgets_utils.py +0 -0
  32. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/_widgets/ipywidgets_utils.py +0 -0
  33. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/azure.py +0 -0
  34. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/casing.py +0 -0
  35. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/client_types.py +0 -0
  36. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/clock.py +0 -0
  37. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/common/lro.py +0 -0
  38. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/common/types/__init__.py +0 -0
  39. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/common/types/fieldmask.py +0 -0
  40. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/core.py +0 -0
  41. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/credentials_provider.py +0 -0
  42. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/data_plane.py +0 -0
  43. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/dbutils.py +0 -0
  44. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/environments.py +0 -0
  45. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/__init__.py +0 -0
  46. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/base.py +0 -0
  47. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/customizer.py +0 -0
  48. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/deserializer.py +0 -0
  49. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/details.py +0 -0
  50. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/mapper.py +0 -0
  51. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/overrides.py +0 -0
  52. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/parser.py +0 -0
  53. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/platform.py +0 -0
  54. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/private_link.py +0 -0
  55. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/errors/sdk.py +0 -0
  56. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/logger/__init__.py +0 -0
  57. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/logger/round_trip_logger.py +0 -0
  58. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/__init__.py +0 -0
  59. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/_grpc_transport.py +0 -0
  60. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/compute.py +0 -0
  61. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/files_utils.py +0 -0
  62. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/jobs.py +0 -0
  63. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/open_ai_client.py +0 -0
  64. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/sandbox.py +0 -0
  65. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/sharing.py +0 -0
  66. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/mixins/workspace.py +0 -0
  67. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/oauth.py +0 -0
  68. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/oidc.py +0 -0
  69. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/oidc_token_supplier.py +0 -0
  70. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/py.typed +0 -0
  71. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/retries.py +0 -0
  72. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/runtime/__init__.py +0 -0
  73. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/runtime/dbutils_stub.py +0 -0
  74. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/__init__.py +0 -0
  75. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/_internal.py +0 -0
  76. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/agentbricks.py +0 -0
  77. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/agentkit.py +0 -0
  78. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/aifunctions.py +0 -0
  79. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/aisearch.py +0 -0
  80. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/apps.py +0 -0
  81. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/bundle.py +0 -0
  82. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/cleanrooms.py +0 -0
  83. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/compute.py +0 -0
  84. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/dashboards.py +0 -0
  85. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/database.py +0 -0
  86. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/dataclassification.py +0 -0
  87. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/dataquality.py +0 -0
  88. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/disasterrecovery.py +0 -0
  89. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/domains.py +0 -0
  90. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/environments.py +0 -0
  91. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/files.py +0 -0
  92. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/iam.py +0 -0
  93. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/iamv2.py +0 -0
  94. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/jobs.py +0 -0
  95. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/knowledgeassistants.py +0 -0
  96. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/marketplace.py +0 -0
  97. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/networking.py +0 -0
  98. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/oauth2.py +0 -0
  99. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/postgres.py +0 -0
  100. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/provisioning.py +0 -0
  101. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/qualitymonitorv2.py +0 -0
  102. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/sandbox.py +0 -0
  103. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/serving.py +0 -0
  104. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/settings.py +0 -0
  105. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/settingsv2.py +0 -0
  106. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/supervisoragents.py +0 -0
  107. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/tags.py +0 -0
  108. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/vectorsearch.py +0 -0
  109. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/service/workspace.py +0 -0
  110. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks/sdk/useragent.py +0 -0
  111. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks_sdk.egg-info/SOURCES.txt +0 -0
  112. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks_sdk.egg-info/dependency_links.txt +0 -0
  113. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks_sdk.egg-info/requires.txt +0 -0
  114. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/databricks_sdk.egg-info/top_level.txt +0 -0
  115. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/pyproject.toml +0 -0
  116. {databricks_sdk-0.154.0 → databricks_sdk-0.155.0}/setup.cfg +0 -0
@@ -1,5 +1,16 @@
1
1
  # Version changelog
2
2
 
3
+ ## Release v0.155.0 (2026-10-21)
4
+
5
+ ### API Changes
6
+ * Add `sdp_source` field for `databricks.sdk.service.ml.DataSource`.
7
+ * Add `customer_version_label`, `max_dbu` and `reyden_cluster_size_multiplier` fields for `databricks.sdk.service.sql.CreateWarehouseRequest`.
8
+ * Add `customer_version_label`, `max_dbu` and `reyden_cluster_size_multiplier` fields for `databricks.sdk.service.sql.EditWarehouseRequest`.
9
+ * Add `customer_version_label`, `max_dbu` and `reyden_cluster_size_multiplier` fields for `databricks.sdk.service.sql.EndpointInfo`.
10
+ * Add `customer_version_label`, `max_dbu` and `reyden_cluster_size_multiplier` fields for `databricks.sdk.service.sql.GetWarehouseResponse`.
11
+ * [Breaking] Remove `replication_config` field for `databricks.sdk.service.sharing.CreateShare`.
12
+ * [Breaking] Remove `replication_config` field for `databricks.sdk.service.sharing.ShareInfo`.
13
+
3
14
  ## Release v0.154.0 (2026-10-19)
4
15
 
5
16
  ### API Changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-sdk
3
- Version: 0.154.0
3
+ Version: 0.155.0
4
4
  Summary: Databricks SDK for Python (Beta)
5
5
  Project-URL: Documentation, https://databricks-sdk-py.readthedocs.io
6
6
  Keywords: databricks,sdk
@@ -267,6 +267,11 @@ class Config:
267
267
  # When enabled, the SDK will probe the storage proxy and use it if available.
268
268
  experimental_files_ext_enable_storage_proxy: bool = False
269
269
 
270
+ # Whether to ask the workspace which endpoints to use for file transfers (GET /api/2.0/fs/endpoints).
271
+ # When disabled, or when the server cannot answer, the SDK uses a built-in order: Presigned URL, then
272
+ # Files API 2.0 on the workspace host.
273
+ experimental_files_ext_enable_endpoints_api: bool = False
274
+
270
275
  def __init__(
271
276
  self,
272
277
  *,
@@ -16,6 +16,7 @@ from collections.abc import Iterator
16
16
  from concurrent.futures import ThreadPoolExecutor, as_completed
17
17
  from dataclasses import dataclass
18
18
  from datetime import timedelta
19
+ from enum import Enum
19
20
  from io import BytesIO
20
21
  from queue import Empty, Full, Queue
21
22
  from tempfile import mkstemp
@@ -746,6 +747,35 @@ class _PresignedUrl:
746
747
  part_number: int | None = None
747
748
 
748
749
 
750
+ class _ResolvedEndpoint(Enum):
751
+ """A file transfer protocol this SDK can speak, identified by the (api, api_version) pair the
752
+ endpoints API returns."""
753
+
754
+ IO_OFFLOAD = "IO_OFFLOAD"
755
+ FILES_API_V2 = "FILES_API_V2"
756
+
757
+
758
+ # Maps the server's (api, api_version) to a protocol compiled into this SDK. Pairs not listed here are
759
+ # skipped, which lets the server advertise newer protocols without breaking older SDKs. IO_OFFLOAD is
760
+ # unversioned during the preview, so a versioned IO_OFFLOAD is newer than this SDK.
761
+ _RECOGNIZED_ENDPOINTS: dict[tuple[str, Optional[str]], _ResolvedEndpoint] = {
762
+ ("IO_OFFLOAD", None): _ResolvedEndpoint.IO_OFFLOAD,
763
+ ("FILES_API", "2.0"): _ResolvedEndpoint.FILES_API_V2,
764
+ }
765
+
766
+ _ENDPOINT_SCHEMES = ("http", "https")
767
+
768
+
769
+ @dataclass(frozen=True)
770
+ class _Endpoint:
771
+ """One entry of the ordered endpoint list a file transfer walks, best first."""
772
+
773
+ kind: _ResolvedEndpoint
774
+ base_url: str
775
+ """Scheme and hostname as returned by the server, e.g. https://example.cloud.databricks.com."""
776
+ multipart_upload_supported: bool
777
+
778
+
749
779
  class _PresignedUrlRequestBuilder:
750
780
  """Builds presigned URL requests for file upload operations.
751
781
 
@@ -928,6 +958,12 @@ class FilesExt(files.FilesAPI):
928
958
  # Timeout in seconds for the storage-proxy health check probe.
929
959
  _STORAGE_PROXY_PROBE_TIMEOUT: float = 3.0
930
960
 
961
+ _ENDPOINTS_API_PATH: str = "/api/2.0/fs/endpoints"
962
+
963
+ # Endpoint discovery is a single attempt bounded by this timeout: it precedes a transfer, so it
964
+ # must fail fast to the default order rather than retry and stall the upload or download.
965
+ _ENDPOINTS_RESOLVE_TIMEOUT_SECONDS: float = 10.0
966
+
931
967
  @dataclass(frozen=True)
932
968
  class _UploadContext:
933
969
  target_path: str
@@ -956,13 +992,129 @@ class FilesExt(files.FilesAPI):
956
992
  self._dp_hostname_available: Optional[bool] = None
957
993
  self._cached_storage_proxy_session: Optional[requests.Session] = None
958
994
  self._storage_proxy_session_lock = Lock()
995
+ self._cached_endpoints: Optional[list[_Endpoint]] = None
996
+ self._endpoints_lock = Lock()
959
997
 
960
- def _get_hostname(self) -> str:
961
- """Returns the hostname for file operations.
998
+ def _resolve_endpoints(self) -> list[_Endpoint]:
999
+ """Returns the ordered endpoints to try for a file transfer, best first.
962
1000
 
963
- When storage proxy is enabled, probes it on first call and caches the
964
- result. Returns the proxy hostname if available, otherwise the workspace
965
- hostname.
1001
+ The server is asked once per client and its answer, including a failure, is cached. Anything
1002
+ short of a usable list falls back to the built-in order, so endpoint discovery never fails a
1003
+ transfer.
1004
+ """
1005
+ if not self._config.experimental_files_ext_enable_endpoints_api:
1006
+ return self._default_endpoints()
1007
+ with self._endpoints_lock:
1008
+ if self._cached_endpoints is None:
1009
+ self._cached_endpoints = self._fetch_endpoints() or self._default_endpoints()
1010
+ return list(self._cached_endpoints)
1011
+
1012
+ def _default_endpoints(self) -> list[_Endpoint]:
1013
+ host = self._config.host
1014
+ return [
1015
+ _Endpoint(_ResolvedEndpoint.IO_OFFLOAD, host, multipart_upload_supported=True),
1016
+ _Endpoint(_ResolvedEndpoint.FILES_API_V2, host, multipart_upload_supported=False),
1017
+ ]
1018
+
1019
+ def _fetch_endpoints(self) -> list[_Endpoint]:
1020
+ """Fetches the endpoint list from the server, keeping only entries this SDK can speak.
1021
+
1022
+ Discovery runs before a transfer, so it is a single short-timeout attempt with no retries: a
1023
+ slow or failing endpoint must fall back to the default order quickly rather than hold up the
1024
+ upload or download.
1025
+ """
1026
+ url = f"{self._config.host}{self._ENDPOINTS_API_PATH}"
1027
+ try:
1028
+ response = self._cloud_provider_session().request(
1029
+ "GET",
1030
+ url,
1031
+ headers={**self._config.authenticate(), "Accept": "application/json"},
1032
+ timeout=self._ENDPOINTS_RESOLVE_TIMEOUT_SECONDS,
1033
+ )
1034
+ except Exception as e:
1035
+ # Broad on purpose: network and auth failures must all fail safe to the default order.
1036
+ _LOG.warning(f"Failed to resolve file endpoints, using the default endpoints: {e}")
1037
+ return []
1038
+
1039
+ # Lets a failure below be traced to the server's request log.
1040
+ request_id = response.headers.get("x-request-id")
1041
+ if response.status_code == 404:
1042
+ # Not a warning: until the server-side rollout completes, some workspaces do not serve the API.
1043
+ _LOG.info(
1044
+ f"Endpoints API is not served for this workspace (request ID {request_id}), using the default endpoints."
1045
+ )
1046
+ return []
1047
+ if response.status_code != 200:
1048
+ _LOG.warning(
1049
+ f"Unexpected status resolving file endpoints ({response.status_code}, request ID {request_id}), "
1050
+ "using the default endpoints."
1051
+ )
1052
+ return []
1053
+ try:
1054
+ body = response.json()
1055
+ except Exception as e:
1056
+ _LOG.warning(
1057
+ f"Failed to parse endpoints response (request ID {request_id}), using the default endpoints: {e}"
1058
+ )
1059
+ return []
1060
+
1061
+ # Proto3 JSON leaves out an empty repeated field.
1062
+ entries = body.get("endpoints", []) if isinstance(body, dict) else None
1063
+ if not isinstance(entries, list):
1064
+ _LOG.warning(
1065
+ f"Unexpected endpoints response (request ID {request_id}), using the default endpoints: {body}"
1066
+ )
1067
+ return []
1068
+ endpoints = []
1069
+ for entry in entries:
1070
+ kind = self._endpoint_kind(entry)
1071
+ if kind is None:
1072
+ # Not a warning: an older SDK is expected to skip entries for APIs added after it shipped.
1073
+ _LOG.info(f"Skipping endpoint this SDK cannot use (request ID {request_id}): {entry}")
1074
+ continue
1075
+ endpoint = self._parse_endpoint(entry, kind)
1076
+ if endpoint is None:
1077
+ _LOG.warning(
1078
+ f"Skipping {kind.value} endpoint with an unusable address (request ID {request_id}): {entry}"
1079
+ )
1080
+ continue
1081
+ endpoints.append(endpoint)
1082
+ if not endpoints:
1083
+ _LOG.warning(f"No usable endpoints in the response (request ID {request_id}), using the default endpoints.")
1084
+ return endpoints
1085
+
1086
+ @staticmethod
1087
+ def _endpoint_kind(entry) -> Optional[_ResolvedEndpoint]:
1088
+ """Returns the protocol of a listed endpoint, or None if this SDK does not speak it."""
1089
+ if not isinstance(entry, dict):
1090
+ return None
1091
+ api = entry.get("api")
1092
+ api_version = entry.get("api_version")
1093
+ # The entry is unvalidated JSON: an unhashable value such as a list would make the lookup below raise
1094
+ # instead of skipping the entry. IO_OFFLOAD entries have no api_version, so None is allowed.
1095
+ if not isinstance(api, str) or not (api_version is None or isinstance(api_version, str)):
1096
+ return None
1097
+ return _RECOGNIZED_ENDPOINTS.get((api, api_version))
1098
+
1099
+ @staticmethod
1100
+ def _parse_endpoint(entry: dict, kind: _ResolvedEndpoint) -> Optional[_Endpoint]:
1101
+ scheme = entry.get("scheme")
1102
+ hostname = entry.get("hostname")
1103
+ if scheme not in _ENDPOINT_SCHEMES or not isinstance(hostname, str) or not hostname:
1104
+ return None
1105
+ # Mirrors the proto getter: an unset optional bool reads as false.
1106
+ multipart_upload_supported = entry.get("multipart_upload_supported") is True
1107
+ return _Endpoint(kind, f"{scheme}://{hostname}", multipart_upload_supported)
1108
+
1109
+ def _active_endpoint(self) -> _Endpoint:
1110
+ """The endpoint used for bulk file transfer.
1111
+
1112
+ Selected by the storage-proxy probe: the storage proxy (a direct Files API path) when the probe
1113
+ finds it available, otherwise the offload (presigned) path on the workspace host. The probe runs
1114
+ once and its result is cached.
1115
+
1116
+ This is the single-endpoint selection; PR wiring the endpoints API replaces it with a walk over
1117
+ the server-resolved list.
966
1118
  """
967
1119
  if self._config.experimental_files_ext_enable_storage_proxy:
968
1120
  if self._dp_hostname_available is None:
@@ -972,19 +1124,28 @@ class FilesExt(files.FilesAPI):
972
1124
  else:
973
1125
  _LOG.info("Storage proxy is not available, will use presigned URLs.")
974
1126
  if self._dp_hostname_available:
975
- return self._STORAGE_PROXY_HOSTNAME
976
- return self._config.host
1127
+ return _Endpoint(
1128
+ _ResolvedEndpoint.FILES_API_V2, self._STORAGE_PROXY_HOSTNAME, multipart_upload_supported=True
1129
+ )
1130
+ return _Endpoint(_ResolvedEndpoint.IO_OFFLOAD, self._config.host, multipart_upload_supported=True)
1131
+
1132
+ def _get_hostname(self) -> str:
1133
+ """Returns the scheme+hostname for file operations, e.g. https://example.cloud.databricks.com."""
1134
+ return self._active_endpoint().base_url
977
1135
 
978
1136
  def _create_request_builder(self):
979
- """Creates the appropriate request builder for file operations.
1137
+ """Creates the request builder for the active endpoint."""
1138
+ return self._request_builder_for(self._active_endpoint())
1139
+
1140
+ def _request_builder_for(self, endpoint: _Endpoint):
1141
+ """Maps an endpoint to the builder that speaks its protocol.
980
1142
 
981
- Returns a storage proxy builder when the proxy is available,
982
- otherwise a presigned URL builder.
1143
+ The offload path coordinates presigned URLs through the workspace API; the direct Files API path
1144
+ builds URLs straight at the endpoint host.
983
1145
  """
984
- hostname = self._get_hostname()
985
- if self._config.experimental_files_ext_enable_storage_proxy and self._dp_hostname_available:
986
- return _StorageProxyRequestBuilder(hostname)
987
- return _PresignedUrlRequestBuilder(self._api, hostname)
1146
+ if endpoint.kind == _ResolvedEndpoint.IO_OFFLOAD:
1147
+ return _PresignedUrlRequestBuilder(self._api, endpoint.base_url)
1148
+ return _StorageProxyRequestBuilder(endpoint.base_url)
988
1149
 
989
1150
  def _resolve_workspace_id(self) -> Optional[str]:
990
1151
  """Resolves the workspace ID by querying the SCIM Me endpoint."""
@@ -193,8 +193,15 @@ class BudgetConfiguration:
193
193
  """Databricks account ID."""
194
194
 
195
195
  alert_configurations: Optional[List[AlertConfiguration]] = None
196
- """Alerts to configure when this budget is in a triggered state. Budgets must have exactly one
197
- alert configuration."""
196
+ """Alerts to configure when this budget is in a triggered state. Budgets must have at least one
197
+ alert configuration. A budget can have up to four shared alerts per time period, each with a
198
+ unique ``quantity_threshold``. Budgets with ``resource_type`` set to
199
+ ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY`` can also use per-user alerts, with optional
200
+ ``principal_overrides``. These budgets can have at most one per-user alert per time period, and
201
+ can use shared alerts, a per-user alert, or both. The ``BLOCK_USAGE`` action is only supported
202
+ on budgets with ``resource_type`` set to ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY``. At most one
203
+ shared alert per time period can have a ``BLOCK_USAGE`` action, and it must be the shared alert
204
+ with the highest threshold in that period."""
198
205
 
199
206
  budget_configuration_id: Optional[str] = None
200
207
  """Databricks budget configuration ID."""
@@ -504,8 +511,15 @@ class CreateBudgetConfigurationBudget:
504
511
  """Databricks account ID."""
505
512
 
506
513
  alert_configurations: Optional[List[CreateBudgetConfigurationBudgetAlertConfigurations]] = None
507
- """Alerts to configure when this budget is in a triggered state. Budgets must have exactly one
508
- alert configuration."""
514
+ """Alerts to configure when this budget is in a triggered state. Budgets must have at least one
515
+ alert configuration. A budget can have up to four shared alerts per time period, each with a
516
+ unique ``quantity_threshold``. Budgets with ``resource_type`` set to
517
+ ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY`` can also use per-user alerts, with optional
518
+ ``principal_overrides``. These budgets can have at most one per-user alert per time period, and
519
+ can use shared alerts, a per-user alert, or both. The ``BLOCK_USAGE`` action is only supported
520
+ on budgets with ``resource_type`` set to ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY``. At most one
521
+ shared alert per time period can have a ``BLOCK_USAGE`` action, and it must be the shared alert
522
+ with the highest threshold in that period."""
509
523
 
510
524
  display_name: Optional[str] = None
511
525
  """Human-readable name of budget configuration. Max Length: 128"""
@@ -1470,8 +1484,15 @@ class UpdateBudgetConfigurationBudget:
1470
1484
  """Databricks account ID."""
1471
1485
 
1472
1486
  alert_configurations: Optional[List[AlertConfiguration]] = None
1473
- """Alerts to configure when this budget is in a triggered state. Budgets must have exactly one
1474
- alert configuration."""
1487
+ """Alerts to configure when this budget is in a triggered state. Budgets must have at least one
1488
+ alert configuration. A budget can have up to four shared alerts per time period, each with a
1489
+ unique ``quantity_threshold``. Budgets with ``resource_type`` set to
1490
+ ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY`` can also use per-user alerts, with optional
1491
+ ``principal_overrides``. These budgets can have at most one per-user alert per time period, and
1492
+ can use shared alerts, a per-user alert, or both. The ``BLOCK_USAGE`` action is only supported
1493
+ on budgets with ``resource_type`` set to ``BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY``. At most one
1494
+ shared alert per time period can have a ``BLOCK_USAGE`` action, and it must be the shared alert
1495
+ with the highest threshold in that period."""
1475
1496
 
1476
1497
  budget_configuration_id: Optional[str] = None
1477
1498
  """Databricks budget configuration ID."""
@@ -559,10 +559,11 @@ class Operation:
559
559
  rejected with ABORTED so the caller can re-read and retry."""
560
560
 
561
561
  state: Optional[str] = None
562
- """Serialized local config state after the operation. Its presence records whether the resource
563
- still exists. Explicitly clearing state removes the resource; omitting it from the update mask
564
- leaves resource state unchanged. State is stored only on Resources. UpdateOperation accepts
565
- state but omits it from its response, as do subsequent GetOperation and ListOperations.
562
+ """Serialized local config state after the operation. Its presence records whether the resource is
563
+ still tracked by the deployment. Explicitly clearing state removes the resource from the
564
+ deployment; omitting it from the update mask leaves resource state unchanged. State is stored
565
+ only on Resources. UpdateOperation accepts state but omits it from its response, as do
566
+ subsequent GetOperation and ListOperations.
566
567
 
567
568
  Mutable: may be updated after creation via UpdateOperation. When updating, the caller must echo
568
569
  the last-observed ``sequence_id`` as a concurrency precondition.
@@ -1529,8 +1530,8 @@ class BundleDeploymentsAPI:
1529
1530
  value it last observed, and the server rejects the update with ``ABORTED`` if the operation has been
1530
1531
  modified since. On success the server increments ``sequence_id``; updates to ``state``,
1531
1532
  ``resource_id``, and ``dashboard_metadata`` are mirrored onto the corresponding deployment-level
1532
- resource. Listing ``state`` in ``update_mask`` with no value clears it, which removes the resource, so
1533
- a delete that is retried until it succeeds must clear ``state``. The parent version must be in
1533
+ resource. Listing ``state`` in ``update_mask`` with no value clears it, which removes the tracked
1534
+ resource, so a delete or unbind that succeeds must clear ``state``. The parent version must be in
1534
1535
  progress, and after the update is applied a succeeded operation cannot carry an ``error_message``. See
1535
1536
  the ``state`` and ``resource_id`` fields for the rest.
1536
1537
 
@@ -8051,7 +8051,7 @@ class ModelProviderServiceConfigCustomProviderApiKeyHeaderAuth:
8051
8051
 
8052
8052
  @dataclass
8053
8053
  class ModelProviderServiceConfigCustomProviderConfig:
8054
- """Custom OpenAI-compatible provider configuration with bearer-token authentication."""
8054
+ """Custom OpenAI-compatible provider configuration."""
8055
8055
 
8056
8056
  direct: Optional[ModelProviderServiceConfigCustomProviderDirectConfig] = None
8057
8057
  """Endpoint and authentication configuration for the custom provider."""
@@ -14464,8 +14464,16 @@ class AiGatewayAPI:
14464
14464
 
14465
14465
  def create_skill(self, skill: Skill, parent: str, skill_id: str) -> Skill:
14466
14466
  """Creates a skill in a Unity Catalog schema and provisions its managed bundle storage. Specify its name
14467
- in ``skill_id``. The request contains an optional comment but no bundle bytes. Upload bundle files
14468
- through the Files API, then call FinalizeSkill.
14467
+ in ``skill_id``. The request contains an optional comment but no bundle bytes.
14468
+
14469
+ To publish a skill:
14470
+
14471
+ 1. Call CreateSkill to create the skill in Unity Catalog.
14472
+ 2. Upload every bundle file, including ``SKILL.md`` at the bundle root, with the Files API: ``PUT
14473
+ /api/2.0/fs/files/Skills/{catalog}/{schema}/{skill}/{file_path}``. The CreateSkill caller owns the
14474
+ skill and can upload. Other callers need ``READ_VOLUME`` and ``WRITE_VOLUME`` on the skill.
14475
+ 3. Call FinalizeSkill to validate ``SKILL.md`` and set the skill's ``bundle_name`` and ``description``
14476
+ from its frontmatter ``name`` and ``description``.
14469
14477
 
14470
14478
  You must be the owner of the parent schema or have ``CREATE_VOLUME`` and ``USE_SCHEMA`` on it, plus
14471
14479
  ``USE_CATALOG`` on the parent catalog.
@@ -14651,12 +14659,13 @@ class AiGatewayAPI:
14651
14659
  self._api.do("DELETE", f"/api/2.1/unity-catalog/{name}", query=query, headers=headers)
14652
14660
 
14653
14661
  def finalize_skill(self, name: str) -> Skill:
14654
- """Finalizes a skill after its bundle is uploaded. This method reads SKILL.md through the Files API using
14655
- the caller's authorization. Its YAML frontmatter must contain an agentskills.io-compliant ``name`` and
14656
- a nonblank ``description`` within the configured UTF-8 byte limit. On success, it replaces
14657
- ``bundle_name`` and ``description``; refreshes ``finalize_time``, ``update_time``, and ``updated_by``;
14658
- and returns the updated skill. ``comment`` is preserved. Re-finalization uses the latest SKILL.md and
14659
- is last-write-wins without an etag precondition. Validation failures do not change metadata.
14662
+ """Finalizes a skill after its bundle files are uploaded or changed through the Files API. Call it again
14663
+ after every bundle change. This method reads SKILL.md through the Files API using the caller's
14664
+ authorization. Its YAML frontmatter must contain an agentskills.io-compliant ``name`` and a nonblank
14665
+ ``description`` within the configured UTF-8 byte limit. On success, it replaces ``bundle_name`` and
14666
+ ``description``; refreshes ``finalize_time``, ``update_time``, and ``updated_by``; and returns the
14667
+ updated skill. ``comment`` is preserved. Re-finalization uses the latest SKILL.md and is
14668
+ last-write-wins without an etag precondition. Validation failures do not change metadata.
14660
14669
 
14661
14670
  You must be the owner of the skill or have ``READ_VOLUME`` on it, plus ``USE_CATALOG`` on the parent
14662
14671
  catalog and ``USE_SCHEMA`` on the parent schema.
@@ -14819,7 +14828,7 @@ class AiGatewayAPI:
14819
14828
  returned.
14820
14829
 
14821
14830
  :param page_size: int (optional)
14822
- Maximum number of MCP services to return. Defaults to 100 when unset or 0; the maximum is 200. Use
14831
+ Maximum number of MCP services to return. Defaults to 200 when unset or 0; the maximum is 200. Use
14823
14832
  ``page_token`` to retrieve additional pages.
14824
14833
  :param page_token: str (optional)
14825
14834
  Opaque pagination token from the previous response.
@@ -14877,7 +14886,7 @@ class AiGatewayAPI:
14877
14886
  ``MANAGE``) are returned.
14878
14887
 
14879
14888
  :param page_size: int (optional)
14880
- Maximum number of provider services to return. Defaults to 100 when unset or 0; the maximum is 200.
14889
+ Maximum number of provider services to return. Defaults to 200 when unset or 0; the maximum is 200.
14881
14890
  Use ``page_token`` to retrieve additional pages.
14882
14891
  :param page_token: str (optional)
14883
14892
  Opaque pagination token from the previous response.
@@ -14935,7 +14944,7 @@ class AiGatewayAPI:
14935
14944
  returned.
14936
14945
 
14937
14946
  :param page_size: int (optional)
14938
- Maximum number of model services to return. Defaults to 100 when unset or 0; the maximum is 200. Use
14947
+ Maximum number of model services to return. Defaults to 200 when unset or 0; the maximum is 200. Use
14939
14948
  ``page_token`` to retrieve additional pages.
14940
14949
  :param page_token: str (optional)
14941
14950
  Opaque pagination token from the previous response.
@@ -14993,7 +15002,7 @@ class AiGatewayAPI:
14993
15002
  Required: skill listing is schema-scoped, so ``parent`` must be set; an unset or empty ``parent`` is
14994
15003
  rejected with INVALID_PARAMETER_VALUE.
14995
15004
  :param page_size: int (optional)
14996
- Maximum number of skills to return. Defaults to 100 when unset or 0; the maximum is 200. Use
15005
+ Maximum number of skills to return. Defaults to 200 when unset or 0; the maximum is 200. Use
14997
15006
  ``page_token`` to retrieve additional pages.
14998
15007
  :param page_token: str (optional)
14999
15008
  Opaque pagination token from a previous request.
@@ -15201,8 +15210,13 @@ class AiGatewayAPI:
15201
15210
  conditional on the skill not having changed since it was read. Bundle files, grants, tags, and
15202
15211
  ownership are unchanged.
15203
15212
 
15204
- You must be the owner of the skill or have ``MANAGE`` on it, plus ``USE_CATALOG`` on the parent
15205
- catalog and ``USE_SCHEMA`` on the parent schema.
15213
+ To update the bundle, add, overwrite (``overwrite=true``), or delete files under
15214
+ ``/Skills/{catalog}/{schema}/{skill}/`` with the Files API, then call FinalizeSkill. Changing bundle
15215
+ files requires being the owner of the skill or having ``READ_VOLUME`` and ``WRITE_VOLUME`` on it;
15216
+ ``MANAGE`` does not grant access to bundle files.
15217
+
15218
+ To call UpdateSkill, you must be the owner of the skill or have ``MANAGE`` on it, plus ``USE_CATALOG``
15219
+ on the parent catalog and ``USE_SCHEMA`` on the parent schema.
15206
15220
 
15207
15221
  :param name: str
15208
15222
  Resource name of the skill. Format: ``skills/{catalog}.{schema}.{skill}``. Each ``{...}`` component
@@ -1240,6 +1240,9 @@ class DataSource:
1240
1240
  request_source: Optional[RequestSource] = None
1241
1241
  """A request-time data source."""
1242
1242
 
1243
+ sdp_source: Optional[SdpSource] = None
1244
+ """A Spark Declarative Pipeline data source."""
1245
+
1243
1246
  stream_source: Optional[StreamSource] = None
1244
1247
  """A Stream data source."""
1245
1248
 
@@ -1256,6 +1259,8 @@ class DataSource:
1256
1259
  body["lateness"] = self.lateness.as_dict()
1257
1260
  if self.request_source:
1258
1261
  body["request_source"] = self.request_source.as_dict()
1262
+ if self.sdp_source:
1263
+ body["sdp_source"] = self.sdp_source.as_dict()
1259
1264
  if self.stream_source:
1260
1265
  body["stream_source"] = self.stream_source.as_dict()
1261
1266
  return body
@@ -1273,6 +1278,8 @@ class DataSource:
1273
1278
  body["lateness"] = self.lateness
1274
1279
  if self.request_source:
1275
1280
  body["request_source"] = self.request_source
1281
+ if self.sdp_source:
1282
+ body["sdp_source"] = self.sdp_source
1276
1283
  if self.stream_source:
1277
1284
  body["stream_source"] = self.stream_source
1278
1285
  return body
@@ -1286,6 +1293,7 @@ class DataSource:
1286
1293
  kafka_source=_from_dict(d, "kafka_source", KafkaSource),
1287
1294
  lateness=_from_dict(d, "lateness", SourceLateness),
1288
1295
  request_source=_from_dict(d, "request_source", RequestSource),
1296
+ sdp_source=_from_dict(d, "sdp_source", SdpSource),
1289
1297
  stream_source=_from_dict(d, "stream_source", StreamSource),
1290
1298
  )
1291
1299
 
@@ -8144,6 +8152,106 @@ class SchemaRegistryConfig:
8144
8152
  )
8145
8153
 
8146
8154
 
8155
+ @dataclass
8156
+ class SdpSource:
8157
+ """A Spark Declarative Pipeline (SDP) data source."""
8158
+
8159
+ dataframe_schema: Optional[str] = None
8160
+ """Schema of the resulting dataframe after transformations, in Spark StructType JSON format (from
8161
+ df.schema.json()). Required if transformation_sql is specified. Example:
8162
+ {"type":"struct","fields":[{"name":"col_a","type":"integer","nullable":true,"metadata":{}},{"name":"col_c","type":"integer","nullable":true,"metadata":{}}]}"""
8163
+
8164
+ filter_condition: Optional[str] = None
8165
+ """Single WHERE clause to filter the pipeline's output table before applying transformations. Will
8166
+ be row-wise evaluated, so should only include conditionals and projections."""
8167
+
8168
+ input_tables: Optional[List[str]] = None
8169
+ """The full three-part names of the tables the pipeline reads from. Required to materialize this
8170
+ feature with a TableTrigger, which starts a run when these tables update. Each table must exist
8171
+ when the feature is created. After the pipeline runs, Feature Store checks that it reads from
8172
+ these tables, and the run fails if it doesn't. At most 100 tables."""
8173
+
8174
+ output_table: Optional[str] = None
8175
+ """The full three-part (catalog, schema, table) name of the pipeline's output table to read from.
8176
+ The table doesn't need to exist until the pipeline first runs. Required."""
8177
+
8178
+ pipeline_id: Optional[str] = None
8179
+ """The ID of the Spark Declarative Pipeline that Feature Store runs to produce this source, before
8180
+ each materialization or backfill. The pipeline must already exist when the feature is created,
8181
+ and you need CAN_RUN, CAN_MANAGE, or owner permission on it. It doesn't need to have run yet.
8182
+ Deleting the feature doesn't delete the pipeline. If the pipeline is deleted, this field reads
8183
+ back empty. Required."""
8184
+
8185
+ pipeline_state: Optional[SdpSourceState] = None
8186
+ """State tracking pipeline execution and output table validation. PENDING until the pipeline has
8187
+ run at least once and created the output table; then RESOLVED on success, or ERROR on failure."""
8188
+
8189
+ transformation_sql: Optional[str] = None
8190
+ """A single SQL SELECT expression applied after filter_condition. Should contain all the columns
8191
+ needed (eg. "SELECT *, col_a + col_b AS col_c FROM x.y.z WHERE col_a > 0" would have
8192
+ ``transformation_sql`` "*, col_a + col_b AS col_c") If transformation_sql is not provided, all
8193
+ columns of the pipeline's output table are present in the DataSource dataframe."""
8194
+
8195
+ def as_dict(self) -> dict:
8196
+ """Serializes the SdpSource into a dictionary suitable for use as a JSON request body."""
8197
+ body = {}
8198
+ if self.dataframe_schema is not None:
8199
+ body["dataframe_schema"] = self.dataframe_schema
8200
+ if self.filter_condition is not None:
8201
+ body["filter_condition"] = self.filter_condition
8202
+ if self.input_tables:
8203
+ body["input_tables"] = [v for v in self.input_tables]
8204
+ if self.output_table is not None:
8205
+ body["output_table"] = self.output_table
8206
+ if self.pipeline_id is not None:
8207
+ body["pipeline_id"] = self.pipeline_id
8208
+ if self.pipeline_state is not None:
8209
+ body["pipeline_state"] = self.pipeline_state.value
8210
+ if self.transformation_sql is not None:
8211
+ body["transformation_sql"] = self.transformation_sql
8212
+ return body
8213
+
8214
+ def as_shallow_dict(self) -> dict:
8215
+ """Serializes the SdpSource into a shallow dictionary of its immediate attributes."""
8216
+ body = {}
8217
+ if self.dataframe_schema is not None:
8218
+ body["dataframe_schema"] = self.dataframe_schema
8219
+ if self.filter_condition is not None:
8220
+ body["filter_condition"] = self.filter_condition
8221
+ if self.input_tables:
8222
+ body["input_tables"] = self.input_tables
8223
+ if self.output_table is not None:
8224
+ body["output_table"] = self.output_table
8225
+ if self.pipeline_id is not None:
8226
+ body["pipeline_id"] = self.pipeline_id
8227
+ if self.pipeline_state is not None:
8228
+ body["pipeline_state"] = self.pipeline_state
8229
+ if self.transformation_sql is not None:
8230
+ body["transformation_sql"] = self.transformation_sql
8231
+ return body
8232
+
8233
+ @classmethod
8234
+ def from_dict(cls, d: Dict[str, Any]) -> SdpSource:
8235
+ """Deserializes the SdpSource from a dictionary."""
8236
+ return cls(
8237
+ dataframe_schema=d.get("dataframe_schema", None),
8238
+ filter_condition=d.get("filter_condition", None),
8239
+ input_tables=d.get("input_tables", None),
8240
+ output_table=d.get("output_table", None),
8241
+ pipeline_id=d.get("pipeline_id", None),
8242
+ pipeline_state=_enum(d, "pipeline_state", SdpSourceState),
8243
+ transformation_sql=d.get("transformation_sql", None),
8244
+ )
8245
+
8246
+
8247
+ class SdpSourceState(Enum):
8248
+ """State of the SDP source relative to pipeline execution and output table validation."""
8249
+
8250
+ ERROR = "ERROR"
8251
+ PENDING = "PENDING"
8252
+ RESOLVED = "RESOLVED"
8253
+
8254
+
8147
8255
  @dataclass
8148
8256
  class SearchExperimentsResponse:
8149
8257
  experiments: Optional[List[Experiment]] = None
@@ -6652,8 +6652,8 @@ class PipelinesAPI:
6652
6652
  optional. The default value is 25. The maximum value is 100. An error is returned if the value of
6653
6653
  max_results is greater than 100.
6654
6654
  :param order_by: List[str] (optional)
6655
- A list of strings specifying the order of results. Supported order_by fields are id and name. The
6656
- default is id asc. This field is optional.
6655
+ A list of strings specifying the order of results. The supported order_by field is id. The default
6656
+ is id asc. This field is optional.
6657
6657
  :param page_token: str (optional)
6658
6658
  Page token returned by previous call
6659
6659