Skip to content

refactor(sdk): hand OAuth token requests to Authlib 1.8.0 (0.3.1) - #16

Merged
quantumdark merged 1 commit into
developmentfrom
feat/authlib
Aug 31, 2026
Merged

refactor(sdk): hand OAuth token requests to Authlib 1.8.0 (0.3.1)#16
quantumdark merged 1 commit into
developmentfrom
feat/authlib

Conversation

@yudelevi

@yudelevi yudelevi commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Why

Authlib 1.8.0 (released 2026-08-30) supports httpx2, so the SDK no longer needs to own OAuth protocol code. PKCE, authorization URL, code exchange, and refresh now go through Authlib's OAuth2Client/AsyncOAuth2Client.

What stays in-house

  • DiscolikeAuth: 401 replay, cross-process credential reload (PropelAuth revokes the refresh family on replay), sync+async locks, API-key branch. Authlib's sync client has no lock and only refreshes on expiry.
  • DCR + metadata discovery: Authlib has no RFC 7591 client (RFC7591 Registration client API authlib/authlib#526, open since 2023, no movement).

TokenClient/AsyncTokenClient override parse_response_token so OAuthError.error, status_code, and token-redacted payloads are unchanged.

Behavior notes

  • Refresh uses a dedicated token-endpoint client (30s timeout), not the SDK http_client; proxies/transports on http_client= don't reach the token endpoint. In CHANGELOG.
  • expires_at is whole seconds (Authlib rounds), ≤1s conservative.
  • New dependency: authlib>=1.8.0 (pulls cryptography, joserfc).
  • Version 0.3.1.

Verified against prod

auth login (reused stored DCR client), auth status, account usage, proactive refresh with rotation persisted, 401 replay with rotation.

Also: README sign-up links → discolike.com/signup.

Greptile Summary

The PR delegates PKCE authorization, code exchange, and token refresh to Authlib 1.8.0 while retaining DiscoLike’s credential persistence, locking, cross-process reload, and 401 replay behavior.

  • Adds Authlib and its locked transitive dependencies, then aligns SDK and CLI versions at 0.3.1.
  • Introduces synchronous and asynchronous Authlib token clients with DiscoLike-compatible error parsing and token redaction.
  • Moves refresh traffic to dedicated token-endpoint clients and documents the resulting timeout and transport behavior.
  • Updates OAuth, authentication-flow, package, CLI, and persistence tests for the new integration.
  • Updates README signup links.

Confidence Score: 5/5

The PR appears safe to merge with no concrete changed-code defect identified.

The Authlib integration preserves the established OAuth request shapes, credential rotation and persistence behavior, sync and async coordination, 401 replay, and SDK error payload contracts; the intentional dedicated-client transport change is documented.

Important Files Changed

Filename Overview
packages/discolike/src/discolike/_oauth.py Replaces hand-built PKCE and token requests with Authlib clients while preserving SDK-specific token validation, redaction, and authentication-error mapping.
packages/discolike/src/discolike/_auth.py Routes proactive and post-401 refresh through dedicated sync and async token clients while retaining locking, reload, adoption, persistence, and replay behavior.
packages/discolike-cli/src/discolike_cli/auth.py Adapts the CLI authorization flow to receive Authlib’s generated PKCE verifier and use the dedicated code-exchange client.
packages/discolike/pyproject.toml Adds the Authlib 1.8.0 dependency and aligns the optional CLI dependency with release 0.3.1.
packages/discolike/tests/test_oauth.py Updates OAuth tests to validate Authlib-generated PKCE, request forms, credential conversion, async refresh, and error translation.
packages/discolike/tests/test_auth_flow.py Injects mock token transports and continues covering proactive refresh, concurrency, credential adoption, and 401 replay behavior.
uv.lock Locks Authlib 1.8.0 and its cryptographic transitive dependencies for the updated workspace packages.

Reviews (1): Last reviewed commit: "refactor(sdk): hand OAuth token requests..." | Re-trigger Greptile

Authlib 1.8.0 (2026-08-30) ships httpx2 support, so PKCE challenge
generation, the authorization URL, code exchange, and refresh now go
through its OAuth2Client instead of hand-rolled request building. The
point is to stop owning protocol code: Authlib maintains RFC 6749/7636
handling, we keep only what it lacks.

What stays ours, deliberately:
- DiscolikeAuth (httpx2.Auth): single 401 replay, cross-process
  credential reload (PropelAuth revokes the whole refresh family on a
  replayed refresh token, so two CLI processes must not both refresh),
  sync+async locks, and the API-key branch. Authlib's sync client has
  no lock and refreshes on expiry only.
- Dynamic client registration and metadata discovery: Authlib has no
  RFC 7591 client (authlib/authlib#526, open since 2023).

TokenClient/AsyncTokenClient override parse_response_token so error
types, status codes, and token-redacted payloads are unchanged for
callers. Refreshes use a dedicated token-endpoint client (30s timeout)
rather than the SDK http_client, so proxies configured there no longer
reach the token endpoint; noted in the changelog.

Verified live against prod: login (reused DCR client), status, usage,
proactive refresh with token rotation, and 401 replay.

Also: README sign-up links to discolike.com/signup.
@quantumdark
quantumdark merged commit e7d1de5 into development Aug 31, 2026
8 checks passed
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