|
| 1 | +"""Async Wrapper around Google Auth Credentials""" |
| 2 | + |
| 3 | +import asyncio |
| 4 | +from google.auth.aio import credentials as async_creds |
| 5 | +from google.auth.transport.requests import Request |
| 6 | + |
| 7 | +class AsyncCredsWrapper(async_creds.Credentials): |
| 8 | + """Wraps synchronous Google Auth credentials to provide an asynchronous interface. |
| 9 | +
|
| 10 | + This class adapts standard synchronous `google.auth.credentials.Credentials` for use |
| 11 | + in asynchronous contexts. It offloads blocking operations, such as token refreshes, |
| 12 | + to a separate thread using `asyncio.loop.run_in_executor`. |
| 13 | +
|
| 14 | + Args: |
| 15 | + sync_creds (google.auth.credentials.Credentials): The synchronous credentials |
| 16 | + instance to wrap. |
| 17 | + """ |
| 18 | + |
| 19 | + def __init__(self, sync_creds): |
| 20 | + super().__init__() |
| 21 | + self.creds = sync_creds |
| 22 | + self._loop = asyncio.get_event_loop() |
| 23 | + |
| 24 | + async def refresh(self, _request): |
| 25 | + """Refreshes the access token.""" |
| 26 | + await self._loop.run_in_executor( |
| 27 | + None, self.creds.refresh, Request() |
| 28 | + ) |
| 29 | + |
| 30 | + @property |
| 31 | + def valid(self): |
| 32 | + """Checks the validity of the credentials.""" |
| 33 | + return self.creds.valid |
| 34 | + |
| 35 | + async def before_request(self, _request, method, url, headers): |
| 36 | + """Performs credential-specific before request logic.""" |
| 37 | + if self.valid: |
| 38 | + self.creds.apply(headers) |
| 39 | + return |
| 40 | + |
| 41 | + await self._loop.run_in_executor( |
| 42 | + None, self.creds.before_request, Request(), method, url, headers |
| 43 | + ) |
0 commit comments