Per-Request Auth Token Refresh#103
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements dynamic token refresh for OAuth authentication by deferring token acquisition from channel creation time to per-RPC invocation. The implementation changes from async to sync I/O to accommodate gRPC's threading model and switches the authorization header format from "Token" to the standard "Bearer" prefix.
Changes:
- Token acquisition now occurs dynamically per RPC instead of eagerly at channel creation time
- Converted CredentialHelper from async/await to synchronous with threading.Lock for gRPC callback compatibility
- Changed authorization header format from "Token {token}" to standard "Bearer {token}"
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/resolver_athena_client/client/channel.py | Removed TokenMetadataPlugin, added _AutoRefreshTokenAuthMetadataPlugin for dynamic token refresh; converted CredentialHelper from async to sync; changed authorization scheme to Bearer |
| tests/client/test_channel.py | Updated tests to verify non-eager token fetching; converted async tests to sync; added tests for new _AutoRefreshTokenAuthMetadataPlugin class |
| tests/functional/conftest.py | Removed eager token acquisition test from credential_helper fixture |
| examples/example.py | Removed eager token acquisition and validation before channel creation |
| examples/classify_single_example.py | Removed eager token acquisition and validation before channel creation |
| docs/authentication.rst | Updated code examples to reflect that get_token() is now synchronous |
| docs/api/exceptions.rst | Updated code examples to reflect that get_token() is now synchronous |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1b3e2a2
…only scanning relevant files
|
@iwillspeak I've opened a new pull request, #107, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@iwillspeak I've opened a new pull request, #108, to work on those changes. Once the pull request is ready, I'll request review from you. |
…stampede (#107) * Initial plan * Implement background token refresh for old tokens - Add issued_at field to TokenData to track token creation time - Add is_old() method to check if token should be refreshed (< 50% lifetime) - Trigger non-blocking background refresh when token is old but valid - Keep blocking refresh for expired tokens - Add comprehensive tests for background refresh behavior Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * fix: update tests to match preserved token scheme casing Tests were expecting capitalized schemes but implementation was changed in 4b7e73a to preserve server-provided casing. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Address code review feedback - Add logging for background refresh failures - Improve comments explaining magic numbers - Add test for server casing preservation - Add comment explaining test tolerance Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Address PR review comments - Make issued_at a required field (remove default value) - Remove fallback logic for legacy tokens in is_old() - Add stampede prevention in _background_refresh - Remove obsolete tests for fallback logic - Add test for stampede prevention Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Revert Bearer/DPoP test assertion changes from c50327d The target branch now properly fixes the test by providing "Bearer" in the mock data. Reverting my previous fix that changed the assertion to match the old mock data. Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com> * fix: start refresh thread checks for already refreshed token * chore: remove extraneous comment * feat: reduce eagerness of background refresh from at 50% remaining to 25% remaining * doc: update is_old docstring * fix: correct boolean logic in _start_background_refresh Changed from OR to AND logic: refresh should start if (refresh_not_active AND token_needs_refresh), not if any condition is true. This prevents unnecessary refresh attempts. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * test: fix test assertions to be on 25% instead of 50% * feat: allow configurable proactive_refresh_threshold --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com> Co-authored-by: anna-singleton-resolver <anna.singleton@resolver.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Token is now not eagerly pulled and baked into requests, its dynamically aquired per rpc