0
# Async Support
1
2
Full async implementations using aiohttp for non-blocking authentication flows. Provides async versions of core authentication components enabling high-performance concurrent applications.
3
4
## Capabilities
5
6
### Async Credentials
7
8
Async versions of core credential classes supporting non-blocking token refresh and authentication operations.
9
10
```python { .api }
11
class Credentials(google.auth.credentials.Credentials):
12
"""Async credentials base class."""
13
14
async def refresh(self, request):
15
"""
16
Async refresh of the access token.
17
18
Args:
19
request (google.auth.aio.transport.Request): Async HTTP transport
20
21
Raises:
22
google.auth.exceptions.RefreshError: If credentials cannot be refreshed
23
"""
24
25
async def apply(self, headers, token=None):
26
"""
27
Async apply authentication headers to a request.
28
29
Args:
30
headers (Mapping[str, str]): The HTTP request headers
31
token (str): Optional token to use instead of current token
32
"""
33
34
class AnonymousCredentials(google.auth.credentials.AnonymousCredentials):
35
"""Async anonymous credentials."""
36
37
async def refresh(self, request):
38
"""No-op refresh for anonymous credentials."""
39
```
40
41
### Async Transport
42
43
Async HTTP transport implementations using aiohttp for non-blocking requests and credential refresh.
44
45
```python { .api }
46
class Request(google.auth.transport.Request):
47
"""Async HTTP transport using aiohttp."""
48
49
def __init__(self, session=None):
50
"""
51
Initialize async transport.
52
53
Args:
54
session (aiohttp.ClientSession): The aiohttp session.
55
If not specified, a new session will be created for each request.
56
"""
57
58
async def __call__(self, method, url, data=None, headers=None, **kwargs):
59
"""
60
Make an async HTTP request.
61
62
Args:
63
method (str): The HTTP method (GET, POST, etc.)
64
url (str): The URL to request
65
data (bytes): The request body data
66
headers (Mapping[str, str]): Request headers
67
**kwargs: Additional arguments to pass to aiohttp
68
69
Returns:
70
google.auth.transport.Response: The HTTP response
71
"""
72
73
class AuthorizedSession(aiohttp.ClientSession):
74
"""Async session with automatic credential refresh."""
75
76
def __init__(
77
self,
78
credentials,
79
refresh_status_codes=None,
80
max_refresh_attempts=None,
81
**kwargs
82
):
83
"""
84
Initialize async authorized session.
85
86
Args:
87
credentials (google.auth.credentials.Credentials): The credentials to use
88
refresh_status_codes (Sequence[int]): HTTP status codes that trigger refresh
89
max_refresh_attempts (int): Maximum number of refresh attempts
90
**kwargs: Additional arguments to pass to aiohttp.ClientSession
91
"""
92
93
async def request(self, method, url, **kwargs):
94
"""
95
Make an async authenticated request.
96
97
Args:
98
method (str): The HTTP method
99
url (str): The URL to request
100
**kwargs: Additional arguments to pass to aiohttp
101
102
Returns:
103
aiohttp.ClientResponse: The HTTP response
104
"""
105
106
async def get(self, url, **kwargs):
107
"""Make an async GET request."""
108
109
async def post(self, url, **kwargs):
110
"""Make an async POST request."""
111
112
async def put(self, url, **kwargs):
113
"""Make an async PUT request."""
114
115
async def delete(self, url, **kwargs):
116
"""Make an async DELETE request."""
117
```
118
119
Usage example:
120
121
```python
122
import asyncio
123
import google.auth
124
from google.auth.aio.transport import aiohttp
125
126
async def main():
127
# Get default credentials
128
credentials, project = google.auth.default(
129
scopes=['https://www.googleapis.com/auth/cloud-platform']
130
)
131
132
# Create async authorized session
133
async with aiohttp.AuthorizedSession(credentials) as session:
134
# Make async authenticated requests
135
async with session.get('https://www.googleapis.com/compute/v1/projects') as response:
136
data = await response.json()
137
print(f"Projects: {len(data.get('items', []))}")
138
139
# Make multiple concurrent requests
140
urls = [
141
'https://www.googleapis.com/compute/v1/projects',
142
'https://www.googleapis.com/storage/v1/b',
143
'https://bigquery.googleapis.com/bigquery/v2/projects'
144
]
145
146
tasks = [session.get(url) for url in urls]
147
responses = await asyncio.gather(*tasks)
148
149
for response in responses:
150
data = await response.json()
151
print(f"Response: {response.status}")
152
153
# Run async function
154
asyncio.run(main())
155
```
156
157
### Async Service Account Credentials
158
159
Async service account authentication supporting non-blocking token refresh and JWT signing.
160
161
```python { .api }
162
class Credentials(google.oauth2.service_account.Credentials):
163
"""Async service account credentials."""
164
165
async def refresh(self, request):
166
"""
167
Async refresh of service account token.
168
169
Args:
170
request (google.auth.aio.transport.Request): Async HTTP transport
171
"""
172
173
@classmethod
174
def from_service_account_file(cls, filename, **kwargs):
175
"""
176
Create async service account credentials from file.
177
178
Args:
179
filename (str): Path to service account JSON file
180
**kwargs: Additional arguments
181
182
Returns:
183
Credentials: Async service account credentials
184
"""
185
186
@classmethod
187
def from_service_account_info(cls, info, **kwargs):
188
"""
189
Create async service account credentials from info.
190
191
Args:
192
info (Mapping[str, str]): Service account info dictionary
193
**kwargs: Additional arguments
194
195
Returns:
196
Credentials: Async service account credentials
197
"""
198
```
199
200
### Async OAuth2 Credentials
201
202
Async OAuth2 user credentials with non-blocking token refresh.
203
204
```python { .api }
205
class Credentials(google.oauth2.credentials.Credentials):
206
"""Async OAuth2 user credentials."""
207
208
async def refresh(self, request):
209
"""
210
Async refresh of OAuth2 token using refresh token.
211
212
Args:
213
request (google.auth.aio.transport.Request): Async HTTP transport
214
"""
215
```
216
217
### Async JWT Operations
218
219
Async JWT token operations for non-blocking JWT creation and verification.
220
221
```python { .api }
222
class Credentials(google.auth.jwt.Credentials):
223
"""Async JWT credentials."""
224
225
async def refresh(self, request):
226
"""
227
Async refresh of JWT token.
228
229
Args:
230
request (google.auth.aio.transport.Request): Async HTTP transport
231
"""
232
233
async def verify_token_async(id_token, request, audience=None, **kwargs):
234
"""
235
Async verify an ID token.
236
237
Args:
238
id_token (Union[str, bytes]): The encoded token
239
request (google.auth.aio.transport.Request): Async HTTP transport
240
audience (str): Expected audience
241
**kwargs: Additional verification options
242
243
Returns:
244
Mapping[str, Any]: The decoded token payload
245
"""
246
247
async def fetch_id_token_async(request, audience, service_account_email=None):
248
"""
249
Async fetch an ID token from metadata server.
250
251
Args:
252
request (google.auth.aio.transport.Request): Async HTTP transport
253
audience (str): The audience for the ID token
254
service_account_email (str): Service account to impersonate
255
256
Returns:
257
str: The ID token
258
"""
259
```
260
261
### Async Reauth
262
263
Async reauth flows for multi-factor authentication scenarios.
264
265
```python { .api }
266
async def refresh_grant_async(
267
request,
268
token_uri,
269
refresh_token,
270
client_id,
271
client_secret,
272
scopes=None
273
):
274
"""
275
Async refresh an access token using a refresh token.
276
277
Args:
278
request (google.auth.aio.transport.Request): Async HTTP transport
279
token_uri (str): The OAuth 2.0 token endpoint URI
280
refresh_token (str): The refresh token
281
client_id (str): The OAuth 2.0 client ID
282
client_secret (str): The OAuth 2.0 client secret
283
scopes (Sequence[str]): Optional scopes
284
285
Returns:
286
Tuple[str, Optional[str], Optional[datetime], Mapping[str, str]]:
287
Access token, new refresh token, expiry, additional data
288
"""
289
```
290
291
### Async External Account Credentials
292
293
Async external account credentials for workload identity with non-blocking token exchange.
294
295
```python { .api }
296
class Credentials(google.auth.external_account.Credentials):
297
"""Async external account credentials."""
298
299
async def refresh(self, request):
300
"""
301
Async refresh using STS token exchange.
302
303
Args:
304
request (google.auth.aio.transport.Request): Async HTTP transport
305
"""
306
307
async def retrieve_subject_token(self):
308
"""
309
Async retrieve subject token from credential source.
310
311
Returns:
312
str: The subject token
313
"""
314
```
315
316
## Async Usage Patterns
317
318
### Context Manager Pattern
319
320
```python
321
async def api_operations():
322
credentials, project = google.auth.default()
323
324
# Use async context manager for automatic cleanup
325
async with aiohttp.AuthorizedSession(credentials) as session:
326
# Session automatically handles credential refresh
327
async with session.get('https://api.example.com/data') as response:
328
return await response.json()
329
```
330
331
### Concurrent Requests
332
333
```python
334
async def concurrent_api_calls():
335
credentials, project = google.auth.default()
336
337
async with aiohttp.AuthorizedSession(credentials) as session:
338
# Make multiple concurrent authenticated requests
339
tasks = [
340
session.get('https://api1.googleapis.com/data'),
341
session.get('https://api2.googleapis.com/data'),
342
session.get('https://api3.googleapis.com/data')
343
]
344
345
# Wait for all requests to complete
346
responses = await asyncio.gather(*tasks, return_exceptions=True)
347
348
results = []
349
for response in responses:
350
if isinstance(response, Exception):
351
print(f"Request failed: {response}")
352
else:
353
data = await response.json()
354
results.append(data)
355
356
return results
357
```
358
359
### Long-Running Services
360
361
```python
362
class AsyncAuthenticatedService:
363
def __init__(self):
364
self.credentials, self.project = google.auth.default()
365
self.session = None
366
367
async def start(self):
368
"""Start the service with persistent session."""
369
self.session = aiohttp.AuthorizedSession(self.credentials)
370
371
async def stop(self):
372
"""Clean up resources."""
373
if self.session:
374
await self.session.close()
375
376
async def make_request(self, url):
377
"""Make authenticated request using persistent session."""
378
async with self.session.get(url) as response:
379
return await response.json()
380
381
async def __aenter__(self):
382
await self.start()
383
return self
384
385
async def __aexit__(self, exc_type, exc_val, exc_tb):
386
await self.stop()
387
388
# Usage
389
async def main():
390
async with AsyncAuthenticatedService() as service:
391
result = await service.make_request('https://api.googleapis.com/data')
392
print(result)
393
```
394
395
## Error Handling
396
397
```python { .api }
398
class RefreshError(google.auth.exceptions.GoogleAuthError):
399
"""Raised when async credential refresh fails."""
400
401
class TransportError(google.auth.exceptions.GoogleAuthError):
402
"""Raised when async transport encounters an error."""
403
```
404
405
Common async error scenarios:
406
- Network timeouts during async requests
407
- Concurrent credential refresh conflicts
408
- Session management errors
409
- aiohttp connection pool exhaustion
410
- Async context manager cleanup failures
411
- Event loop integration issues