databricks-sdk 0.58.0__py3-none-any.whl → 0.60.0__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.

Potentially problematic release.


This version of databricks-sdk might be problematic. Click here for more details.

Files changed (34) hide show
  1. databricks/sdk/__init__.py +18 -10
  2. databricks/sdk/credentials_provider.py +2 -2
  3. databricks/sdk/mixins/files.py +43 -15
  4. databricks/sdk/mixins/open_ai_client.py +28 -7
  5. databricks/sdk/oidc.py +6 -2
  6. databricks/sdk/service/{aibuilder.py → agentbricks.py} +5 -132
  7. databricks/sdk/service/apps.py +52 -46
  8. databricks/sdk/service/billing.py +9 -200
  9. databricks/sdk/service/catalog.py +5501 -7697
  10. databricks/sdk/service/cleanrooms.py +24 -54
  11. databricks/sdk/service/compute.py +456 -2515
  12. databricks/sdk/service/dashboards.py +1 -177
  13. databricks/sdk/service/database.py +34 -53
  14. databricks/sdk/service/files.py +2 -218
  15. databricks/sdk/service/iam.py +16 -295
  16. databricks/sdk/service/jobs.py +108 -1171
  17. databricks/sdk/service/marketplace.py +0 -573
  18. databricks/sdk/service/ml.py +76 -2445
  19. databricks/sdk/service/oauth2.py +122 -237
  20. databricks/sdk/service/pipelines.py +180 -752
  21. databricks/sdk/service/provisioning.py +0 -603
  22. databricks/sdk/service/serving.py +5 -577
  23. databricks/sdk/service/settings.py +192 -1560
  24. databricks/sdk/service/sharing.py +5 -470
  25. databricks/sdk/service/sql.py +117 -1704
  26. databricks/sdk/service/vectorsearch.py +0 -391
  27. databricks/sdk/service/workspace.py +250 -721
  28. databricks/sdk/version.py +1 -1
  29. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/METADATA +1 -1
  30. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/RECORD +34 -34
  31. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/WHEEL +0 -0
  32. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/licenses/LICENSE +0 -0
  33. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/licenses/NOTICE +0 -0
  34. {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/top_level.txt +0 -0
@@ -13,7 +13,7 @@ from databricks.sdk.mixins.files import DbfsExt, FilesExt
13
13
  from databricks.sdk.mixins.jobs import JobsExt
14
14
  from databricks.sdk.mixins.open_ai_client import ServingEndpointsExt
15
15
  from databricks.sdk.mixins.workspace import WorkspaceExt
16
- from databricks.sdk.service import aibuilder as pkg_aibuilder
16
+ from databricks.sdk.service import agentbricks as pkg_agentbricks
17
17
  from databricks.sdk.service import apps as pkg_apps
18
18
  from databricks.sdk.service import billing as pkg_billing
19
19
  from databricks.sdk.service import catalog as pkg_catalog
@@ -36,7 +36,7 @@ from databricks.sdk.service import sharing as pkg_sharing
36
36
  from databricks.sdk.service import sql as pkg_sql
37
37
  from databricks.sdk.service import vectorsearch as pkg_vectorsearch
38
38
  from databricks.sdk.service import workspace as pkg_workspace
39
- from databricks.sdk.service.aibuilder import AiBuilderAPI
39
+ from databricks.sdk.service.agentbricks import AgentBricksAPI
40
40
  from databricks.sdk.service.apps import AppsAPI
41
41
  from databricks.sdk.service.billing import (BillableUsageAPI, BudgetPolicyAPI,
42
42
  BudgetsAPI, LogDeliveryAPI,
@@ -97,7 +97,8 @@ from databricks.sdk.service.oauth2 import (AccountFederationPolicyAPI,
97
97
  OAuthPublishedAppsAPI,
98
98
  PublishedAppIntegrationAPI,
99
99
  ServicePrincipalFederationPolicyAPI,
100
- ServicePrincipalSecretsAPI)
100
+ ServicePrincipalSecretsAPI,
101
+ ServicePrincipalSecretsProxyAPI)
101
102
  from databricks.sdk.service.pipelines import PipelinesAPI
102
103
  from databricks.sdk.service.provisioning import (CredentialsAPI,
103
104
  EncryptionKeysAPI,
@@ -113,10 +114,11 @@ from databricks.sdk.service.settings import (
113
114
  AibiDashboardEmbeddingApprovedDomainsAPI, AutomaticClusterUpdateAPI,
114
115
  ComplianceSecurityProfileAPI, CredentialsManagerAPI,
115
116
  CspEnablementAccountAPI, DashboardEmailSubscriptionsAPI,
116
- DefaultNamespaceAPI, DisableLegacyAccessAPI, DisableLegacyDbfsAPI,
117
- DisableLegacyFeaturesAPI, EnableExportNotebookAPI, EnableIpAccessListsAPI,
118
- EnableNotebookTableClipboardAPI, EnableResultsDownloadingAPI,
119
- EnhancedSecurityMonitoringAPI, EsmEnablementAccountAPI, IpAccessListsAPI,
117
+ DefaultNamespaceAPI, DefaultWarehouseIdAPI, DisableLegacyAccessAPI,
118
+ DisableLegacyDbfsAPI, DisableLegacyFeaturesAPI, EnableExportNotebookAPI,
119
+ EnableIpAccessListsAPI, EnableNotebookTableClipboardAPI,
120
+ EnableResultsDownloadingAPI, EnhancedSecurityMonitoringAPI,
121
+ EsmEnablementAccountAPI, IpAccessListsAPI,
120
122
  LlmProxyPartnerPoweredAccountAPI, LlmProxyPartnerPoweredEnforceAPI,
121
123
  LlmProxyPartnerPoweredWorkspaceAPI, NetworkConnectivityAPI,
122
124
  NetworkPoliciesAPI, NotificationDestinationsAPI, PersonalComputeAPI,
@@ -238,7 +240,7 @@ class WorkspaceClient:
238
240
  serving_endpoints = ServingEndpointsExt(self._api_client)
239
241
  self._access_control = pkg_iam.AccessControlAPI(self._api_client)
240
242
  self._account_access_control_proxy = pkg_iam.AccountAccessControlProxyAPI(self._api_client)
241
- self._ai_builder = pkg_aibuilder.AiBuilderAPI(self._api_client)
243
+ self._agent_bricks = pkg_agentbricks.AgentBricksAPI(self._api_client)
242
244
  self._alerts = pkg_sql.AlertsAPI(self._api_client)
243
245
  self._alerts_legacy = pkg_sql.AlertsLegacyAPI(self._api_client)
244
246
  self._alerts_v2 = pkg_sql.AlertsV2API(self._api_client)
@@ -323,6 +325,7 @@ class WorkspaceClient:
323
325
  self._resource_quotas = pkg_catalog.ResourceQuotasAPI(self._api_client)
324
326
  self._schemas = pkg_catalog.SchemasAPI(self._api_client)
325
327
  self._secrets = pkg_workspace.SecretsAPI(self._api_client)
328
+ self._service_principal_secrets_proxy = pkg_oauth2.ServicePrincipalSecretsProxyAPI(self._api_client)
326
329
  self._service_principals = pkg_iam.ServicePrincipalsAPI(self._api_client)
327
330
  self._serving_endpoints = serving_endpoints
328
331
  serving_endpoints_data_plane_token_source = DataPlaneTokenSource(
@@ -374,9 +377,9 @@ class WorkspaceClient:
374
377
  return self._account_access_control_proxy
375
378
 
376
379
  @property
377
- def ai_builder(self) -> pkg_aibuilder.AiBuilderAPI:
380
+ def agent_bricks(self) -> pkg_agentbricks.AgentBricksAPI:
378
381
  """The Custom LLMs service manages state and powers the UI for the Custom LLM product."""
379
- return self._ai_builder
382
+ return self._agent_bricks
380
383
 
381
384
  @property
382
385
  def alerts(self) -> pkg_sql.AlertsAPI:
@@ -788,6 +791,11 @@ class WorkspaceClient:
788
791
  """The Secrets API allows you to manage secrets, secret scopes, and access permissions."""
789
792
  return self._secrets
790
793
 
794
+ @property
795
+ def service_principal_secrets_proxy(self) -> pkg_oauth2.ServicePrincipalSecretsProxyAPI:
796
+ """These APIs enable administrators to manage service principal secrets at the workspace level."""
797
+ return self._service_principal_secrets_proxy
798
+
791
799
  @property
792
800
  def service_principals(self) -> pkg_iam.ServicePrincipalsAPI:
793
801
  """Identities for use with jobs, automated tools, and systems such as scripts, apps, and CI/CD platforms."""
@@ -331,7 +331,7 @@ def file_oidc(cfg) -> Optional[CredentialsProvider]:
331
331
  # that provides a Databricks token from an IdTokenSource.
332
332
  def _oidc_credentials_provider(cfg, id_token_source: oidc.IdTokenSource) -> Optional[CredentialsProvider]:
333
333
  try:
334
- id_token = id_token_source.id_token()
334
+ id_token_source.id_token() # validate the id_token_source
335
335
  except Exception as e:
336
336
  logger.debug(f"Failed to get OIDC token: {e}")
337
337
  return None
@@ -341,7 +341,7 @@ def _oidc_credentials_provider(cfg, id_token_source: oidc.IdTokenSource) -> Opti
341
341
  token_endpoint=cfg.oidc_endpoints.token_endpoint,
342
342
  client_id=cfg.client_id,
343
343
  account_id=cfg.account_id,
344
- id_token=id_token,
344
+ id_token_source=id_token_source,
345
345
  disable_async=cfg.disable_async_token_refresh,
346
346
  )
347
347
 
@@ -28,7 +28,6 @@ from .._base_client import _BaseClient, _RawResponse, _StreamingResponse
28
28
  from .._property import _cached_property
29
29
  from ..config import Config
30
30
  from ..errors import AlreadyExists, NotFound
31
- from ..errors.customizer import _RetryAfterCustomizer
32
31
  from ..errors.mapper import _error_mapper
33
32
  from ..retries import retried
34
33
  from ..service import files
@@ -577,6 +576,27 @@ class _DbfsPath(_Path):
577
576
  return f"<_DbfsPath {self._path}>"
578
577
 
579
578
 
579
+ class _RetryableException(Exception):
580
+ """Base class for retryable exceptions in DBFS operations."""
581
+
582
+ def __init__(self, message: str, http_status_code: int):
583
+ super().__init__()
584
+ self.message = message
585
+ self.http_status_code = http_status_code
586
+
587
+ def __str__(self) -> str:
588
+ return f"{self.message} (HTTP Status: {self.http_status_code})"
589
+
590
+ @staticmethod
591
+ def make_error(response: requests.Response) -> "_RetryableException":
592
+ """Map the response to a retryable exception."""
593
+
594
+ return _RetryableException(
595
+ message=response.text,
596
+ http_status_code=response.status_code,
597
+ )
598
+
599
+
580
600
  class DbfsExt(files.DbfsAPI):
581
601
  __doc__ = files.DbfsAPI.__doc__
582
602
 
@@ -885,7 +905,7 @@ class FilesExt(files.FilesAPI):
885
905
  timeout=self._config.multipart_upload_single_chunk_upload_timeout_seconds,
886
906
  )
887
907
 
888
- upload_response = self._retry_idempotent_operation(perform, rewind)
908
+ upload_response = self._retry_cloud_idempotent_operation(perform, rewind)
889
909
 
890
910
  if upload_response.status_code in (200, 201):
891
911
  # Chunk upload successful
@@ -1097,7 +1117,7 @@ class FilesExt(files.FilesAPI):
1097
1117
  )
1098
1118
 
1099
1119
  try:
1100
- return self._retry_idempotent_operation(perform)
1120
+ return self._retry_cloud_idempotent_operation(perform)
1101
1121
  except RequestException:
1102
1122
  _LOG.warning("Failed to retrieve upload status")
1103
1123
  return None
@@ -1116,7 +1136,7 @@ class FilesExt(files.FilesAPI):
1116
1136
  # a 503 or 500 response, then you need to resume the interrupted upload from where it left off.
1117
1137
 
1118
1138
  # Let's follow that for all potentially retryable status codes.
1119
- # Together with the catch block below we replicate the logic in _retry_idempotent_operation().
1139
+ # Together with the catch block below we replicate the logic in _retry_databricks_idempotent_operation().
1120
1140
  if upload_response.status_code in self._RETRYABLE_STATUS_CODES:
1121
1141
  if retry_count < self._config.multipart_upload_max_retries:
1122
1142
  retry_count += 1
@@ -1243,7 +1263,7 @@ class FilesExt(files.FilesAPI):
1243
1263
  timeout=self._config.multipart_upload_single_chunk_upload_timeout_seconds,
1244
1264
  )
