Add support for custom storage of oauth2 tokens #78
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This implements support for using an external storage mechanism for oauth2 tokens to prevent contention issues when using multiple clients in different processes. The proposal was written out in #72, but I made some slight changes that felt natural when writing the code. This implementation replaces
BaseClient.access_token
andBaseClient.refresh_token
with properties that defer toBaseClient.__access_token
andBaseClient.__refresh_token
when no external storage is configured. This behavior should be fully backwards compatible with how the library worked before this PR.There are two new options that you can specify when initializing the base client that will change this default behavior:
oauth2_token_getter: Optional[Callable[[Literal['access_token', 'refresh_token'], str], str]] = None
andoauth2_token_setter: Optional[Callable[[Literal['access_token', 'refresh_token'], str, str], None]] = None
. They both take the token type as the first argument and the client ID as the second argument. The setter has one additional argument that is the value of the token. These methods both default toNone
, but are used instead of deferring toBaseClient.__access_token
andBaseClient.__refresh_token
when the are provided. This allows using whichever shared storage mechanism you see fit to manage the tokens. If no tokens are retrieved from the getter method, then the properties will fall back to the internal variables. Even if theaccess_token
is expired, this allows the client to get new tokens when the external storage is expired or otherwise unavailable.Here's an example of how you can use the new functionality to store your oauth2 tokens in redis:
Closes #72