Skip to content

Call _resolve_host_metadata on Config init and make failures non-fatal#1318

Merged
hectorcast-db merged 2 commits intomainfrom
hectorcast-db/stack/resolve-host-metadata-on-init
Mar 11, 2026
Merged

Call _resolve_host_metadata on Config init and make failures non-fatal#1318
hectorcast-db merged 2 commits intomainfrom
hectorcast-db/stack/resolve-host-metadata-on-init

Conversation

@hectorcast-db
Copy link
Copy Markdown
Contributor

@hectorcast-db hectorcast-db commented Mar 10, 2026

🥞 Stacked PR

Use this link to review incremental changes.


Summary

Call _resolve_host_metadata() automatically during Config.__init__ so that account_id, workspace_id, discovery_url, and cloud are populated from the /.well-known/databricks-config endpoint before auth is initialized. Metadata fetch failures are non-fatal — a warning is logged and initialization continues with whatever the user has explicitly configured.

Why

_resolve_host_metadata() already existed but had to be called explicitly by callers who wanted auto-discovery. This meant that WorkspaceClient and AccountClient did not benefit from it out of the box. Beyond the missing call, the old implementation was also strictly fatal: any HTTP error or missing field (account_id, oidc_endpoint) raised a ValueError, making it unsafe to run automatically since not all hosts expose the endpoint.

This PR wires up the call during Config.__init__ (between _fix_host_if_needed and _validate) and hardens the implementation so it degrades gracefully: HTTP failures produce a warning, and missing optional fields are simply left unset. The only remaining hard failure is when a {account_id} template in oidc_endpoint cannot be substituted because no account_id is available — this is a configuration error that should still surface.

Auto-discovery is currently gated to hosts with experimental_is_unified_host=True (a # TODO: Enable this everywhere marks the guard) to avoid unintended network calls on standard workspace and account deployments until the endpoint is broadly available.

What changed

Interface changes

None. _resolve_host_metadata() remains private.

Behavioral changes

For hosts with experimental_is_unified_host=True: Config.__init__ now makes an HTTP request to {host}/.well-known/databricks-config and silently back-fills account_id, workspace_id, discovery_url, and cloud from the response. Previously this did not happen.

All other hosts: no change.

Internal changes

  • databricks/sdk/config.py: Added _resolve_host_metadata() call to Config.__init__. Added HostType.UNIFIED guard. Made HTTP failures non-fatal (warning + return). Removed mandatory-field assertions (account_id is required, discovery_url is required) — missing fields are now silently skipped.
  • tests/conftest.py: Added autouse stub_host_metadata fixture that mocks get_host_metadata for all unit tests, preventing unexpected network calls.
  • tests/test_config.py: Replaced the old requests_mock-based tests (which called _resolve_host_metadata() directly) with mocker.patch-based tests that exercise the full Config.__init__ path. Added test_resolve_host_metadata_skipped_for_non_unified to assert the guard works.

How is this tested?

Unit tests in tests/test_config.py cover: successful resolution of all fields, no-overwrite of pre-configured values, HTTP failure tolerance, missing oidc_endpoint, and the guard that skips non-unified hosts.

NO_CHANGELOG=true

@hectorcast-db hectorcast-db force-pushed the hectorcast-db/stack/resolve-host-metadata-on-init branch from df4fa68 to 238f0a5 Compare March 11, 2026 09:42
@hectorcast-db hectorcast-db force-pushed the hectorcast-db/stack/resolve-host-metadata-on-init branch from 238f0a5 to 63156f6 Compare March 11, 2026 09:44
@hectorcast-db hectorcast-db marked this pull request as ready for review March 11, 2026 09:44
github-merge-queue bot pushed a commit that referenced this pull request Mar 11, 2026
…e is_account_client docstrings (#1317)

## 🥞 Stacked PR
Use this
[link](https://github.com/databricks/databricks-sdk-py/pull/1317/files)
to review incremental changes.
-
[**stack/use-test-environment-type-in-integration-tests**](#1317)
[[Files
changed](https://github.com/databricks/databricks-sdk-py/pull/1317/files)]
-
[stack/resolve-host-metadata-on-init](#1318)
[[Files
changed](https://github.com/databricks/databricks-sdk-py/pull/1318/files/0eff155d0ca7fc796d878cf9ee332dac5149be6a..63156f63eb80992d0c25a7b341d0b19b77dc9527)]
-
[stack/cloud-from-host-metadata](#1320)
[[Files
changed](https://github.com/databricks/databricks-sdk-py/pull/1320/files/63156f63eb80992d0c25a7b341d0b19b77dc9527..f9b0c3e2df72ddecb0fccb0d59af46f3a06846d2)]
-
[stack/resolve-token-audience-from-host-metadata](#1321)
[[Files
changed](https://github.com/databricks/databricks-sdk-py/pull/1321/files/f9b0c3e2df72ddecb0fccb0d59af46f3a06846d2..d97bd75a5692faddc36d51d46208513e442e7c87)]
-
[stack/google-auth-use-host-metadata](#1322)
[[Files
changed](https://github.com/databricks/databricks-sdk-py/pull/1322/files/d97bd75a5692faddc36d51d46208513e442e7c87..87b4c1a35e3fe1abfb125069ba1590eeaecf34e9)]

---------
## Summary

Replace `is_account_client` heuristics and `DATABRICKS_ACCOUNT_ID`
presence checks in integration test fixtures with explicit
`TEST_ENVIRONMENT_TYPE`-based filtering. Also deprecate
`is_account_client` in docstrings across `Config` and `ApiClient`.

## Why

Integration test fixtures in `tests/integration/conftest.py` used two
different heuristics to decide whether a test should run:

1. `account_client.config.is_account_client` — inspects the host URL to
infer whether the SDK is talking to an account-level API. This is
unreliable now that unified hosts can serve both account and workspace
APIs, and the property already raises `ValueError` when
`experimental_is_unified_host` is set.
2. `"DATABRICKS_ACCOUNT_ID" in os.environ` — a proxy check used to skip
workspace fixtures on account environments. This is fragile and doesn't
express intent clearly.

The test orchestrator now sets `TEST_ENVIRONMENT_TYPE` explicitly to one
of `ACCOUNT`, `UC_ACCOUNT`, `WORKSPACE`, or `UC_WORKSPACE`. Using this
value directly makes fixture skip-guards authoritative and easy to
reason about.

## What changed

### Interface changes

None. No public SDK API changes.

### Behavioral changes

None for SDK users. Integration test fixture skip conditions are now
driven by `TEST_ENVIRONMENT_TYPE` instead of `is_account_client` and
`DATABRICKS_ACCOUNT_ID`.

### Internal changes

- **`tests/integration/conftest.py`**: All four client fixtures (`a`,
`ucacct`, `w`, `ucws`) now check `TEST_ENVIRONMENT_TYPE` against an
explicit allowlist instead of using `is_account_client` or
`DATABRICKS_ACCOUNT_ID`.
- **`databricks/sdk/config.py`**: Updated `is_account_client` docstring
to note deprecation — clients can now support both workspace and account
APIs from a single host.
- **`databricks/sdk/core.py`**: Added matching deprecation note to
`ApiClient.is_account_client`.

## How is this tested?

The changed code is test infrastructure itself. Correctness will be
validated when integration tests run against environments that set
`TEST_ENVIRONMENT_TYPE`.

NO_CHANGELOG=true
@hectorcast-db hectorcast-db force-pushed the hectorcast-db/stack/resolve-host-metadata-on-init branch from 63156f6 to cd35488 Compare March 11, 2026 12:02
@github-actions
Copy link
Copy Markdown

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: 1318
  • Commit SHA: cd35488c886dc7a57ff3b1f79d70d1089a3ab6cf

Checks will be approved automatically on success.

Copy link
Copy Markdown
Contributor

@tejaskochar-db tejaskochar-db left a comment

Choose a reason for hiding this comment

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

lgtm modulo question about removing existing tests already, while we're gating the unified behaviour with a flag.

"workspace_id": _DUMMY_WORKSPACE_ID,
},
{},
{"experimental_is_unified_host": True},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we're replacing a test for the general case with a test for the experimental flag case. Shouldn't we have both until the flag is removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually, this test was always for the unified path.
The always called the resolve_metadata_path, but now this is skipped if the flag is false.

_DUMMY_ACC_HOST,
{"oidc_endpoint": f"{_DUMMY_ACC_HOST}/oidc/accounts/{{account_id}}"},
{"account_id": _DUMMY_ACCOUNT_ID},
{"account_id": _DUMMY_ACCOUNT_ID, "experimental_is_unified_host": True},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ditto

{
"account_id": _DUMMY_ACCOUNT_ID,
"workspace_id": _DUMMY_WORKSPACE_ID,
"experimental_is_unified_host": True,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ditto

@hectorcast-db hectorcast-db added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit 3dd760d Mar 11, 2026
17 checks passed
@hectorcast-db hectorcast-db deleted the hectorcast-db/stack/resolve-host-metadata-on-init branch March 11, 2026 14:52
github-merge-queue bot pushed a commit to databricks/databricks-sdk-go that referenced this pull request Mar 16, 2026
## 🥞 Stacked PR
Use this
[link](https://github.com/databricks/databricks-sdk-go/pull/1542/files)
to review incremental changes.
-
[**stack/port/resolve-host-metadata-on-init**](#1542)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1542/files)]
-
[stack/port/resolve-token-audience-from-metadata](#1543)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1543/files/20b6cd4abc1a3284d586c88f802c4b7df2678062..9893d9cbbfe8baab7f7aeacb8ce7faf49026c86a)]
-
[stack/port/gcp-sa-token-non-blocking](#1544)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1544/files/9893d9cbbfe8baab7f7aeacb8ce7faf49026c86a..07e28b7aef05ada2f357f87faa749c6990be8173)]
-
[stack/port/test-environment-type](#1545)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1545/files/07e28b7aef05ada2f357f87faa749c6990be8173..0da1b0d546ab8842dffbd50aa55fb136bbeffddf)]
-
[stack/port/host-metadata-integration-test](#1546)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1546/files/0da1b0d546ab8842dffbd50aa55fb136bbeffddf..e9854aad19dc522ffe8def175bef3a3eabface2b)]
-
[stack/port/remove-unified-flag](#1547)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1547/files/e9854aad19dc522ffe8def175bef3a3eabface2b..fae626deb92c4671a0c8aa0f1e3e6bad1f8c5cc6)]
-
[stack/port/gcp-sa-from-metadata](#1548)
[[Files
changed](https://github.com/databricks/databricks-sdk-go/pull/1548/files/fae626deb92c4671a0c8aa0f1e3e6bad1f8c5cc6..ecb1dbeed4ed1990a74895c6ced958c05f16ffef)]

---------
## Summary
- Port of Python SDK PR
databricks/databricks-sdk-py#1318 and discovery
URL fix from PR
databricks/databricks-sdk-py#1332
- Extract `applyHostMetadata()` from `resolveHostMetadata()` for reuse
during config init
- Call host metadata resolution during `EnsureResolved()` for unified
hosts (gated behind `Experimental_IsUnifiedHost`), with non-fatal error
handling (warns on failure)
- OIDC endpoint from metadata is now treated as the OIDC root, with
`/.well-known/oauth-authorization-server` appended to form the full
discovery URL

## Test plan
- `TestEnsureResolved_ResolvesHostMetadata_WhenUnifiedHost` — verifies
fields populated from metadata
- `TestEnsureResolved_HostMetadataFailure_NonFatal` — 500 response,
config still resolves
- `TestEnsureResolved_HostMetadata_NoOidcEndpoint_NonFatal` — missing
oidc_endpoint, no error
-
`TestEnsureResolved_HostMetadata_MissingAccountIdWithPlaceholder_Warns`
— template needs account_id but missing
- Existing `resolveHostMetadata` tests updated for new discovery URL
format

NO_CHANGELOG=true

This pull request was AI-assisted by Isaac.
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