1245
1265
 
1246
- abort_response = self._retry_idempotent_operation(perform)
1266
+ abort_response = self._retry_cloud_idempotent_operation(perform)
1247
1267
 
1248
1268
  if abort_response.status_code not in (200, 201):
1249
1269
  raise ValueError(abort_response)
@@ -1265,7 +1285,7 @@ class FilesExt(files.FilesAPI):
1265
1285
  timeout=self._config.multipart_upload_single_chunk_upload_timeout_seconds,
1266
1286
  )
1267
1287
 
1268
- abort_response = self._retry_idempotent_operation(perform)
1288
+ abort_response = self._retry_cloud_idempotent_operation(perform)
1269
1289
 
1270
1290
  if abort_response.status_code not in (200, 201):
1271
1291
  raise ValueError(abort_response)
@@ -1283,23 +1303,31 @@ class FilesExt(files.FilesAPI):
1283
1303
  session.mount("http://", http_adapter)
1284
1304
  return session
1285
1305
 
1286
- def _retry_idempotent_operation(
1306
+ def _retry_cloud_idempotent_operation(
1287
1307
  self, operation: Callable[[], requests.Response], before_retry: Callable = None
1288
1308
  ) -> requests.Response:
1289
- """Perform given idempotent operation with necessary retries. Since operation is idempotent it's
1290
- safe to retry it for response codes where server state might have changed.
1309
+ """Perform given idempotent operation with necessary retries for requests to non Databricks APIs.
1310
+ For cloud APIs, we will retry on network errors and on server response codes.
1311
+ Since operation is idempotent it's safe to retry it for response codes where server state might have changed.
1291
1312
  """
1292
1313
 
1293
- def delegate():
1314
+ def delegate() -> requests.Response:
1294
1315
  response = operation()
1295
1316
  if response.status_code in self._RETRYABLE_STATUS_CODES:
1296
- attrs = {}
1297
- # this will assign "retry_after_secs" to the attrs, essentially making exception look retryable
1298
- _RetryAfterCustomizer().customize_error(response, attrs)
1299
- raise _error_mapper(response, attrs)
1317
+ raise _RetryableException.make_error(response)
1300
1318
  else:
1301
1319
  return response
1302
1320
 
1321
+ def extended_is_retryable(e: BaseException) -> Optional[str]:
1322
+ retry_reason_from_base = _BaseClient._is_retryable(e)
1323
+ if retry_reason_from_base is not None:
1324
+ return retry_reason_from_base
1325
+
1326
+ if isinstance(e, _RetryableException):
1327
+ # this is a retriable exception, but not a network error
1328
+ return f"retryable exception (status_code:{e.http_status_code})"
1329
+ return None
1330
+
1303
1331
  # following _BaseClient timeout
1304
1332
  retry_timeout_seconds = self._config.retry_timeout_seconds or 300
1305
1333
 
@@ -1307,7 +1335,7 @@ class FilesExt(files.FilesAPI):
1307
1335
  timeout=timedelta(seconds=retry_timeout_seconds),
1308
1336
  # also retry on network errors (connection error, connection timeout)
1309
1337
  # where we believe request didn't reach the server
1310
- is_retryable=_BaseClient._is_retryable,
1338
+ is_retryable=extended_is_retryable,
1311
1339
  before_retry=before_retry,
1312
1340
  )(delegate)()
1313
1341
 
@@ -4,6 +4,7 @@ from typing import Dict, Optional
4
4
  from requests import Response
5
5
 
6
6
  from databricks.sdk.service.serving import (ExternalFunctionRequestHttpMethod,
7
+ HttpRequestResponse,
7
8
  ServingEndpointsAPI)
8
9
 
9
10
 
@@ -88,15 +89,30 @@ class ServingEndpointsExt(ServingEndpointsAPI):
88
89
  """
89
90
  response = Response()
90
91
  response.status_code = 200
91
- server_response = super().http_request(
92
- connection_name=conn,
93
- method=method,
94
- path=path,
95
- headers=js.dumps(headers) if headers is not None else None,
96
- json=js.dumps(json) if json is not None else None,
97
- params=js.dumps(params) if params is not None else None,
92
+
93
+ # We currently don't call super.http_request because we need to pass in response_headers
94
+ # This is a temporary fix to get the headers we need for the MCP session id
95
+ # TODO: Remove this once we have a better way to get back the response headers
96
+ headers_to_capture = ["mcp-session-id"]
97
+ res = self._api.do(
98
+ "POST",
99
+ "/api/2.0/external-function",
100
+ body={
101
+ "connection_name": conn,
102
+ "method": method.value,
103
+ "path": path,
104
+ "headers": js.dumps(headers) if headers is not None else None,
105
+ "json": js.dumps(json) if json is not None else None,
106
+ "params": js.dumps(params) if params is not None else None,
107
+ },
108
+ headers={"Accept": "text/plain", "Content-Type": "application/json"},
109
+ raw=True,
110
+ response_headers=headers_to_capture,
98
111
  )
99
112
 
113
+ # Create HttpRequestResponse from the raw response
114
+ server_response = HttpRequestResponse.from_dict(res)
115
+
100
116
  # Read the content from the HttpRequestResponse object
101
117
  if hasattr(server_response, "contents") and hasattr(server_response.contents, "read"):
102
118
  raw_content = server_response.contents.read() # Read the bytes
@@ -109,4 +125,9 @@ class ServingEndpointsExt(ServingEndpointsAPI):
109
125
  else:
110
126
  raise ValueError("Contents must be bytes.")
111
127
 
128
+ # Copy headers from raw response to Response
129
+ for header_name in headers_to_capture:
130
+ if header_name in res:
131
+ response.headers[header_name] = res[header_name]
132
+
112
133
  return response
databricks/sdk/oidc.py CHANGED
@@ -188,14 +188,18 @@ class DatabricksOidcTokenSource(oauth.TokenSource):
188
188
  logger.debug("Client ID provided, authenticating with Workload Identity Federation")
189
189
 
190
190
  id_token = self._id_token_source.id_token()
191
+ return self._exchange_id_token(id_token)
191
192
 
193
+ # This function is used to create the OAuth client.
194
+ # It exists to make it easier to test.
195
+ def _exchange_id_token(self, id_token: IdToken) -> oauth.Token:
192
196
  client = oauth.ClientCredentials(
193
197
  client_id=self._client_id,
194
- client_secret="", # we have no (rotatable) secrets in OIDC flow
198
+ client_secret="", # there is no (rotatable) secrets in the OIDC flow
195
199
  token_url=self._token_endpoint,
196
200
  endpoint_params={
197
201
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
198
- "subject_token": id_token,
202
+ "subject_token": id_token.jwt,
199
203
  "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
200
204
  },
201
205
  scopes=["all-apis"],
@@ -15,73 +15,6 @@ _LOG = logging.getLogger("databricks.sdk")
15
15
  # all definitions in this file are in alphabetical order
16
16
 
17
17
 
18
- @dataclass
19
- class CancelCustomLlmOptimizationRunRequest:
20
- id: Optional[str] = None
21
-
22
-
23
- @dataclass
24
- class CreateCustomLlmRequest:
25
- name: str
26
- """Name of the custom LLM. Only alphanumeric characters and dashes allowed."""
27
-
28
- instructions: str
29
- """Instructions for the custom LLM to follow"""
30
-
31
- agent_artifact_path: Optional[str] = None
32
- """Optional: UC path for agent artifacts. If you are using a dataset that you only have read
33
- permissions, please provide a destination path where you have write permissions. Please provide
34
- this in catalog.schema format."""
35
-
36
- datasets: Optional[List[Dataset]] = None
37
- """Datasets used for training and evaluating the model, not for inference. Currently, only 1
38
- dataset is accepted."""
39
-
40
- guidelines: Optional[List[str]] = None
41
- """Guidelines for the custom LLM to adhere to"""
42
-
43
- def as_dict(self) -> dict:
44
- """Serializes the CreateCustomLlmRequest into a dictionary suitable for use as a JSON request body."""
45
- body = {}
46
- if self.agent_artifact_path is not None:
47
- body["agent_artifact_path"] = self.agent_artifact_path
48
- if self.datasets:
49
- body["datasets"] = [v.as_dict() for v in self.datasets]
50
- if self.guidelines:
51
- body["guidelines"] = [v for v in self.guidelines]
52
- if self.instructions is not None:
53
- body["instructions"] = self.instructions
54
- if self.name is not None:
55
- body["name"] = self.name
56
- return body
57
-
58
- def as_shallow_dict(self) -> dict:
59
- """Serializes the CreateCustomLlmRequest into a shallow dictionary of its immediate attributes."""
60
- body = {}
61
- if self.agent_artifact_path is not None:
62
- body["agent_artifact_path"] = self.agent_artifact_path
63
- if self.datasets:
64
- body["datasets"] = self.datasets
65
- if self.guidelines:
66
- body["guidelines"] = self.guidelines
67
- if self.instructions is not None:
68
- body["instructions"] = self.instructions
69
- if self.name is not None:
70
- body["name"] = self.name
71
- return body
72
-
73
- @classmethod
74
- def from_dict(cls, d: Dict[str, Any]) -> CreateCustomLlmRequest:
75
- """Deserializes the CreateCustomLlmRequest from a dictionary."""
76
- return cls(
77
- agent_artifact_path=d.get("agent_artifact_path", None),
78
- datasets=_repeated_dict(d, "datasets", Dataset),
79
- guidelines=d.get("guidelines", None),
80
- instructions=d.get("instructions", None),
81
- name=d.get("name", None),
82
- )
83
-
84
-
85
18
  @dataclass
86
19
  class CustomLlm:
87
20
  name: str
@@ -90,9 +23,6 @@ class CustomLlm:
90
23
  instructions: str
91
24
  """Instructions for the custom LLM to follow"""
92
25
 
93
- optimization_state: State
94
- """If optimization is kicked off, tracks the state of the custom LLM"""
95
-
96
26
  agent_artifact_path: Optional[str] = None
97
27
 
98
28
  creation_time: Optional[str] = None
@@ -112,6 +42,9 @@ class CustomLlm:
112
42
 
113
43
  id: Optional[str] = None
114
44
 
45
+ optimization_state: Optional[State] = None
46
+ """If optimization is kicked off, tracks the state of the custom LLM"""
47
+
115
48
  def as_dict(self) -> dict:
116
49
  """Serializes the CustomLlm into a dictionary suitable for use as a JSON request body."""
117
50
  body = {}
@@ -203,12 +136,6 @@ class Dataset:
203
136
  return cls(table=_from_dict(d, "table", Table))
204
137
 
205
138
 
206
- @dataclass
207
- class StartCustomLlmOptimizationRunRequest:
208
- id: Optional[str] = None
209
- """The Id of the tile."""
210
-
211
-
212
139
  class State(Enum):
213
140
  """States of Custom LLM optimization lifecycle."""
214
141
 
@@ -263,61 +190,7 @@ class Table:
263
190
  )
264
191
 
265
192
 
266
- @dataclass
267
- class UpdateCustomLlmRequest:
268
- custom_llm: CustomLlm
269
- """The CustomLlm containing the fields which should be updated."""
270
-
271
- update_mask: str
272
- """The list of the CustomLlm fields to update. These should correspond to the values (or lack
273
- thereof) present in `custom_llm`.
274
-
275
- The field mask must be a single string, with multiple fields separated by commas (no spaces).
276
- The field path is relative to the resource object, using a dot (`.`) to navigate sub-fields
277
- (e.g., `author.given_name`). Specification of elements in sequence or map fields is not allowed,
278
- as only the entire collection field can be specified. Field names must exactly match the
279
- resource field names.
280
-
281
- A field mask of `*` indicates full replacement. It’s recommended to always explicitly list the
282
- fields being updated and avoid using `*` wildcards, as it can lead to unintended results if the
283
- API changes in the future."""
284
-
285
- id: Optional[str] = None
286
- """The id of the custom llm"""
287
-
288
- def as_dict(self) -> dict:
289
- """Serializes the UpdateCustomLlmRequest into a dictionary suitable for use as a JSON request body."""
290
- body = {}
291
- if self.custom_llm:
292
- body["custom_llm"] = self.custom_llm.as_dict()
293
- if self.id is not None:
294
- body["id"] = self.id
295
- if self.update_mask is not None:
296
- body["update_mask"] = self.update_mask
297
- return body
298
-
299
- def as_shallow_dict(self) -> dict:
300
- """Serializes the UpdateCustomLlmRequest into a shallow dictionary of its immediate attributes."""
301
- body = {}
302
- if self.custom_llm:
303
- body["custom_llm"] = self.custom_llm
304
- if self.id is not None:
305
- body["id"] = self.id
306
- if self.update_mask is not None:
307
- body["update_mask"] = self.update_mask
308
- return body
309
-
310
- @classmethod
311
- def from_dict(cls, d: Dict[str, Any]) -> UpdateCustomLlmRequest:
312
- """Deserializes the UpdateCustomLlmRequest from a dictionary."""
313
- return cls(
314
- custom_llm=_from_dict(d, "custom_llm", CustomLlm),
315
- id=d.get("id", None),
316
- update_mask=d.get("update_mask", None),
317
- )
318
-
319
-
320
- class AiBuilderAPI:
193
+ class AgentBricksAPI:
321
194
  """The Custom LLMs service manages state and powers the UI for the Custom LLM product."""
322
195
 
323
196
  def __init__(self, api_client):
@@ -397,7 +270,7 @@ class AiBuilderAPI:
397
270
  "Accept": "application/json",
398
271
  }
399
272
 
400
- self._api.do("DELETE", f"/api/2.0/custom-lms/{id}", headers=headers)
273
+ self._api.do("DELETE", f"/api/2.0/custom-llms/{id}", headers=headers)
401
274
 
402
275
  def get_custom_llm(self, id: str) -> CustomLlm:
403
276
  """Get a Custom LLM.
@@ -602,45 +602,13 @@ class AppPermissionsDescription:
602
602
  )
603
603
 
604
604
 
605
- @dataclass
606
- class AppPermissionsRequest:
607
- access_control_list: Optional[List[AppAccessControlRequest]] = None
608
-
609
- app_name: Optional[str] = None
610
- """The app for which to get or manage permissions."""
611
-
612
- def as_dict(self) -> dict:
613
- """Serializes the AppPermissionsRequest into a dictionary suitable for use as a JSON request body."""
614
- body = {}
615
- if self.access_control_list:
616
- body["access_control_list"] = [v.as_dict() for v in self.access_control_list]
617
- if self.app_name is not None:
618
- body["app_name"] = self.app_name
619
- return body
620
-
621
- def as_shallow_dict(self) -> dict:
622
- """Serializes the AppPermissionsRequest into a shallow dictionary of its immediate attributes."""
623
- body = {}
624
- if self.access_control_list:
625
- body["access_control_list"] = self.access_control_list
626
- if self.app_name is not None:
627
- body["app_name"] = self.app_name
628
- return body
629
-
630
- @classmethod
631
- def from_dict(cls, d: Dict[str, Any]) -> AppPermissionsRequest:
632
- """Deserializes the AppPermissionsRequest from a dictionary."""
633
- return cls(
634
- access_control_list=_repeated_dict(d, "access_control_list", AppAccessControlRequest),
635
- app_name=d.get("app_name", None),
636
- )
637
-
638
-
639
605
  @dataclass
640
606
  class AppResource:
641
607
  name: str
642
608
  """Name of the App Resource."""
643
609
 
610
+ database: Optional[AppResourceDatabase] = None
611
+
644
612
  description: Optional[str] = None
645
613
  """Description of the App Resource."""
646
614
 
@@ -657,6 +625,8 @@ class AppResource:
657
625
  def as_dict(self) -> dict:
658
626
  """Serializes the AppResource into a dictionary suitable for use as a JSON request body."""
659
627
  body = {}
628
+ if self.database:
629
+ body["database"] = self.database.as_dict()
660
630
  if self.description is not None:
661
631
  body["description"] = self.description
662
632
  if self.job:
@@ -676,6 +646,8 @@ class AppResource:
676
646
  def as_shallow_dict(self) -> dict:
677
647
  """Serializes the AppResource into a shallow dictionary of its immediate attributes."""
678
648
  body = {}
649
+ if self.database:
650
+ body["database"] = self.database
679
651
  if self.description is not None:
680
652
  body["description"] = self.description
681
653
  if self.job:
@@ -696,6 +668,7 @@ class AppResource:
696
668
  def from_dict(cls, d: Dict[str, Any]) -> AppResource:
697
669
  """Deserializes the AppResource from a dictionary."""
698
670
  return cls(
671
+ database=_from_dict(d, "database", AppResourceDatabase),
699
672
  description=d.get("description", None),
700
673
  job=_from_dict(d, "job", AppResourceJob),
701
674
  name=d.get("name", None),
@@ -706,6 +679,51 @@ class AppResource:
706
679
  )
707
680
 
708
681
 
682
+ @dataclass
683
+ class AppResourceDatabase:
684
+ instance_name: str
685
+
686
+ database_name: str
687
+
688
+ permission: AppResourceDatabaseDatabasePermission
689
+
690
+ def as_dict(self) -> dict:
691
+ """Serializes the AppResourceDatabase into a dictionary suitable for use as a JSON request body."""
692
+ body = {}
693
+ if self.database_name is not None:
694
+ body["database_name"] = self.database_name
695
+ if self.instance_name is not None:
696
+ body["instance_name"] = self.instance_name
697
+ if self.permission is not None:
698
+ body["permission"] = self.permission.value
699
+ return body
700
+
701
+ def as_shallow_dict(self) -> dict:
702
+ """Serializes the AppResourceDatabase into a shallow dictionary of its immediate attributes."""
703
+ body = {}
704
+ if self.database_name is not None:
705
+ body["database_name"] = self.database_name
706
+ if self.instance_name is not None:
707
+ body["instance_name"] = self.instance_name
708
+ if self.permission is not None:
709
+ body["permission"] = self.permission
710
+ return body
711
+
712
+ @classmethod
713
+ def from_dict(cls, d: Dict[str, Any]) -> AppResourceDatabase:
714
+ """Deserializes the AppResourceDatabase from a dictionary."""
715
+ return cls(
716
+ database_name=d.get("database_name", None),
717
+ instance_name=d.get("instance_name", None),
718
+ permission=_enum(d, "permission", AppResourceDatabaseDatabasePermission),
719
+ )
720
+
721
+
722
+ class AppResourceDatabaseDatabasePermission(Enum):
723
+
724
+ CAN_CONNECT_AND_CREATE = "CAN_CONNECT_AND_CREATE"
725
+
726
+
709
727
  @dataclass
710
728
  class AppResourceJob:
711
729
  id: str
@@ -1109,18 +1127,6 @@ class ListAppsResponse:
1109
1127
  return cls(apps=_repeated_dict(d, "apps", App), next_page_token=d.get("next_page_token", None))
1110
1128
 
1111
1129
 
1112
- @dataclass
1113
- class StartAppRequest:
1114
- name: Optional[str] = None
1115
- """The name of the app."""
1116
-
1117
-
1118
- @dataclass
1119
- class StopAppRequest:
1120
- name: Optional[str] = None
1121
- """The name of the app."""
1122
-
1123
-
1124
1130
  class AppsAPI:
1125
1131
  """Apps run directly on a customer’s Databricks instance, integrate with their data, use and extend
1126
1132
  Databricks services, and enable users to interact through single sign-on."""