Skip to content

Commit 2fa3228

Browse files
Add DATABRICKS_OIDC_TOKEN_FILEPATH env var support (#1334)
## Summary The Go SDK, CLI, and Terraform all use `DATABRICKS_OIDC_TOKEN_FILEPATH`, while the Python SDK used `DATABRICKS_OIDC_TOKEN_FILE`. This mismatch caused silent failures for users coming from Go/CLI/Terraform. This PR: - Adds an `env_aliases` mechanism to `ConfigAttribute` so a config field can be loaded from multiple env vars with clear precedence (primary > alias) - Makes `DATABRICKS_OIDC_TOKEN_FILEPATH` the primary env var, keeping `DATABRICKS_OIDC_TOKEN_FILE` as a backward-compatible alias - Reports alias usage in `debug_string` output ## Test plan - [x] Alias loads when primary is not set - [x] Primary takes precedence over alias when both are set - [x] Constructor arg takes precedence over both env vars
1 parent 388f703 commit 2fa3228

3 files changed

Lines changed: 43 additions & 2 deletions

File tree

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Release v0.103.0
44

55
### New Features and Improvements
6+
* Accept `DATABRICKS_OIDC_TOKEN_FILEPATH` environment variable for consistency with other Databricks SDKs (Go, CLI, Terraform). The previous `DATABRICKS_OIDC_TOKEN_FILE` is still supported as an alias.
67

78
### Security
89

databricks/sdk/config.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@ class ConfigAttribute:
3434
transform: type = str
3535
_custom_transform = None
3636

37-
def __init__(self, env: str = None, auth: str = None, sensitive: bool = False, transform=None):
37+
def __init__(
38+
self, env: str = None, auth: str = None, sensitive: bool = False, transform=None, env_aliases: List[str] = None
39+
):
3840
self.env = env
3941
self.auth = auth
4042
self.sensitive = sensitive
4143
self._custom_transform = transform
44+
self.env_aliases = env_aliases or []
4245

4346
def __get__(self, cfg: "Config", owner):
4447
if not cfg:
@@ -109,7 +112,10 @@ class Config:
109112

110113
# Environment variable for OIDC token.
111114
oidc_token_env: str = ConfigAttribute(env="DATABRICKS_OIDC_TOKEN_ENV", auth="env-oidc")
112-
oidc_token_filepath: str = ConfigAttribute(env="DATABRICKS_OIDC_TOKEN_FILE", auth="file-oidc")
115+
# The DATABRICKS_OIDC_TOKEN_FILE alias is kept for backward compatibility.
116+
oidc_token_filepath: str = ConfigAttribute(
117+
env="DATABRICKS_OIDC_TOKEN_FILEPATH", auth="file-oidc", env_aliases=["DATABRICKS_OIDC_TOKEN_FILE"]
118+
)
113119

114120
username: str = ConfigAttribute(env="DATABRICKS_USERNAME", auth="basic")
115121
password: str = ConfigAttribute(env="DATABRICKS_PASSWORD", auth="basic", sensitive=True)
@@ -557,6 +563,11 @@ def debug_string(self) -> str:
557563
for attr in Config.attributes():
558564
if attr.env and os.environ.get(attr.env):
559565
envs_used.append(attr.env)
566+
else:
567+
for alias in attr.env_aliases:
568+
if os.environ.get(alias):
569+
envs_used.append(alias)
570+
break
560571
value = getattr(self, attr.name)
561572
if not value:
562573
continue
@@ -709,6 +720,11 @@ def _load_from_env(self):
709720
if attr.name in self._inner:
710721
continue
711722
value = os.environ.get(attr.env)
723+
if not value:
724+
for alias in attr.env_aliases:
725+
value = os.environ.get(alias)
726+
if value:
727+
break
712728
if not value:
713729
continue
714730
self.__setattr__(attr.name, value)

tests/test_config.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,30 @@ def test_config_host_url_format_check(mocker, host, expected):
4747
assert Config(host=host).host == expected
4848

4949

50+
def test_oidc_token_filepath_env_alias(monkeypatch, mocker):
51+
monkeypatch.setenv("DATABRICKS_HOST", "https://abc.def.ghi")
52+
monkeypatch.setenv("DATABRICKS_OIDC_TOKEN_FILE", "/tmp/token")
53+
monkeypatch.delenv("DATABRICKS_OIDC_TOKEN_FILEPATH", raising=False)
54+
mocker.patch("databricks.sdk.config.Config.init_auth")
55+
assert Config().oidc_token_filepath == "/tmp/token"
56+
57+
58+
def test_oidc_token_filepath_env_primary_precedence(monkeypatch, mocker):
59+
monkeypatch.setenv("DATABRICKS_HOST", "https://abc.def.ghi")
60+
monkeypatch.setenv("DATABRICKS_OIDC_TOKEN_FILEPATH", "/tmp/primary")
61+
monkeypatch.setenv("DATABRICKS_OIDC_TOKEN_FILE", "/tmp/alias")
62+
mocker.patch("databricks.sdk.config.Config.init_auth")
63+
assert Config().oidc_token_filepath == "/tmp/primary"
64+
65+
66+
def test_oidc_token_filepath_env_constructor_precedence(monkeypatch, mocker):
67+
monkeypatch.setenv("DATABRICKS_HOST", "https://abc.def.ghi")
68+
monkeypatch.setenv("DATABRICKS_OIDC_TOKEN_FILEPATH", "/tmp/env")
69+
monkeypatch.setenv("DATABRICKS_OIDC_TOKEN_FILE", "/tmp/alias")
70+
mocker.patch("databricks.sdk.config.Config.init_auth")
71+
assert Config(oidc_token_filepath="/tmp/constructor").oidc_token_filepath == "/tmp/constructor"
72+
73+
5074
def test_extra_and_upstream_user_agent(monkeypatch):
5175

5276
class MockUname:

0 commit comments

Comments
 (0)