Skip to content

Pass --profile to CLI token source and add --host fallback for older CLIs#1297

Merged
hectorcast-db merged 4 commits intomainfrom
hectorcast/pass-profile-to-cli-token-source
Feb 26, 2026
Merged

Pass --profile to CLI token source and add --host fallback for older CLIs#1297
hectorcast-db merged 4 commits intomainfrom
hectorcast/pass-profile-to-cli-token-source

Conversation

@hectorcast-db
Copy link
Contributor

@hectorcast-db hectorcast-db commented Feb 25, 2026

Why

Today databricks auth token --profile <name> fails to find a valid token even when one exists — because the token was stored under the host URL key (via --host), not the profile name key. The SDK's DatabricksCliTokenSource always passed --host regardless of whether a profile was configured, so the CLI never had a chance to do profile-based lookup.

This is a port of databricks-sdk-go#1497.

Changes

CliTokenSource

  • Added host_cmd optional parameter: a fallback --host command for CLIs too old to support --profile.
  • Extracted _exec_cli_command() helper to run a single CLI invocation.
  • Updated refresh() to try the primary command first; if it fails with "unknown flag: --profile", retry with host_cmd and emit a warning to upgrade the CLI.

DatabricksCliTokenSource

  • Extracted _build_host_args() static method from the existing inline --host argument construction.
  • When cfg.profile is set: uses --profile <name> as the primary command. If cfg.host is also present, builds a --host fallback via _build_host_args() for compatibility with older CLIs.
  • When cfg.profile is empty: unchanged — existing --host path is used.

Test plan

  • --profile set with host → primary cmd uses --profile, fallback --host cmd is built
  • --profile set without host → primary cmd uses --profile, no fallback
  • --profile not set → existing --host path unchanged
  • refresh(): --profile fails with "unknown flag: --profile" → retries with --host, succeeds
  • refresh(): --profile fails with real auth error → no retry, error propagated
  • refresh(): --profile fails, no host_cmd set → original error raised
  • All 24 existing + new tests pass

🤖 Generated with Claude Code

…CLIs

When cfg.profile is set, DatabricksCliTokenSource now uses
`databricks auth token --profile <name>` as the primary command
instead of `--host`. A --host fallback command is also built so that
if the CLI returns "unknown flag: --profile" (older CLI version), the
SDK retries with --host and emits a warning to upgrade.

Ported from databricks-sdk-go#1497.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ell scripts

Shell scripts (.sh) don't work on Windows. Replace with mocker.patch on
_run_subprocess, consistent with how other tests in this file are written.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@hectorcast-db hectorcast-db force-pushed the hectorcast/pass-profile-to-cli-token-source branch from 51a8971 to 56c57f1 Compare February 25, 2026 13:21
Copy link
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, mostly minor nits. Consider the comment with stdout or stderr

@@ -684,6 +688,18 @@ def refresh(self) -> oauth.Token:
message = stdout or stderr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't touch this but I think this or means if the CLI dumps usage text to stdout and the real error ("unknown flag: --profile") to stderr, message will be the usage text and the fallback in refresh() won't trigger. might want stdout + "\n" + stderr or at least check both. the fallback tests only mock stderr so this doesn't get caught today.

try:
return self._exec_cli_command(self._cmd)
except IOError as e:
if self._host_cmd is not None and "unknown flag: --profile" in str(e):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe worth a quick comment here noting which CLI version introduced --profile support (or a link to the CLI PR), so a future reader knows when this fallback can eventually be removed.

cli_path = self.__class__._find_executable(cli_path)

host_cmd = None
if cfg.profile:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: this guards against cfg.host being None! me gusta

access_token_field: str,
expiry_field: str,
disable_async: bool = True,
host_cmd: Optional[List[str]] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: host_cmd makes total sense in DatabricksCliTokenSource context but at the CliTokenSource level it's a bit opaque - fallback_cmd would be more self-documenting. totally fine to keep it if the Go SDK uses the same name for parity though.

- Rename host_cmd -> fallback_cmd for clarity at CliTokenSource level
- Fix message construction to include both stdout and stderr so
  "unknown flag: --profile" in stderr is never masked by usage text in stdout
- Add comment linking to Go PR for when the fallback can be removed
- Add test covering the stdout+stderr case

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/sdk-py

Inputs:

  • PR number: 1297
  • Commit SHA: fcbbf1c28b06f27c358b2e765a7d5995b892ee57

Checks will be approved automatically on success.

@hectorcast-db hectorcast-db added this pull request to the merge queue Feb 26, 2026
Merged via the queue into main with commit 3c3c1f3 Feb 26, 2026
17 checks passed
@hectorcast-db hectorcast-db deleted the hectorcast/pass-profile-to-cli-token-source branch February 26, 2026 07:07
github-merge-queue bot pushed a commit to databricks/databricks-sdk-java that referenced this pull request Feb 27, 2026
## Why

Today \`databricks auth token --profile <name>\` fails to find a valid
token even when one exists — because the token was stored under the host
URL key (via \`--host\`), not the profile name key. The SDK's
\`DatabricksCliCredentialsProvider\` always passed \`--host\` regardless
of whether a profile was configured, so the CLI never had a chance to do
profile-based lookup.

This is a port of
[databricks-sdk-py#1297](databricks/databricks-sdk-py#1297)
/
[databricks-sdk-go#1497](databricks/databricks-sdk-go#1497).

## Changes

### \`CliTokenSource\`
- Added \`fallbackCmd\` optional field: a fallback command for CLIs too
old to support \`--profile\`.
- Added inner \`CliCommandException extends IOException\`: its
\`getMessage()\` returns the clean stderr-based message (what users
see), while \`getFullOutput()\` exposes the combined stdout+stderr for
flag detection — avoiding verbose combined output in user-facing errors.
- Extracted \`execCliCommand()\` helper to run a single CLI invocation.
- Updated \`getToken()\` to try the primary command first; if it fails
with \`"unknown flag: --profile"\` (checked in full output across both
streams), retries with \`fallbackCmd\` and emits a warning to upgrade
the CLI.

### \`DatabricksCliCredentialsProvider\`
- Renamed \`buildCliCommand\` → \`buildHostArgs\` (reflects its role as
the \`--host\` legacy path).
- When \`cfg.profile\` is set: uses \`--profile <name>\` as the primary
command. If \`cfg.host\` is also present, builds a \`--host\` fallback
via \`buildHostArgs()\` for compatibility with older CLIs.
- When \`cfg.profile\` is empty: unchanged — existing \`--host\` path is
used.

## Test plan

- [x] \`--profile\` fails with \`"unknown flag: --profile"\` in stderr →
retries with \`--host\`, succeeds
- [x] \`--profile\` fails with \`"unknown flag: --profile"\` in stdout →
fallback still triggered
- [x] \`--profile\` fails with real auth error → no retry, error
propagated
- [x] \`fallbackCmd\` is \`null\` and \`--profile\` fails → original
error raised
- [x] All existing \`buildHostArgs\` tests (workspace, account, unified
host variants) pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants