Open thehesiod opened 3 years ago
This is still an issue, and @thehesiod is right about the fix.
Some more detail...
It looks like the _aio_http_requests.AuthorizedSession
definitely expects an async credentials object when it calls before_request
:
await self.credentials.before_request(
auth_request, method, url, request_headers
)
And then it later in the same function, it definitely seems to assume that the credentials are non-async - running the refresh in a background thread but not actually awaiting the coroutine itself:
async with self._refresh_lock:
await self._loop.run_in_executor(
None, self.credentials.refresh, auth_request
)
Note: The
await
here isn't awaiting therefresh
call; it'sawait
ing the background thread withoutawaiting
therefresh
coroutine itself.
So there seems to clearly be a paradox/contradiction here, conflating async vs non-async credentials.
Keep in mind that this only happens if the first HTTP request attempt fails with a retry status code, which is unlikely because the before_request
also proactively does a refresh; but it is technically possible for the case to happen in the small window of time before the credentials expire, and quite nasty to diagnose when it does happen intermittently.
async with self._refresh_lock:
- await self._loop.run_in_executor(
- None, self.credentials.refresh, auth_request
- )
+ await self.credentials.refresh(auth_request)
A more fancy approach would be to conditionally await
the refresh
OR run a background thread, depending on whether async vs non-async credentials are used; but that's a bit more involved and might be more of a "nice to have" / future improvement.
Right now though the refresh call appears to definitely be broken, causing intermittently bizarre behavior when this code tries to trigger a refresh, so hopefully the quick fix can be applied.
(I don't have time to submit a PR for this, but maybe this info will help someone)
Verified this is still a problem with v. 2.20.0.
Verified this is still a problem with v2.32.0
Recently I migrated from my custom async implementation to the beta implementation however I noticed two issues:
1) _CombinedResponse is missing the reason property and occasionally errors out, my fix:
2) the credentials refresh does not support an async call (which should be the default if you're using the credentials_async class
fix is making this call async: https://github.com/googleapis/google-auth-library-python/blob/main/google/auth/transport/_aiohttp_requests.py#L371
if sync needs to be supported it should do a check if the method is awaitable/a coroutine or not.
Environment details
google-auth
version: 2.2.1Steps to reproduce