Skip to content

fix: add timeout to requests.post()/get() calls in oauth.py#1339

Open
cgrierson-smartsheet wants to merge 2 commits intodatabricks:mainfrom
cgrierson-smartsheet:fix/oauth-missing-timeout
Open

fix: add timeout to requests.post()/get() calls in oauth.py#1339
cgrierson-smartsheet wants to merge 2 commits intodatabricks:mainfrom
cgrierson-smartsheet:fix/oauth-missing-timeout

Conversation

@cgrierson-smartsheet
Copy link

@cgrierson-smartsheet cgrierson-smartsheet commented Mar 19, 2026

Summary

Add timeout to all requests.post()/requests.get() calls in oauth.py that currently have no timeout parameter. Without a timeout, these calls block indefinitely when the OAuth endpoint is unreachable or slow.

Extract _DEFAULT_HTTP_TIMEOUT_SECONDS constant from the existing hardcoded or 60 in _BaseClient.__init__ and use it consistently. The timeout is configurable via Config.http_timeout_seconds, threaded through from all call sites.

Changes

_base_client.py:

  • Extract _DEFAULT_HTTP_TIMEOUT_SECONDS = 60 constant (replaces the existing inline or 60)
  • _BaseClient.__init__ now uses the constant

oauth.py:

  • retrieve_token(): add timeout parameter (default _DEFAULT_HTTP_TIMEOUT_SECONDS), pass to requests.post()
  • get_azure_entra_id_workspace_endpoints(): add timeout parameter (default _DEFAULT_HTTP_TIMEOUT_SECONDS), pass to requests.get()
  • ClientCredentials dataclass: add http_timeout_seconds field (default _DEFAULT_HTTP_TIMEOUT_SECONDS), pass to retrieve_token()
  • PATOAuthTokenExchange dataclass: add http_timeout_seconds field (default _DEFAULT_HTTP_TIMEOUT_SECONDS), pass to requests.post()

credentials_provider.py:

  • All ClientCredentials(...) and PATOAuthTokenExchange(...) construction sites: pass http_timeout_seconds=cfg.http_timeout_seconds or _DEFAULT_HTTP_TIMEOUT_SECONDS
  • All get_azure_entra_id_workspace_endpoints(...) calls: pass timeout=cfg.http_timeout_seconds or _DEFAULT_HTTP_TIMEOUT_SECONDS

config.py:

  • oidc_endpoints property: pass timeout=self.http_timeout_seconds or _DEFAULT_HTTP_TIMEOUT_SECONDS to get_azure_entra_id_workspace_endpoints()

Problem

These calls bypass _BaseClient entirely and use the requests library directly. The SDK's per-request timeout (session.request(timeout=60)) does not protect against hangs in these calls because they execute inside session.auth (the header_factory callback), which runs before the request timeout takes effect.

In long-running processes (>60 min), the M2M OAuth token expires (TTL = 3600s) and the next API call triggers a synchronous token refresh through retrieve_token(). If the OAuth endpoint is slow at that moment, requests.post() blocks indefinitely, hanging the entire process.

See #1338 for full analysis, failure mode tables, and a self-contained reproduction script.

Related: #1046 (non-configurable timeout for _BaseClient.do() in OIDC endpoint discovery — same family of issue, different code path).

Test plan

Signed-off-by: Chris Grierson christopher.grierson@smartsheet.com

@cgrierson-smartsheet cgrierson-smartsheet force-pushed the fix/oauth-missing-timeout branch 3 times, most recently from aa939a6 to cd9626a Compare March 19, 2026 10:03
requests.post() and requests.get() calls in oauth.py's retrieve_token(),
get_azure_entra_id_workspace_endpoints(), and PATOAuthTokenExchange.refresh()
do not pass a timeout= parameter. When the OAuth endpoint is unreachable or
slow, these calls block indefinitely. The SDK's per-request timeout
(session.request(timeout=60)) does not protect against this because the
token refresh runs inside session.auth, before the timeout takes effect.

Extract _DEFAULT_HTTP_TIMEOUT_SECONDS constant from the existing hardcoded
value in _BaseClient.__init__ and use it consistently across all OAuth HTTP
calls. Add http_timeout_seconds fields to ClientCredentials and
PATOAuthTokenExchange dataclasses, and timeout parameters to
retrieve_token() and get_azure_entra_id_workspace_endpoints(). All call
sites in credentials_provider.py and config.py pass
cfg.http_timeout_seconds so the timeout is user-configurable via Config.

Fixes databricks#1338

Signed-off-by: Chris Grierson <christopher.grierson@smartsheet.com>
@cgrierson-smartsheet cgrierson-smartsheet force-pushed the fix/oauth-missing-timeout branch from cd9626a to d4c5563 Compare March 20, 2026 19:40
@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: 1339
  • Commit SHA: 7b6e13d109135ada3beeecc9d8336344348ddf56

Checks will be approved automatically on success.

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