databricks-sdk 0.157.0__tar.gz → 0.158.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.
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/CHANGELOG.md +10 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/PKG-INFO +1 -1
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/credentials_provider.py +15 -6
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/platform.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/files.py +59 -84
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/billing.py +218 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/bundle.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/catalog.py +13 -11
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/database.py +54 -4
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/iamv2.py +11 -7
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/ml.py +3 -2
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/serving.py +2 -1
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/sql.py +2 -2
- databricks_sdk-0.158.0/databricks/sdk/version.py +1 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks_sdk.egg-info/PKG-INFO +1 -1
- databricks_sdk-0.157.0/databricks/sdk/version.py +0 -1
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/CONTRIBUTING.md +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/DCO +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/LICENSE +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/MANIFEST.in +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/Makefile +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/NOTICE +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/README.md +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/SECURITY.md +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_base_client.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_property.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_sandbox_grpc/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_sandbox_grpc/sandbox_service_pb2.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_sandbox_grpc/sandbox_service_pb2_grpc.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_widgets/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_widgets/default_widgets_utils.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/_widgets/ipywidgets_utils.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/azure.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/casing.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/client_types.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/clock.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/common/lro.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/common/types/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/common/types/fieldmask.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/config.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/core.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/data_plane.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/dbutils.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/environments.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/base.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/customizer.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/deserializer.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/details.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/mapper.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/overrides.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/parser.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/private_link.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/errors/sdk.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/logger/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/logger/round_trip_logger.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/_grpc_transport.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/compute.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/files_utils.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/jobs.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/open_ai_client.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/sandbox.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/sharing.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/mixins/workspace.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/oauth.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/oidc.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/oidc_token_supplier.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/py.typed +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/retries.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/runtime/__init__.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/runtime/dbutils_stub.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/_internal.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/agentbricks.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/agentkit.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/aifunctions.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/aisearch.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/apps.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/bundledeployments.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/cleanrooms.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/compute.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/dashboards.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/dataclassification.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/dataquality.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/disasterrecovery.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/domains.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/environments.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/files.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/iam.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/jobs.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/knowledgeassistants.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/marketplace.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/networking.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/oauth2.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/pipelines.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/postgres.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/provisioning.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/qualitymonitorv2.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/sandbox.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/settings.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/settingsv2.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/sharing.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/supervisoragents.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/tags.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/vectorsearch.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/service/workspace.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks/sdk/useragent.py +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks_sdk.egg-info/SOURCES.txt +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks_sdk.egg-info/dependency_links.txt +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks_sdk.egg-info/requires.txt +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/databricks_sdk.egg-info/top_level.txt +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/pyproject.toml +0 -0
- {databricks_sdk-0.157.0 → databricks_sdk-0.158.0}/setup.cfg +0 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Version changelog
|
|
2
2
|
|
|
3
|
+
## Release v0.158.0 (2026-10-29)
|
|
4
|
+
|
|
5
|
+
### API Changes
|
|
6
|
+
* Add `get_budget_spend_status()` and `list_budget_spend_statuses()` methods for [a.budgets](https://databricks-sdk-py.readthedocs.io/en/latest/account/billing/budgets.html) account-level service.
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
* Fix `WorkspaceClient.files.download_to` with `use_parallel=True` always falling back to the Files API for files above the parallel download threshold, instead of downloading byte ranges from presigned URLs (or from the storage proxy when `experimental_files_ext_enable_storage_proxy` is set). A byte range that fails after another range was received now raises, and expired GCP presigned URLs are refreshed like AWS and Azure ones.
|
|
10
|
+
* Fix `WorkspaceClient.files.download_to` with `use_parallel=True` requesting the wrong path from the Files API when the file path contains characters such as `#`, `?` or `%`.
|
|
11
|
+
* Fix Databricks CLI authentication rejecting small wrappers around the CLI (e.g. launcher scripts or version manager shims) as the legacy Python CLI. Small files found in `PATH` are now only rejected if they are the entry point pip installs for the legacy Python CLI.
|
|
12
|
+
|
|
3
13
|
## Release v0.157.0 (2026-10-24)
|
|
4
14
|
|
|
5
15
|
### API Changes
|
|
@@ -1226,6 +1226,13 @@ class DatabricksCliTokenSource(CliTokenSource):
|
|
|
1226
1226
|
cmd += ["--account-id", cfg.account_id]
|
|
1227
1227
|
return cmd
|
|
1228
1228
|
|
|
1229
|
+
# Files at least this large are assumed to be the Go CLI without reading them.
|
|
1230
|
+
_CLI_MIN_SIZE = 1024 * 1024
|
|
1231
|
+
|
|
1232
|
+
# Identifies the legacy CLI's pip entry point script. The imported name is omitted
|
|
1233
|
+
# because it changed from `cli` to `main` in 0.17.8.
|
|
1234
|
+
_LEGACY_CLI_MARKER = b"from databricks_cli.cli import "
|
|
1235
|
+
|
|
1229
1236
|
@staticmethod
|
|
1230
1237
|
def _find_executable(name) -> str:
|
|
1231
1238
|
err = FileNotFoundError("Most likely the Databricks CLI is not installed")
|
|
@@ -1234,12 +1241,14 @@ class DatabricksCliTokenSource(CliTokenSource):
|
|
|
1234
1241
|
if not path.is_file():
|
|
1235
1242
|
continue
|
|
1236
1243
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1244
|
+
if path.stat().st_size < DatabricksCliTokenSource._CLI_MIN_SIZE:
|
|
1245
|
+
try:
|
|
1246
|
+
content = path.read_bytes()
|
|
1247
|
+
except OSError:
|
|
1248
|
+
continue
|
|
1249
|
+
if DatabricksCliTokenSource._LEGACY_CLI_MARKER in content:
|
|
1250
|
+
err = FileNotFoundError("Databricks CLI version <0.100.0 detected")
|
|
1251
|
+
continue
|
|
1243
1252
|
|
|
1244
1253
|
return str(path)
|
|
1245
1254
|
|
|
File without changes
|
|
@@ -850,25 +850,6 @@ class _PresignedUrlRequestBuilder:
|
|
|
850
850
|
)
|
|
851
851
|
return CreateDownloadUrlResponse.from_dict(response)
|
|
852
852
|
|
|
853
|
-
def build_abort_url(self, path: str, session_token: str, expire_time: str) -> _PresignedUrl:
|
|
854
|
-
"""Fetches a presigned URL for aborting a multipart upload."""
|
|
855
|
-
body = {
|
|
856
|
-
"path": path,
|
|
857
|
-
"session_token": session_token,
|
|
858
|
-
"expire_time": expire_time,
|
|
859
|
-
}
|
|
860
|
-
response = self._api.do(
|
|
861
|
-
"POST",
|
|
862
|
-
url=f"{self._hostname}/api/2.0/fs/create-abort-upload-url",
|
|
863
|
-
headers={"Content-Type": "application/json"},
|
|
864
|
-
body=body,
|
|
865
|
-
)
|
|
866
|
-
abort_node = response["abort_upload_url"]
|
|
867
|
-
headers: dict[str, str] = {"Content-Type": "application/octet-stream"}
|
|
868
|
-
for h in abort_node.get("headers", []):
|
|
869
|
-
headers[h["name"]] = h["value"]
|
|
870
|
-
return _PresignedUrl(url=abort_node["url"], headers=headers)
|
|
871
|
-
|
|
872
853
|
|
|
873
854
|
class _StorageProxyRequestBuilder:
|
|
874
855
|
"""Builds direct upload requests to the storage proxy.
|
|
@@ -930,21 +911,6 @@ class _StorageProxyRequestBuilder:
|
|
|
930
911
|
headers={},
|
|
931
912
|
)
|
|
932
913
|
|
|
933
|
-
def build_abort_url(self, path: str, session_token: str, expire_time: str) -> _PresignedUrl:
|
|
934
|
-
"""Builds a URL for aborting an upload directly on the storage proxy."""
|
|
935
|
-
escaped = _escape_multi_segment_path_parameter(path)
|
|
936
|
-
base = f"{self._hostname}/api/2.0/fs/files{escaped}"
|
|
937
|
-
query = parse.urlencode(
|
|
938
|
-
{
|
|
939
|
-
"action": "abort-upload",
|
|
940
|
-
"session_token": session_token,
|
|
941
|
-
}
|
|
942
|
-
)
|
|
943
|
-
return _PresignedUrl(
|
|
944
|
-
url=f"{base}?{query}",
|
|
945
|
-
headers={"Content-Type": "application/json"},
|
|
946
|
-
)
|
|
947
|
-
|
|
948
914
|
|
|
949
915
|
class FilesExt(files.FilesAPI):
|
|
950
916
|
__doc__ = files.FilesAPI.__doc__
|
|
@@ -990,8 +956,8 @@ class FilesExt(files.FilesAPI):
|
|
|
990
956
|
self._cached_cloud_provider_session: Optional[requests.Session] = None
|
|
991
957
|
self._cloud_provider_session_lock = Lock()
|
|
992
958
|
self._dp_hostname_available: Optional[bool] = None
|
|
993
|
-
self.
|
|
994
|
-
self.
|
|
959
|
+
self._cached_authenticated_session: Optional[requests.Session] = None
|
|
960
|
+
self._authenticated_session_lock = Lock()
|
|
995
961
|
self._cached_endpoints: Optional[list[_Endpoint]] = None
|
|
996
962
|
self._endpoints_lock = Lock()
|
|
997
963
|
|
|
@@ -1185,17 +1151,16 @@ class FilesExt(files.FilesAPI):
|
|
|
1185
1151
|
except Exception:
|
|
1186
1152
|
return False
|
|
1187
1153
|
|
|
1188
|
-
def
|
|
1189
|
-
"""Returns an HTTP session with SDK auth for
|
|
1154
|
+
def _authenticated_session(self) -> requests.Session:
|
|
1155
|
+
"""Returns an HTTP session with SDK auth for direct Files API data requests.
|
|
1190
1156
|
|
|
1191
|
-
Unlike _cloud_provider_session (which has no auth), this session
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
first call and cached for reuse.
|
|
1157
|
+
Unlike _cloud_provider_session (which has no auth), this session includes the SDK authentication
|
|
1158
|
+
callback so that every request carries valid credentials. The session is created on first call and
|
|
1159
|
+
cached for reuse.
|
|
1195
1160
|
"""
|
|
1196
|
-
with self.
|
|
1197
|
-
if self.
|
|
1198
|
-
return self.
|
|
1161
|
+
with self._authenticated_session_lock:
|
|
1162
|
+
if self._cached_authenticated_session is not None:
|
|
1163
|
+
return self._cached_authenticated_session
|
|
1199
1164
|
session = requests.Session()
|
|
1200
1165
|
config = self._config
|
|
1201
1166
|
|
|
@@ -1212,7 +1177,7 @@ class FilesExt(files.FilesAPI):
|
|
|
1212
1177
|
)
|
|
1213
1178
|
session.mount("https://", http_adapter)
|
|
1214
1179
|
session.mount("http://", http_adapter)
|
|
1215
|
-
self.
|
|
1180
|
+
self._cached_authenticated_session = session
|
|
1216
1181
|
return session
|
|
1217
1182
|
|
|
1218
1183
|
def download(
|
|
@@ -1339,8 +1304,12 @@ class FilesExt(files.FilesAPI):
|
|
|
1339
1304
|
file_info = self.get_metadata(remote_path)
|
|
1340
1305
|
file_size = file_info.content_length
|
|
1341
1306
|
last_modified = file_info.last_modified
|
|
1342
|
-
# If the file is smaller than the threshold, do not use parallel download.
|
|
1343
|
-
|
|
1307
|
+
# If the file is smaller than the threshold, or fits in one range, do not use parallel download. A range
|
|
1308
|
+
# covering the whole file may also be answered with 200 instead of 206.
|
|
1309
|
+
if file_size <= max(
|
|
1310
|
+
self._config.files_ext_parallel_download_min_file_size,
|
|
1311
|
+
self._config.files_ext_parallel_download_default_part_size,
|
|
1312
|
+
):
|
|
1344
1313
|
self._sequential_download_to_file(destination, remote_path, last_modified)
|
|
1345
1314
|
return
|
|
1346
1315
|
part_size = self._config.files_ext_parallel_download_default_part_size
|
|
@@ -1422,13 +1391,16 @@ class FilesExt(files.FilesAPI):
|
|
|
1422
1391
|
url_distributor.invalidate_url(version)
|
|
1423
1392
|
retry_count += 1
|
|
1424
1393
|
continue
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1394
|
+
# Only a 206 carries the requested range; a 200 carries the whole file, which must not be written
|
|
1395
|
+
# at this range's offset.
|
|
1396
|
+
if raw_resp.status_code != 206:
|
|
1397
|
+
message = f"Received {raw_resp.status_code} from presigned URL for {additional_headers['Range']}"
|
|
1398
|
+
if not any_success.is_set():
|
|
1399
|
+
raise FallbackToDownloadUsingFilesApi(message)
|
|
1400
|
+
if raw_resp.ok:
|
|
1401
|
+
raise ValueError(message)
|
|
1402
|
+
raise _error_mapper(raw_resp, {"message": message})
|
|
1430
1403
|
|
|
1431
|
-
raw_resp.raise_for_status()
|
|
1432
1404
|
any_success.set()
|
|
1433
1405
|
return BytesIO(raw_resp.content)
|
|
1434
1406
|
raise ValueError("Exceeded maximum retries for downloading with presigned URL: URL expired too many times")
|
|
@@ -1451,11 +1423,17 @@ class FilesExt(files.FilesAPI):
|
|
|
1451
1423
|
def download_chunk(additional_headers: dict[str, str]) -> BinaryIO:
|
|
1452
1424
|
raw_response: dict = self._api.do(
|
|
1453
1425
|
method="GET",
|
|
1454
|
-
path=f"/api/2.0/fs/files{remote_path}",
|
|
1426
|
+
path=f"/api/2.0/fs/files{_escape_multi_segment_path_parameter(remote_path)}",
|
|
1455
1427
|
headers=additional_headers,
|
|
1456
1428
|
raw=True,
|
|
1457
1429
|
)
|
|
1458
|
-
|
|
1430
|
+
contents = raw_response["contents"]
|
|
1431
|
+
status = contents._response.status_code
|
|
1432
|
+
if status != 206:
|
|
1433
|
+
# Only a 206 carries the requested range; anything else must not be written at its offset.
|
|
1434
|
+
contents.close()
|
|
1435
|
+
raise ValueError(f"Received {status} from the Files API for {additional_headers['Range']}")
|
|
1436
|
+
return contents
|
|
1459
1437
|
|
|
1460
1438
|
self._do_parallel_download(remote_path, destination, parallelism, download_chunk)
|
|
1461
1439
|
|
|
@@ -2314,7 +2292,7 @@ class FilesExt(files.FilesAPI):
|
|
|
2314
2292
|
"""
|
|
2315
2293
|
Checks if response matches one of the known "URL expired" responses from the cloud storage providers.
|
|
2316
2294
|
"""
|
|
2317
|
-
if response.status_code
|
|
2295
|
+
if response.status_code not in (400, 403):
|
|
2318
2296
|
return False
|
|
2319
2297
|
|
|
2320
2298
|
try:
|
|
@@ -2326,6 +2304,10 @@ class FilesExt(files.FilesAPI):
|
|
|
2326
2304
|
if code is None:
|
|
2327
2305
|
return False
|
|
2328
2306
|
|
|
2307
|
+
if code.text == "ExpiredToken":
|
|
2308
|
+
# GCP, and AWS when the URL was signed with temporary credentials that have since expired.
|
|
2309
|
+
return True
|
|
2310
|
+
|
|
2329
2311
|
if code.text == "AuthenticationFailed":
|
|
2330
2312
|
# Azure
|
|
2331
2313
|
details = xml_root.find("AuthenticationErrorDetail")
|
|
@@ -2587,37 +2569,30 @@ class FilesExt(files.FilesAPI):
|
|
|
2587
2569
|
)
|
|
2588
2570
|
|
|
2589
2571
|
def _abort_multipart_upload(self, ctx: _UploadContext, session_token: str) -> None:
|
|
2590
|
-
"""Aborts ongoing multipart upload session to clean up incomplete file.
|
|
2591
|
-
builder = self._create_request_builder()
|
|
2592
|
-
abort_info = builder.build_abort_url(ctx.target_path, session_token, self._get_upload_url_expire_time())
|
|
2593
|
-
|
|
2594
|
-
def perform() -> requests.Response:
|
|
2595
|
-
return self._cloud_provider_session().request(
|
|
2596
|
-
"DELETE",
|
|
2597
|
-
abort_info.url,
|
|
2598
|
-
headers=abort_info.headers,
|
|
2599
|
-
data=b"",
|
|
2600
|
-
timeout=self._config.files_ext_network_transfer_inactivity_timeout_seconds,
|
|
2601
|
-
)
|
|
2572
|
+
"""Aborts ongoing multipart upload session to clean up incomplete file.
|
|
2602
2573
|
|
|
2603
|
-
|
|
2574
|
+
Best-effort, so sent once, without the API client's retries.
|
|
2575
|
+
"""
|
|
2576
|
+
escaped = _escape_multi_segment_path_parameter(ctx.target_path)
|
|
2577
|
+
abort_response = self._authenticated_session().request(
|
|
2578
|
+
"POST",
|
|
2579
|
+
f"{self._get_hostname()}/api/2.0/fs/files{escaped}",
|
|
2580
|
+
params={"action": "abort-upload", "upload_type": "multipart", "session_token": session_token},
|
|
2581
|
+
timeout=self._config.files_ext_network_transfer_inactivity_timeout_seconds,
|
|
2582
|
+
)
|
|
2604
2583
|
|
|
2605
|
-
if abort_response.
|
|
2584
|
+
if not abort_response.ok:
|
|
2606
2585
|
raise ValueError(abort_response)
|
|
2607
2586
|
|
|
2608
2587
|
def _abort_resumable_upload(self, resumable_upload_url: str, headers: dict[str, str]) -> None:
|
|
2609
|
-
"""Aborts ongoing resumable upload session to clean up incomplete file."""
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
timeout=self._config.files_ext_network_transfer_inactivity_timeout_seconds,
|
|
2618
|
-
)
|
|
2619
|
-
|
|
2620
|
-
abort_response = self._retry_cloud_idempotent_operation(perform)
|
|
2588
|
+
"""Aborts ongoing resumable upload session to clean up incomplete file. Best-effort, so sent once."""
|
|
2589
|
+
abort_response = self._cloud_provider_session().request(
|
|
2590
|
+
"DELETE",
|
|
2591
|
+
resumable_upload_url,
|
|
2592
|
+
headers=headers,
|
|
2593
|
+
data=b"",
|
|
2594
|
+
timeout=self._config.files_ext_network_transfer_inactivity_timeout_seconds,
|
|
2595
|
+
)
|
|
2621
2596
|
|
|
2622
2597
|
if abort_response.status_code not in (200, 201):
|
|
2623
2598
|
raise ValueError(abort_response)
|
|
@@ -2631,7 +2606,7 @@ class FilesExt(files.FilesAPI):
|
|
|
2631
2606
|
The session is created on first call and cached for reuse.
|
|
2632
2607
|
"""
|
|
2633
2608
|
if self._config.experimental_files_ext_enable_storage_proxy and self._dp_hostname_available:
|
|
2634
|
-
return self.
|
|
2609
|
+
return self._authenticated_session()
|
|
2635
2610
|
with self._cloud_provider_session_lock:
|
|
2636
2611
|
if self._cached_cloud_provider_session is None:
|
|
2637
2612
|
session = requests.Session()
|
|
File without changes
|
|
@@ -187,6 +187,76 @@ class AlertConfigurationTriggerType(Enum):
|
|
|
187
187
|
CUMULATIVE_SPENDING_EXCEEDED = "CUMULATIVE_SPENDING_EXCEEDED"
|
|
188
188
|
|
|
189
189
|
|
|
190
|
+
@dataclass
|
|
191
|
+
class AlertSpendStatus:
|
|
192
|
+
"""The calling user's spend against a single blocking threshold. Values may be omitted if live
|
|
193
|
+
spend or threshold data is temporarily unavailable."""
|
|
194
|
+
|
|
195
|
+
percent_consumed: Optional[str] = None
|
|
196
|
+
"""Percentage of the threshold consumed, as a decimal string rounded down to one decimal place (for
|
|
197
|
+
example, "68.4" means 68.4%). May exceed 100 when spend is over the threshold. Returns "0.0" if
|
|
198
|
+
there's no spend, and is omitted if the threshold is $0. For shared thresholds, this is the only
|
|
199
|
+
value returned; the absolute ``spend`` and ``threshold`` dollar amounts are withheld."""
|
|
200
|
+
|
|
201
|
+
scope_type: Optional[AlertConfigurationScopeType] = None
|
|
202
|
+
"""Whether the threshold is evaluated per individual user
|
|
203
|
+
(``ALERT_CONFIGURATION_SCOPE_TYPE_PER_USER``) or on the shared spend across all users
|
|
204
|
+
(``ALERT_CONFIGURATION_SCOPE_TYPE_SHARED``)."""
|
|
205
|
+
|
|
206
|
+
spend: Optional[str] = None
|
|
207
|
+
"""The calling user's live spend against this threshold, in USD at list price. Returns "0" if the
|
|
208
|
+
caller has no usage. Omitted for shared thresholds, where only ``percent_consumed`` is returned."""
|
|
209
|
+
|
|
210
|
+
threshold: Optional[str] = None
|
|
211
|
+
"""The calling user's effective threshold, in USD at list price. The effective threshold is the
|
|
212
|
+
actual threshold amount that applies to the user, after adjusting for any user or group
|
|
213
|
+
overrides. Omitted for shared thresholds, where only ``percent_consumed`` is returned."""
|
|
214
|
+
|
|
215
|
+
time_period: Optional[AlertConfigurationTimePeriod] = None
|
|
216
|
+
"""The time window the threshold applies to, for example ``MONTH``."""
|
|
217
|
+
|
|
218
|
+
def as_dict(self) -> dict:
|
|
219
|
+
"""Serializes the AlertSpendStatus into a dictionary suitable for use as a JSON request body."""
|
|
220
|
+
body = {}
|
|
221
|
+
if self.percent_consumed is not None:
|
|
222
|
+
body["percent_consumed"] = self.percent_consumed
|
|
223
|
+
if self.scope_type is not None:
|
|
224
|
+
body["scope_type"] = self.scope_type.value
|
|
225
|
+
if self.spend is not None:
|
|
226
|
+
body["spend"] = self.spend
|
|
227
|
+
if self.threshold is not None:
|
|
228
|
+
body["threshold"] = self.threshold
|
|
229
|
+
if self.time_period is not None:
|
|
230
|
+
body["time_period"] = self.time_period.value
|
|
231
|
+
return body
|
|
232
|
+
|
|
233
|
+
def as_shallow_dict(self) -> dict:
|
|
234
|
+
"""Serializes the AlertSpendStatus into a shallow dictionary of its immediate attributes."""
|
|
235
|
+
body = {}
|
|
236
|
+
if self.percent_consumed is not None:
|
|
237
|
+
body["percent_consumed"] = self.percent_consumed
|
|
238
|
+
if self.scope_type is not None:
|
|
239
|
+
body["scope_type"] = self.scope_type
|
|
240
|
+
if self.spend is not None:
|
|
241
|
+
body["spend"] = self.spend
|
|
242
|
+
if self.threshold is not None:
|
|
243
|
+
body["threshold"] = self.threshold
|
|
244
|
+
if self.time_period is not None:
|
|
245
|
+
body["time_period"] = self.time_period
|
|
246
|
+
return body
|
|
247
|
+
|
|
248
|
+
@classmethod
|
|
249
|
+
def from_dict(cls, d: Dict[str, Any]) -> AlertSpendStatus:
|
|
250
|
+
"""Deserializes the AlertSpendStatus from a dictionary."""
|
|
251
|
+
return cls(
|
|
252
|
+
percent_consumed=d.get("percent_consumed", None),
|
|
253
|
+
scope_type=_enum(d, "scope_type", AlertConfigurationScopeType),
|
|
254
|
+
spend=d.get("spend", None),
|
|
255
|
+
threshold=d.get("threshold", None),
|
|
256
|
+
time_period=_enum(d, "time_period", AlertConfigurationTimePeriod),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
190
260
|
@dataclass
|
|
191
261
|
class BudgetConfiguration:
|
|
192
262
|
account_id: Optional[str] = None
|
|
@@ -491,6 +561,45 @@ class BudgetResourceType(Enum):
|
|
|
491
561
|
BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY = "BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY"
|
|
492
562
|
|
|
493
563
|
|
|
564
|
+
@dataclass
|
|
565
|
+
class BudgetSpendStatus:
|
|
566
|
+
"""The calling user's live spend against the blocking thresholds of a single budget."""
|
|
567
|
+
|
|
568
|
+
alert_spend_statuses: Optional[List[AlertSpendStatus]] = None
|
|
569
|
+
"""The calling user's spend against each blocking threshold on this budget, one entry per scope
|
|
570
|
+
type and time period. A blocking threshold is a threshold that, once reached, blocks further
|
|
571
|
+
requests through Unity Gateway."""
|
|
572
|
+
|
|
573
|
+
name: Optional[str] = None
|
|
574
|
+
"""The resource name of this budget spend status, of the form
|
|
575
|
+
``accounts/{account_id}/budget-spend-statuses/{budget_id}``."""
|
|
576
|
+
|
|
577
|
+
def as_dict(self) -> dict:
|
|
578
|
+
"""Serializes the BudgetSpendStatus into a dictionary suitable for use as a JSON request body."""
|
|
579
|
+
body = {}
|
|
580
|
+
if self.alert_spend_statuses:
|
|
581
|
+
body["alert_spend_statuses"] = [v.as_dict() for v in self.alert_spend_statuses]
|
|
582
|
+
if self.name is not None:
|
|
583
|
+
body["name"] = self.name
|
|
584
|
+
return body
|
|
585
|
+
|
|
586
|
+
def as_shallow_dict(self) -> dict:
|
|
587
|
+
"""Serializes the BudgetSpendStatus into a shallow dictionary of its immediate attributes."""
|
|
588
|
+
body = {}
|
|
589
|
+
if self.alert_spend_statuses:
|
|
590
|
+
body["alert_spend_statuses"] = self.alert_spend_statuses
|
|
591
|
+
if self.name is not None:
|
|
592
|
+
body["name"] = self.name
|
|
593
|
+
return body
|
|
594
|
+
|
|
595
|
+
@classmethod
|
|
596
|
+
def from_dict(cls, d: Dict[str, Any]) -> BudgetSpendStatus:
|
|
597
|
+
"""Deserializes the BudgetSpendStatus from a dictionary."""
|
|
598
|
+
return cls(
|
|
599
|
+
alert_spend_statuses=_repeated_dict(d, "alert_spend_statuses", AlertSpendStatus), name=d.get("name", None)
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
|
|
494
603
|
@dataclass
|
|
495
604
|
class CreateBillingUsageDashboardResponse:
|
|
496
605
|
dashboard_id: Optional[str] = None
|
|
@@ -1156,6 +1265,45 @@ class ListBudgetPoliciesResponse:
|
|
|
1156
1265
|
)
|
|
1157
1266
|
|
|
1158
1267
|
|
|
1268
|
+
@dataclass
|
|
1269
|
+
class ListBudgetSpendStatusesResponse:
|
|
1270
|
+
"""Response for ListBudgetSpendStatuses."""
|
|
1271
|
+
|
|
1272
|
+
budget_spend_statuses: Optional[List[BudgetSpendStatus]] = None
|
|
1273
|
+
"""The calling user's spend status, one entry per returned budget."""
|
|
1274
|
+
|
|
1275
|
+
next_page_token: Optional[str] = None
|
|
1276
|
+
"""Token to pass as ``page_token`` to retrieve the next page. Absent when there are no more
|
|
1277
|
+
results. A page can contain fewer results than ``page_size``, or none, while this token is still
|
|
1278
|
+
set, so keep paging until it's absent."""
|
|
1279
|
+
|
|
1280
|
+
def as_dict(self) -> dict:
|
|
1281
|
+
"""Serializes the ListBudgetSpendStatusesResponse into a dictionary suitable for use as a JSON request body."""
|
|
1282
|
+
body = {}
|
|
1283
|
+
if self.budget_spend_statuses:
|
|
1284
|
+
body["budget_spend_statuses"] = [v.as_dict() for v in self.budget_spend_statuses]
|
|
1285
|
+
if self.next_page_token is not None:
|
|
1286
|
+
body["next_page_token"] = self.next_page_token
|
|
1287
|
+
return body
|
|
1288
|
+
|
|
1289
|
+
def as_shallow_dict(self) -> dict:
|
|
1290
|
+
"""Serializes the ListBudgetSpendStatusesResponse into a shallow dictionary of its immediate attributes."""
|
|
1291
|
+
body = {}
|
|
1292
|
+
if self.budget_spend_statuses:
|
|
1293
|
+
body["budget_spend_statuses"] = self.budget_spend_statuses
|
|
1294
|
+
if self.next_page_token is not None:
|
|
1295
|
+
body["next_page_token"] = self.next_page_token
|
|
1296
|
+
return body
|
|
1297
|
+
|
|
1298
|
+
@classmethod
|
|
1299
|
+
def from_dict(cls, d: Dict[str, Any]) -> ListBudgetSpendStatusesResponse:
|
|
1300
|
+
"""Deserializes the ListBudgetSpendStatusesResponse from a dictionary."""
|
|
1301
|
+
return cls(
|
|
1302
|
+
budget_spend_statuses=_repeated_dict(d, "budget_spend_statuses", BudgetSpendStatus),
|
|
1303
|
+
next_page_token=d.get("next_page_token", None),
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1306
|
+
|
|
1159
1307
|
class LogDeliveryConfigStatus(Enum):
|
|
1160
1308
|
"""Log Delivery Status
|
|
1161
1309
|
|
|
@@ -1949,6 +2097,27 @@ class BudgetsAPI:
|
|
|
1949
2097
|
res = self._api.do("GET", f"/api/2.1/accounts/{self._api.account_id}/budgets/{budget_id}", headers=headers)
|
|
1950
2098
|
return GetBudgetConfigurationResponse.from_dict(res)
|
|
1951
2099
|
|
|
2100
|
+
def get_budget_spend_status(self, name: str) -> BudgetSpendStatus:
|
|
2101
|
+
"""Get the calling user's live spend against the blocking thresholds of a single Unity Gateway budget.
|
|
2102
|
+
Any account user can call this for their own spend. Spend is reported in USD at list price and is
|
|
2103
|
+
near-real-time, so it may differ slightly from billing data. Returns NOT_FOUND if the budget doesn't
|
|
2104
|
+
exist or has no blocking thresholds.
|
|
2105
|
+
|
|
2106
|
+
:param name: str
|
|
2107
|
+
The resource name of the budget spend status to read, of the form
|
|
2108
|
+
``accounts/{account_id}/budget-spend-statuses/{budget_id}``. A ``budget_id`` that isn't a valid UUID
|
|
2109
|
+
fails with INVALID_PARAMETER_VALUE.
|
|
2110
|
+
|
|
2111
|
+
:returns: :class:`BudgetSpendStatus`
|
|
2112
|
+
"""
|
|
2113
|
+
|
|
2114
|
+
headers = {
|
|
2115
|
+
"Accept": "application/json",
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
res = self._api.do("GET", f"/api/2.1/{name}", headers=headers)
|
|
2119
|
+
return BudgetSpendStatus.from_dict(res)
|
|
2120
|
+
|
|
1952
2121
|
def list(self, *, page_token: Optional[str] = None) -> Iterator[BudgetConfiguration]:
|
|
1953
2122
|
"""Gets all budgets associated with this account.
|
|
1954
2123
|
|
|
@@ -1977,6 +2146,55 @@ class BudgetsAPI:
|
|
|
1977
2146
|
return
|
|
1978
2147
|
query["page_token"] = json["next_page_token"]
|
|
1979
2148
|
|
|
2149
|
+
def list_budget_spend_statuses(
|
|
2150
|
+
self,
|
|
2151
|
+
parent: str,
|
|
2152
|
+
*,
|
|
2153
|
+
filter: Optional[str] = None,
|
|
2154
|
+
page_size: Optional[int] = None,
|
|
2155
|
+
page_token: Optional[str] = None,
|
|
2156
|
+
) -> ListBudgetSpendStatusesResponse:
|
|
2157
|
+
"""List the calling user's live spend against the blocking thresholds across the account's Unity Gateway
|
|
2158
|
+
budgets. Any account user can call this for their own spend. Spend is reported in USD at list price
|
|
2159
|
+
and is near-real-time, so it may differ slightly from billing data. By default, returns every budget
|
|
2160
|
+
in the account that has a blocking threshold. Use ``filter`` to narrow results by workspace.
|
|
2161
|
+
|
|
2162
|
+
:param parent: str
|
|
2163
|
+
The parent account whose budget spend statuses to list, of the form ``accounts/{account_id}``.
|
|
2164
|
+
:param filter: str (optional)
|
|
2165
|
+
A filter expression that narrows the returned budgets by workspace. Only ``workspace_id`` is
|
|
2166
|
+
supported, in lower case with numeric workspace IDs, for example ``workspace_id = 123`` or
|
|
2167
|
+
``workspace_id IN (123, 456)``. Matches budgets that apply to any of the listed workspaces,
|
|
2168
|
+
including budgets that apply to all workspaces. Any other expression, such as an empty ``IN ()``
|
|
2169
|
+
list, fails with INVALID_PARAMETER_VALUE. If empty, returns every budget in the account that has a
|
|
2170
|
+
blocking threshold.
|
|
2171
|
+
:param page_size: int (optional)
|
|
2172
|
+
The maximum number of spend statuses to return per page. If unspecified or 0, at most 100 are
|
|
2173
|
+
returned. The maximum value is 100; values above 100 are coerced to 100. Negative values fail with
|
|
2174
|
+
INVALID_PARAMETER_VALUE. The server may return fewer results than requested, including zero, even
|
|
2175
|
+
when more pages remain; page until ``next_page_token`` is absent.
|
|
2176
|
+
:param page_token: str (optional)
|
|
2177
|
+
A page token from a previous ``ListBudgetSpendStatuses`` response, used to fetch the next page.
|
|
2178
|
+
Requests the first page if absent. All other request parameters except ``page_size`` must match the
|
|
2179
|
+
request that returned the token; otherwise the request fails with INVALID_PARAMETER_VALUE.
|
|
2180
|
+
|
|
2181
|
+
:returns: :class:`ListBudgetSpendStatusesResponse`
|
|
2182
|
+
"""
|
|
2183
|
+
|
|
2184
|
+
query = {}
|
|
2185
|
+
if filter is not None:
|
|
2186
|
+
query["filter"] = filter
|
|
2187
|
+
if page_size is not None:
|
|
2188
|
+
query["page_size"] = page_size
|
|
2189
|
+
if page_token is not None:
|
|
2190
|
+
query["page_token"] = page_token
|
|
2191
|
+
headers = {
|
|
2192
|
+
"Accept": "application/json",
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
res = self._api.do("GET", f"/api/2.1/{parent}/budget-spend-statuses", query=query, headers=headers)
|
|
2196
|
+
return ListBudgetSpendStatusesResponse.from_dict(res)
|
|
2197
|
+
|
|
1980
2198
|
def update(self, budget_id: str, budget: UpdateBudgetConfigurationBudget) -> UpdateBudgetConfigurationResponse:
|
|
1981
2199
|
"""Updates a budget configuration for an account. Both account and budget configuration are specified by
|
|
1982
2200
|
ID.
|
|
File without changes
|
|
@@ -7531,9 +7531,10 @@ class ModelProviderServiceConfig:
|
|
|
7531
7531
|
cross the trust boundary to the upstream provider."""
|
|
7532
7532
|
|
|
7533
7533
|
allow_all_targets: Optional[bool] = None
|
|
7534
|
-
"""When true,
|
|
7535
|
-
|
|
7536
|
-
|
|
7534
|
+
"""When true, allows models from the provider's built-in model catalog in addition to explicit
|
|
7535
|
+
``targets``. When false, only models listed in ``targets`` are routable. Defaults to false.
|
|
7536
|
+
CUSTOM providers have no built-in model catalog and must leave this false and list their models
|
|
7537
|
+
in ``targets``."""
|
|
7537
7538
|
|
|
7538
7539
|
amazon_bedrock: Optional[ModelProviderServiceConfigAmazonBedrockProviderConfig] = None
|
|
7539
7540
|
|
|
@@ -7588,8 +7589,9 @@ class ModelProviderServiceConfig:
|
|
|
7588
7589
|
"""Models and provider-native API types exposed by this provider service. Each entry must include
|
|
7589
7590
|
at least one ``native_api_types`` value. When ``allow_all_targets`` is false, at least one entry
|
|
7590
7591
|
is required and model service destinations can reference only listed models. When
|
|
7591
|
-
``allow_all_targets`` is true,
|
|
7592
|
-
|
|
7592
|
+
``allow_all_targets`` is true, models from the provider's built-in model catalog are also
|
|
7593
|
+
routable. CUSTOM providers must explicitly list their models here and cannot enable
|
|
7594
|
+
``allow_all_targets``."""
|
|
7593
7595
|
|
|
7594
7596
|
def as_dict(self) -> dict:
|
|
7595
7597
|
"""Serializes the ModelProviderServiceConfig into a dictionary suitable for use as a JSON request body."""
|
|
@@ -14828,8 +14830,8 @@ class AiGatewayAPI:
|
|
|
14828
14830
|
returned.
|
|
14829
14831
|
|
|
14830
14832
|
:param page_size: int (optional)
|
|
14831
|
-
Maximum number of MCP services to return. Defaults to 200 when unset or 0; the maximum is
|
|
14832
|
-
``page_token`` to retrieve additional pages.
|
|
14833
|
+
Maximum number of MCP services to return. Defaults to 200 when unset or 0; the maximum is 1000 for
|
|
14834
|
+
``view = BASIC`` and 200 for ``view = FULL``. Use ``page_token`` to retrieve additional pages.
|
|
14833
14835
|
:param page_token: str (optional)
|
|
14834
14836
|
Opaque pagination token from the previous response.
|
|
14835
14837
|
:param parent: str (optional)
|
|
@@ -14886,8 +14888,8 @@ class AiGatewayAPI:
|
|
|
14886
14888
|
``MANAGE``) are returned.
|
|
14887
14889
|
|
|
14888
14890
|
:param page_size: int (optional)
|
|
14889
|
-
Maximum number of provider services to return. Defaults to 200 when unset or 0; the maximum is
|
|
14890
|
-
Use ``page_token`` to retrieve additional pages.
|
|
14891
|
+
Maximum number of provider services to return. Defaults to 200 when unset or 0; the maximum is 1000
|
|
14892
|
+
for ``view = BASIC`` and 200 for ``view = FULL``. Use ``page_token`` to retrieve additional pages.
|
|
14891
14893
|
:param page_token: str (optional)
|
|
14892
14894
|
Opaque pagination token from the previous response.
|
|
14893
14895
|
:param parent: str (optional)
|
|
@@ -14944,8 +14946,8 @@ class AiGatewayAPI:
|
|
|
14944
14946
|
returned by default.
|
|
14945
14947
|
|
|
14946
14948
|
:param page_size: int (optional)
|
|
14947
|
-
Maximum number of model services to return. Defaults to 200 when unset or 0; the maximum is
|
|
14948
|
-
``page_token`` to retrieve additional pages.
|
|
14949
|
+
Maximum number of model services to return. Defaults to 200 when unset or 0; the maximum is 1000 for
|
|
14950
|
+
``view = BASIC`` and 200 for ``view = FULL``. Use ``page_token`` to retrieve additional pages.
|
|
14949
14951
|
:param page_token: str (optional)
|
|
14950
14952
|
Opaque pagination token from the previous response.
|
|
14951
14953
|
:param parent: str (optional)
|