databricks-sdk 0.32.2__py3-none-any.whl → 0.33.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.

@@ -24,6 +24,7 @@ from databricks.sdk.service.catalog import (AccountMetastoreAssignmentsAPI,
24
24
  StorageCredentialsAPI,
25
25
  SystemSchemasAPI,
26
26
  TableConstraintsAPI, TablesAPI,
27
+ TemporaryTableCredentialsAPI,
27
28
  VolumesAPI, WorkspaceBindingsAPI)
28
29
  from databricks.sdk.service.compute import (ClusterPoliciesAPI, ClustersAPI,
29
30
  CommandExecutionAPI,
@@ -69,6 +70,8 @@ from databricks.sdk.service.settings import (AccountIpAccessListsAPI,
69
70
  CredentialsManagerAPI,
70
71
  CspEnablementAccountAPI,
71
72
  DefaultNamespaceAPI,
73
+ DisableLegacyAccessAPI,
74
+ DisableLegacyFeaturesAPI,
72
75
  EnhancedSecurityMonitoringAPI,
73
76
  EsmEnablementAccountAPI,
74
77
  IpAccessListsAPI,
@@ -253,6 +256,7 @@ class WorkspaceClient:
253
256
  self._system_schemas = SystemSchemasAPI(self._api_client)
254
257
  self._table_constraints = TableConstraintsAPI(self._api_client)
255
258
  self._tables = TablesAPI(self._api_client)
259
+ self._temporary_table_credentials = TemporaryTableCredentialsAPI(self._api_client)
256
260
  self._token_management = TokenManagementAPI(self._api_client)
257
261
  self._tokens = TokensAPI(self._api_client)
258
262
  self._users = UsersAPI(self._api_client)
@@ -676,6 +680,11 @@ class WorkspaceClient:
676
680
  """A table resides in the third layer of Unity Catalog’s three-level namespace."""
677
681
  return self._tables
678
682
 
683
+ @property
684
+ def temporary_table_credentials(self) -> TemporaryTableCredentialsAPI:
685
+ """Temporary Table Credentials refer to short-lived, downscoped credentials used to access cloud storage locationswhere table data is stored in Databricks."""
686
+ return self._temporary_table_credentials
687
+
679
688
  @property
680
689
  def token_management(self) -> TokenManagementAPI:
681
690
  """Enables administrators to get all tokens and delete tokens for other users."""
@@ -9,14 +9,15 @@ import pathlib
9
9
  import platform
10
10
  import subprocess
11
11
  import sys
12
+ import time
12
13
  from datetime import datetime
13
- from typing import Callable, Dict, List, Optional, Union
14
+ from typing import Callable, Dict, List, Optional, Tuple, Union
14
15
 
15
- import google.auth
16
+ import google.auth # type: ignore
16
17
  import requests
17
- from google.auth import impersonated_credentials
18
- from google.auth.transport.requests import Request
19
- from google.oauth2 import service_account
18
+ from google.auth import impersonated_credentials # type: ignore
19
+ from google.auth.transport.requests import Request # type: ignore
20
+ from google.oauth2 import service_account # type: ignore
20
21
 
21
22
  from .azure import add_sp_management_token, add_workspace_id_header
22
23
  from .oauth import (ClientCredentials, OAuthClient, Refreshable, Token,
@@ -698,6 +699,90 @@ def metadata_service(cfg: 'Config') -> Optional[CredentialsProvider]:
698
699
  return inner
699
700
 
700
701
 
702
+ # This Code is derived from Mlflow DatabricksModelServingConfigProvider
703
+ # https://github.com/mlflow/mlflow/blob/1219e3ef1aac7d337a618a352cd859b336cf5c81/mlflow/legacy_databricks_cli/configure/provider.py#L332
704
+ class ModelServingAuthProvider():
705
+ _MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH = "/var/credentials-secret/model-dependencies-oauth-token"
706
+
707
+ def __init__(self):
708
+ self.expiry_time = -1
709
+ self.current_token = None
710
+ self.refresh_duration = 300 # 300 Seconds
711
+
712
+ def should_fetch_model_serving_environment_oauth(self) -> bool:
713
+ """
714
+ Check whether this is the model serving environment
715
+ Additionally check if the oauth token file path exists
716
+ """
717
+
718
+ is_in_model_serving_env = (os.environ.get("IS_IN_DB_MODEL_SERVING_ENV")
719
+ or os.environ.get("IS_IN_DATABRICKS_MODEL_SERVING_ENV") or "false")
720
+ return (is_in_model_serving_env == "true"
721
+ and os.path.isfile(self._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH))
722
+
723
+ def get_model_dependency_oauth_token(self, should_retry=True) -> str:
724
+ # Use Cached value if it is valid
725
+ if self.current_token is not None and self.expiry_time > time.time():
726
+ return self.current_token
727
+
728
+ try:
729
+ with open(self._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH) as f:
730
+ oauth_dict = json.load(f)
731
+ self.current_token = oauth_dict["OAUTH_TOKEN"][0]["oauthTokenValue"]
732
+ self.expiry_time = time.time() + self.refresh_duration
733
+ except Exception as e:
734
+ # sleep and retry in case of any race conditions with OAuth refreshing
735
+ if should_retry:
736
+ logger.warning("Unable to read oauth token on first attmept in Model Serving Environment",
737
+ exc_info=e)
738
+ time.sleep(0.5)
739
+ return self.get_model_dependency_oauth_token(should_retry=False)
740
+ else:
741
+ raise RuntimeError(
742
+ "Unable to read OAuth credentials from the file mounted in Databricks Model Serving"
743
+ ) from e
744
+ return self.current_token
745
+
746
+ def get_databricks_host_token(self) -> Optional[Tuple[str, str]]:
747
+ if not self.should_fetch_model_serving_environment_oauth():
748
+ return None
749
+
750
+ # read from DB_MODEL_SERVING_HOST_ENV_VAR if available otherwise MODEL_SERVING_HOST_ENV_VAR
751
+ host = os.environ.get("DATABRICKS_MODEL_SERVING_HOST_URL") or os.environ.get(
752
+ "DB_MODEL_SERVING_HOST_URL")
753
+ token = self.get_model_dependency_oauth_token()
754
+
755
+ return (host, token)
756
+
757
+
758
+ @credentials_strategy('model-serving', [])
759
+ def model_serving_auth(cfg: 'Config') -> Optional[CredentialsProvider]:
760
+ try:
761
+ model_serving_auth_provider = ModelServingAuthProvider()
762
+ if not model_serving_auth_provider.should_fetch_model_serving_environment_oauth():
763
+ logger.debug("model-serving: Not in Databricks Model Serving, skipping")
764
+ return None
765
+ host, token = model_serving_auth_provider.get_databricks_host_token()
766
+ if token is None:
767
+ raise ValueError(
768
+ "Got malformed auth (empty token) when fetching auth implicitly available in Model Serving Environment. Please contact Databricks support"
769
+ )
770
+ if cfg.host is None:
771
+ cfg.host = host
772
+ except Exception as e:
773
+ logger.warning("Unable to get auth from Databricks Model Serving Environment", exc_info=e)
774
+ return None
775
+
776
+ logger.info("Using Databricks Model Serving Authentication")
777
+
778
+ def inner() -> Dict[str, str]:
779
+ # Call here again to get the refreshed token
780
+ _, token = model_serving_auth_provider.get_databricks_host_token()
781
+ return {"Authorization": f"Bearer {token}"}
782
+
783
+ return inner
784
+
785
+
701
786
  class DefaultCredentials:
702
787
  """ Select the first applicable credential provider from the chain """
703
788
 
@@ -706,7 +791,7 @@ class DefaultCredentials:
706
791
  self._auth_providers = [
707
792
  pat_auth, basic_auth, metadata_service, oauth_service_principal, azure_service_principal,
708
793
  github_oidc_azure, azure_cli, external_browser, databricks_cli, runtime_native_auth,
709
- google_credentials, google_id
794
+ google_credentials, google_id, model_serving_auth
710
795
  ]
711
796
 
712
797
  def auth_type(self) -> str: