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.
- databricks/sdk/__init__.py +18 -10
- databricks/sdk/credentials_provider.py +2 -2
- databricks/sdk/mixins/files.py +43 -15
- databricks/sdk/mixins/open_ai_client.py +28 -7
- databricks/sdk/oidc.py +6 -2
- databricks/sdk/service/{aibuilder.py → agentbricks.py} +5 -132
- databricks/sdk/service/apps.py +52 -46
- databricks/sdk/service/billing.py +9 -200
- databricks/sdk/service/catalog.py +5501 -7697
- databricks/sdk/service/cleanrooms.py +24 -54
- databricks/sdk/service/compute.py +456 -2515
- databricks/sdk/service/dashboards.py +1 -177
- databricks/sdk/service/database.py +34 -53
- databricks/sdk/service/files.py +2 -218
- databricks/sdk/service/iam.py +16 -295
- databricks/sdk/service/jobs.py +108 -1171
- databricks/sdk/service/marketplace.py +0 -573
- databricks/sdk/service/ml.py +76 -2445
- databricks/sdk/service/oauth2.py +122 -237
- databricks/sdk/service/pipelines.py +180 -752
- databricks/sdk/service/provisioning.py +0 -603
- databricks/sdk/service/serving.py +5 -577
- databricks/sdk/service/settings.py +192 -1560
- databricks/sdk/service/sharing.py +5 -470
- databricks/sdk/service/sql.py +117 -1704
- databricks/sdk/service/vectorsearch.py +0 -391
- databricks/sdk/service/workspace.py +250 -721
- databricks/sdk/version.py +1 -1
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/METADATA +1 -1
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/RECORD +34 -34
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/WHEEL +0 -0
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/licenses/LICENSE +0 -0
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/licenses/NOTICE +0 -0
- {databricks_sdk-0.58.0.dist-info → databricks_sdk-0.60.0.dist-info}/top_level.txt +0 -0
databricks/sdk/__init__.py
CHANGED
|
@@ -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
|
|
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.
|
|
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,
|
|
117
|
-
DisableLegacyFeaturesAPI, EnableExportNotebookAPI,
|
|
118
|
-
|
|
119
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
344
|
+
id_token_source=id_token_source,
|
|
345
345
|
disable_async=cfg.disable_async_token_refresh,
|
|
346
346
|
)
|
|
347
347
|
|
databricks/sdk/mixins/files.py
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
1290
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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="", #
|
|
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
|
-
|
|
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-
|
|
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.
|
databricks/sdk/service/apps.py
CHANGED
|
@@ -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."""
|