Skip to content

feat(apps): add databricks.apps module for Apps runtime client construction#1398

Open
jamesbroadhead wants to merge 1 commit intodatabricks:mainfrom
jamesbroadhead:jb/sdk-01-databricks-apps-module
Open

feat(apps): add databricks.apps module for Apps runtime client construction#1398
jamesbroadhead wants to merge 1 commit intodatabricks:mainfrom
jamesbroadhead:jb/sdk-01-databricks-apps-module

Conversation

@jamesbroadhead
Copy link
Copy Markdown

Summary

Adds a first-class databricks.apps module with helpers for code running inside Databricks Apps containers. Addresses the SDK-01 gap from internal field feedback — the historical workaround (popping DATABRICKS_CLIENT_ID / DATABRICKS_CLIENT_SECRET from os.environ to avoid a dual-auth validation error) is not thread-safe and forces ~50 lines of boilerplate into every custom agent app.

Public API

from databricks.apps import (
    get_workspace_client,         # app's SP identity (OAuth M2M)
    get_user_workspace_client,    # user OBO (PAT via X-Forwarded-Access-Token)
    get_mcp_client,               # placeholder, SDK-02
)

# In a FastAPI / Flask / Django handler:
def handler(request):
    user = get_user_workspace_client(request)        # reads X-Forwarded-Access-Token
    # or explicit token:
    user = get_user_workspace_client(token=...)

    sp = get_workspace_client()                      # SP identity

Why this is the right fix

The root cause is that WorkspaceClient(token=..., host=...) raises
more than one authorization method configured: oauth and pat when SP env vars are
also set — which is always true inside an Apps container. Both helpers here pin
auth_type explicitly (oauth-m2m and pat) so the validator never sees ambiguous
config. No env mutation, no global state, safe under concurrency.

get_mcp_client() is a placeholder that raises NotImplementedError with a pointer
to the SDK-02 follow-up so dependent code can import the symbol today and adopt the
real implementation when it lands.

Test plan

  • pytest tests/apps/ — 8 tests covering OAuth-M2M wiring, OBO header extraction (case-insensitive), explicit-token path, dual-auth regression, env-non-mutation invariant, missing-creds error paths, MCP placeholder
  • Smoke-import: import databricks.sdk; import databricks.apps both succeed
  • Tests assert on WorkspaceClient constructor kwargs rather than the constructed Config object, avoiding the SDK's eager host-metadata resolution in unit tests
  • Integration test in a real Apps container (draft — pending)

Out of scope

  • get_mcp_client() real implementation — tracked as SDK-02 (depends on mcp_server resource type being honored at runtime)
  • Backport to older SDK release lines

This pull request and its description were written by Claude (claude.ai).

Adds a first-class `databricks.apps` module with three helpers for code
running inside Databricks Apps containers:

  - get_workspace_client(): SP-authenticated client. Uses OAuth M2M with the
    SP credentials injected by the Apps runtime. Pins auth_type="oauth-m2m"
    so the SDK does not also attempt to read DATABRICKS_TOKEN and raise a
    dual-auth validation error.

  - get_user_workspace_client(request=..., token=...): OBO client. Reads the
    user's access token from X-Forwarded-Access-Token on the request, or
    accepts an explicit token kwarg. Pins auth_type="pat" for the same
    reason. Does not mutate os.environ, so it is safe to call concurrently
    from multiple request handlers (the historical workaround of popping SP
    env vars is not thread-safe).

  - get_mcp_client(): placeholder that raises NotImplementedError with a
    clear pointer to the SDK-02 follow-up. Lets dependent code import the
    symbol today and adopt the real implementation when it lands.

Tests assert on the kwargs passed to WorkspaceClient rather than on its
constructed Config object to avoid the SDK's eager host-metadata resolution
during unit tests.

Addresses the "SDK-01" gap from the EMEA Apps Gaps That Matter doc.

Co-authored-by: Isaac
@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: 1398
  • Commit SHA: ce7b8d36e327ff36cf4be4c017546bd424b6c5de

Checks will be approved automatically on success.

@jamesbroadhead jamesbroadhead marked this pull request as ready for review April 21, 2026 17:13
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.

1 participant